OSDN Git Service

NIKON対応途中。
authorMRSa <mrsa@myad.jp>
Sat, 22 Feb 2020 14:02:39 +0000 (23:02 +0900)
committerMRSa <mrsa@myad.jp>
Sat, 22 Feb 2020 14:02:39 +0000 (23:02 +0900)
13 files changed:
app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/liveview/CanonLiveViewControl.java
app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/liveview/CanonLiveViewImageReceiver.java
app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/liveview/ICanonLiveViewImageCallback.java [deleted file]
app/src/main/java/net/osdn/gokigen/a01d/camera/nikon/wrapper/NikonInterfaceProvider.java
app/src/main/java/net/osdn/gokigen/a01d/camera/nikon/wrapper/connection/NikonCameraConnectSequence.java
app/src/main/java/net/osdn/gokigen/a01d/camera/nikon/wrapper/liveview/NikonLiveViewControl.java
app/src/main/java/net/osdn/gokigen/a01d/camera/nikon/wrapper/liveview/NikonLiveViewImageReceiver.java [new file with mode: 0644]
app/src/main/java/net/osdn/gokigen/a01d/camera/nikon/wrapper/status/NikonStatusChecker.java
app/src/main/java/net/osdn/gokigen/a01d/camera/nikon/wrapper/status/NikonStatusWatcher.java [deleted file]
app/src/main/java/net/osdn/gokigen/a01d/camera/ptpip/wrapper/command/IPtpIpMessages.java
app/src/main/java/net/osdn/gokigen/a01d/camera/ptpip/wrapper/command/PtpIpCommandPublisher.java
app/src/main/java/net/osdn/gokigen/a01d/camera/ptpip/wrapper/command/PtpIpResponseReceiver.java [new file with mode: 0644]
app/src/main/java/net/osdn/gokigen/a01d/camera/ptpip/wrapper/liveview/IPtpIpLiveViewImageCallback.java [new file with mode: 0644]

index b7a4356..af2ba87 100644 (file)
@@ -10,6 +10,7 @@ import net.osdn.gokigen.a01d.camera.ptpip.IPtpIpInterfaceProvider;
 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandPublisher;
 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommunication;
 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.messages.PtpIpCommandGeneric;
+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.liveview.IPtpIpLiveViewImageCallback;
 import net.osdn.gokigen.a01d.liveview.liveviewlistener.IImageDataReceiver;
 import net.osdn.gokigen.a01d.liveview.liveviewlistener.ILiveViewListener;
 
@@ -18,7 +19,7 @@ import java.util.Map;
 
 import static net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpMessages.SEQ_GET_VIEWFRAME;
 
-public class CanonLiveViewControl implements ILiveViewControl, ILiveViewListener, IPtpIpCommunication, ICanonLiveViewImageCallback
+public class CanonLiveViewControl implements ILiveViewControl, ILiveViewListener, IPtpIpCommunication, IPtpIpLiveViewImageCallback
 {
     private final String TAG = this.toString();
     private final IPtpIpCommandPublisher commandIssuer;
index a9623cd..d1bc43d 100644 (file)
@@ -4,6 +4,7 @@ import android.util.Log;
 
 import androidx.annotation.NonNull;
 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandCallback;
+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.liveview.IPtpIpLiveViewImageCallback;
 
 import java.io.ByteArrayOutputStream;
 
@@ -11,7 +12,7 @@ public class CanonLiveViewImageReceiver implements IPtpIpCommandCallback
 {
     private final String TAG = toString();
 
-    private ICanonLiveViewImageCallback callback;
+    private IPtpIpLiveViewImageCallback callback;
 
     private int received_total_bytes = 0;
     private int received_remain_bytes = 0;
@@ -20,7 +21,7 @@ public class CanonLiveViewImageReceiver implements IPtpIpCommandCallback
     private boolean receivedFirstData = false;
     private ByteArrayOutputStream byteStream;
 
-    CanonLiveViewImageReceiver(@NonNull ICanonLiveViewImageCallback callback)
+    CanonLiveViewImageReceiver(@NonNull IPtpIpLiveViewImageCallback callback)
     {
         this.callback = callback;
         byteStream = new ByteArrayOutputStream();
diff --git a/app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/liveview/ICanonLiveViewImageCallback.java b/app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/liveview/ICanonLiveViewImageCallback.java
deleted file mode 100644 (file)
index 0697262..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-package net.osdn.gokigen.a01d.camera.canon.wrapper.liveview;
-
-import android.graphics.Bitmap;
-
-import java.util.Map;
-
-public interface ICanonLiveViewImageCallback
-{
-    void onCompleted(byte[] data, Map<String, Object> metadata);
-    void onErrorOccurred(Exception  e);
-}
index 9bf79c0..f20bd68 100644 (file)
@@ -41,11 +41,10 @@ public class NikonInterfaceProvider implements IPtpIpInterfaceProvider, IDisplay
 {
     private final String TAG = toString();
 
-    private static final int STREAM_PORT = 15742;   // ??
-    private static final int ASYNC_RESPONSE_PORT = 15741;  // ??
+    private static final int ASYNC_RESPONSE_PORT = 15741;
     private static final int CONTROL_PORT = 15740;
     private static final int EVENT_PORT = 15740;
-    private static final String CAMERA_IP = "192.168.0.1";
+    private static final String CAMERA_IP = "192.168.1.1";
 
     private final Activity activity;
     private final PtpIpRunMode runmode;
@@ -65,7 +64,7 @@ public class NikonInterfaceProvider implements IPtpIpInterfaceProvider, IDisplay
     {
         this.activity = context;
         commandPublisher = new PtpIpCommandPublisher(CAMERA_IP, CONTROL_PORT);
-        liveViewControl = new NikonLiveViewControl(context, CAMERA_IP, STREAM_PORT);
+        liveViewControl = new NikonLiveViewControl(context, this, 20);
         asyncReceiver = new PtpIpAsyncResponseReceiver(CAMERA_IP, ASYNC_RESPONSE_PORT);
         statusChecker = new NikonStatusChecker(activity, commandPublisher, CAMERA_IP, EVENT_PORT);
         canonConnection = new NikonConnection(context, provider, this, statusChecker);
index a4d4a94..957df30 100644 (file)
@@ -27,11 +27,11 @@ public class NikonCameraConnectSequence implements Runnable, IPtpIpCommandCallba
     private final IPtpIpInterfaceProvider interfaceProvider;
     private final IPtpIpCommandPublisher commandIssuer;
     private final NikonStatusChecker statusChecker;
-    private boolean isDumpLog = false;
+    private boolean isDumpLog = true;
 
     NikonCameraConnectSequence(@NonNull Activity context, @NonNull ICameraStatusReceiver statusReceiver, @NonNull final ICameraConnection cameraConnection, @NonNull IPtpIpInterfaceProvider interfaceProvider, @NonNull NikonStatusChecker statusChecker)
     {
-        Log.v(TAG, " NikonCameraConnectSequenceForPlayback");
+        Log.v(TAG, " NikonCameraConnectSequence");
         this.context = context;
         this.cameraConnection = cameraConnection;
         this.cameraStatusReceiver = statusReceiver;
@@ -110,9 +110,14 @@ public class NikonCameraConnectSequence implements Runnable, IPtpIpCommandCallba
                 break;
 
             case SEQ_EVENT_INITIALIZE:
+                interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting1), false, false, 0);
+                commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_INIT_SESSION, 50, isDumpLog, 0, 0x1001, 0, 0, 0, 0, 0));  // GetDeviceInfo
+                break;
+
+            case SEQ_INIT_SESSION:
                 if (checkEventInitialize(rx_body))
                 {
-                    interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting1), false, false, 0);
+                    interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting2), false, false, 0);
                     commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_OPEN_SESSION, 50, isDumpLog, 0, 0x1002, 4, 0x41, 0, 0, 0));  // OpenSession
                 }
                 else
@@ -120,16 +125,13 @@ public class NikonCameraConnectSequence implements Runnable, IPtpIpCommandCallba
                     onConnectError(context.getString(R.string.connect_error_message));
                 }
                 break;
-
             case SEQ_OPEN_SESSION:
-                interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting2), false, false, 0);
-                commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_INIT_SESSION, 50, isDumpLog, 0, 0x1001, 0, 0, 0, 0, 0));  // GetDeviceInfo
+                interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting3), false, false, 0);
+                commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_CHANGE_REMOTE, 50, isDumpLog, 0, 0x902c, 4, 0x01, 0, 0, 0));  //
                 break;
 
-            case SEQ_INIT_SESSION:
             case SEQ_CHANGE_REMOTE:
             case SEQ_SET_EVENT_MODE:
-                interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting3), false, false, 0);
                 interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting4), false, false, 0);
                 interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting5), false, false, 0);
                 interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.connect_connect_finished), false, false, 0);
index 3d8cc17..6c36f2a 100644 (file)
@@ -6,23 +6,41 @@ import android.util.Log;
 import androidx.annotation.NonNull;
 
 import net.osdn.gokigen.a01d.camera.ILiveViewControl;
+import net.osdn.gokigen.a01d.camera.ptpip.IPtpIpInterfaceProvider;
+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandCallback;
+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandPublisher;
 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommunication;
+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.PtpIpResponseReceiver;
+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.messages.PtpIpCommandGeneric;
+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.liveview.IPtpIpLiveViewImageCallback;
 import net.osdn.gokigen.a01d.liveview.liveviewlistener.IImageDataReceiver;
 import net.osdn.gokigen.a01d.liveview.liveviewlistener.ILiveViewListener;
 
-public class NikonLiveViewControl implements ILiveViewControl, ILiveViewListener, IPtpIpCommunication
-{
-    private final String TAG = this.toString();
+import java.util.Arrays;
+import java.util.Map;
 
-    private final Activity context;
-    private final String ipAddr;
-    private final int portNo;
+import static net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpMessages.SEQ_AFDRIVE;
+import static net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpMessages.SEQ_DEVICE_READY;
+import static net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpMessages.SEQ_GET_VIEWFRAME;
+import static net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpMessages.SEQ_START_LIVEVIEW;
+import static net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpMessages.SEQ_STOP_LIVEVIEW;
 
-    public NikonLiveViewControl(@NonNull Activity context, @NonNull String ipAddr, int portNo)
+public class NikonLiveViewControl  implements ILiveViewControl, ILiveViewListener, IPtpIpCommunication, IPtpIpLiveViewImageCallback
+{
+    private final String TAG = this.toString();
+    private final IPtpIpCommandPublisher commandIssuer;
+    private final int delayMs;
+    private NikonLiveViewImageReceiver imageReceiver;
+    private IImageDataReceiver dataReceiver = null;
+    private boolean liveViewIsReceiving = false;
+    private boolean commandIssued = false;
+    private boolean isDumpLog = true;
+
+    public NikonLiveViewControl(@NonNull Activity context, @NonNull IPtpIpInterfaceProvider interfaceProvider, int delayMs)
     {
-        this.context = context;
-        this.ipAddr = ipAddr;
-        this.portNo = portNo;
+        this.commandIssuer = interfaceProvider.getCommandPublisher();
+        this.delayMs = delayMs;
+        this.imageReceiver = new NikonLiveViewImageReceiver(this);
     }
 
     public ILiveViewListener getLiveViewListener()
@@ -40,26 +58,89 @@ public class NikonLiveViewControl implements ILiveViewControl, ILiveViewListener
     public void startLiveView()
     {
         Log.v(TAG, " startLiveView() ");
-
+        try
+        {
+            commandIssuer.enqueueCommand(new PtpIpCommandGeneric(new PtpIpResponseReceiver(), SEQ_START_LIVEVIEW, 20, isDumpLog, 0, 0x9201, 0, 0x00, 0x00, 0x00, 0x00));
+            commandIssuer.enqueueCommand(new PtpIpCommandGeneric(new PtpIpResponseReceiver(), SEQ_DEVICE_READY, 20, isDumpLog, 0, 0x90c8, 0, 0x00, 0x00, 0x00, 0x00));
+            commandIssuer.enqueueCommand(new PtpIpCommandGeneric(new PtpIpResponseReceiver(), SEQ_AFDRIVE, 20, isDumpLog, 0, 0x90c1, 0, 0x00, 0x00, 0x00, 0x00));
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
     }
 
     @Override
     public void stopLiveView()
     {
         Log.v(TAG, " stopLiveView() ");
+        liveViewIsReceiving = false;
+        try
+        {
+            commandIssuer.enqueueCommand(new PtpIpCommandGeneric(new PtpIpResponseReceiver(), SEQ_STOP_LIVEVIEW, 20, isDumpLog, 0, 0x9202, 0, 0x00, 0x00, 0x00, 0x00));
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
 
+    private void startLiveviewImpl()
+    {
+        liveViewIsReceiving = true;
+        try
+        {
+            Thread thread = new Thread(new Runnable() {
+                @Override
+                public void run()
+                {
+                    try
+                    {
+                        while (liveViewIsReceiving)
+                        {
+                            if (!commandIssued)
+                            {
+                                commandIssued = true;
+                                commandIssuer.enqueueCommand(new PtpIpCommandGeneric(imageReceiver, SEQ_GET_VIEWFRAME, 20, false, 0, 0x9203, 0, 0x00, 0x00, 0x00, 0x00));
+                            }
+                            try
+                            {
+                                Thread.sleep(delayMs);
+                            }
+                            catch (Exception e)
+                            {
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                    catch (Exception e)
+                    {
+                        e.printStackTrace();
+                    }
+                }
+            });
+            thread.start();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
     }
 
+
+
+
     @Override
     public void updateDigitalZoom()
     {
+        Log.v(TAG, " updateDigitalZoom() ");
 
     }
 
     @Override
     public void updateMagnifyingLiveViewScale(boolean isChangeScale)
     {
-
+        Log.v(TAG, " updateMagnifyingLiveViewScale() ");
     }
 
     @Override
@@ -77,7 +158,8 @@ public class NikonLiveViewControl implements ILiveViewControl, ILiveViewListener
     @Override
     public void setCameraLiveImageView(IImageDataReceiver target)
     {
-
+        Log.v(TAG, " setCameraLiveImageView() ");
+        this.dataReceiver = target;
     }
 
     @Override
@@ -92,4 +174,34 @@ public class NikonLiveViewControl implements ILiveViewControl, ILiveViewListener
     {
         Log.v(TAG, " disconnect() ");
     }
+
+    @Override
+    public void onCompleted(byte[] data, Map<String, Object> metadata)
+    {
+        //Log.v(TAG, "  ---+++--- RECEIVED LV IMAGE ---+++--- ");
+        try
+        {
+            if ((dataReceiver != null)&&(data != null))
+            {
+                //Log.v(TAG, "  ---+++--- RECEIVED LV IMAGE ---+++--- : " + data.length + " bytes.");
+                //dataReceiver.setImageData(data, metadata);
+                if (data.length > 8)
+                {
+                    dataReceiver.setImageData(Arrays.copyOfRange(data, 8, data.length), metadata);  // ヘッダ部分を切り取って送る
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+        commandIssued = false;
+    }
+
+    @Override
+    public void onErrorOccurred(Exception e)
+    {
+        Log.v(TAG, " onErrorOccurred () : " + e.getLocalizedMessage());
+        commandIssued = false;
+    }
 }
diff --git a/app/src/main/java/net/osdn/gokigen/a01d/camera/nikon/wrapper/liveview/NikonLiveViewImageReceiver.java b/app/src/main/java/net/osdn/gokigen/a01d/camera/nikon/wrapper/liveview/NikonLiveViewImageReceiver.java
new file mode 100644 (file)
index 0000000..ad2db78
--- /dev/null
@@ -0,0 +1,145 @@
+package net.osdn.gokigen.a01d.camera.nikon.wrapper.liveview;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandCallback;
+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.liveview.IPtpIpLiveViewImageCallback;
+import net.osdn.gokigen.a01d.camera.utils.SimpleLogDumper;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Arrays;
+
+public class NikonLiveViewImageReceiver implements IPtpIpCommandCallback
+{
+    private final String TAG = toString();
+
+    private IPtpIpLiveViewImageCallback callback;
+
+    private int received_total_bytes = 0;
+    private int received_remain_bytes = 0;
+
+    private int target_image_size = 0;
+    private boolean receivedFirstData = false;
+    private ByteArrayOutputStream byteStream;
+
+    NikonLiveViewImageReceiver(@NonNull IPtpIpLiveViewImageCallback callback)
+    {
+        this.callback = callback;
+        byteStream = new ByteArrayOutputStream();
+    }
+
+    @Override
+    public void receivedMessage(int id, byte[] rx_body)
+    {
+        try
+        {
+            // end of receive sequence.
+            //byte [] thumbnail = byteStream.toByteArray();
+            //Log.v(TAG, " TransferComplete() RECEIVED  : " + id + " size : " + target_image_size + " (" + thumbnail.length + ")");
+            //SimpleLogDumper.dump_bytes(" [xxxxx]", Arrays.copyOfRange(thumbnail, 0, (64)));
+            //SimpleLogDumper.dump_bytes(" [zzzzz]", Arrays.copyOfRange(thumbnail, (thumbnail.length - 64), (thumbnail.length)));
+            callback.onCompleted(byteStream.toByteArray(), null);
+            receivedFirstData = false;
+            received_remain_bytes = 0;
+            received_total_bytes = 0;
+            target_image_size = 0;
+
+            byteStream.reset();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            {
+                callback.onErrorOccurred(e);
+            }
+        }
+    }
+
+    @Override
+    public void onReceiveProgress(final int currentBytes, final int totalBytes, byte[] rx_body)
+    {
+        // Log.v(TAG, " onReceiveProgress() " + currentBytes + "/" + totalBytes);
+
+        // 受信したデータから、通信のヘッダ部分を削除する
+        cutHeader(rx_body);
+    }
+
+    private void cutHeader(byte[] rx_body)
+    {
+        if (rx_body == null)
+        {
+            return;
+        }
+        int length = rx_body.length;
+        int data_position = 0;
+        if (!receivedFirstData)
+        {
+            // データを最初に読んだとき。ヘッダ部分を読み飛ばす
+            receivedFirstData = true;
+            data_position = (int) rx_body[0] & (0xff);
+            //Log.v(TAG, " FIRST DATA POS. : " + data_position);
+            //SimpleLogDumper.dump_bytes(" [sssss]", Arrays.copyOfRange(rx_body, 0, (64)));
+        }
+        else if (received_remain_bytes > 0)
+        {
+            // データの読み込みが途中だった場合...
+            if (length < received_remain_bytes)
+            {
+                // 全部コピーする、足りないバイト数は残す
+                received_remain_bytes = received_remain_bytes - length;
+                received_total_bytes = received_total_bytes + rx_body.length;
+                byteStream.write(rx_body, 0, rx_body.length);
+                return;
+            }
+            else
+            {
+                byteStream.write(rx_body, data_position, received_remain_bytes);
+                data_position = received_remain_bytes;
+                received_remain_bytes = 0;
+            }
+        }
+
+        while (data_position <= (length - 12)) {
+            int body_size = (rx_body[data_position] & 0xff) + ((rx_body[data_position + 1] & 0xff) << 8) +
+                    ((rx_body[data_position + 2] & 0xff) << 16) + ((rx_body[data_position + 3] & 0xff) << 24);
+            if (body_size <= 12) {
+                Log.v(TAG, " --- BODY SIZE IS SMALL : " + data_position + " (" + body_size + ") [" + received_remain_bytes + "] " + rx_body.length + "  (" + target_image_size + ")");
+                //int startpos = (data_position > 48) ? (data_position - 48) : 0;
+                //SimpleLogDumper.dump_bytes(" [xxx]", Arrays.copyOfRange(rx_body, startpos, (data_position + 48)));
+                break;
+            }
+
+            // 受信データ(のヘッダ部分)をダンプする
+            Log.v(TAG, " RX DATA : " + data_position + " (" + body_size + ") [" + received_remain_bytes + "] (" + received_total_bytes + ")");
+            SimpleLogDumper.dump_bytes(" [zzz] " + data_position + ": ", Arrays.copyOfRange(rx_body, data_position, (data_position + 48)));
+
+            if ((data_position + body_size) > length) {
+                // データがすべてバッファ内になかったときは、バッファすべてコピーして残ったサイズを記憶しておく。
+                int copysize = (length - ((data_position + 12)));
+                byteStream.write(rx_body, (data_position + 12), copysize);
+                received_remain_bytes = body_size - copysize - 12;  // マイナス12は、ヘッダ分
+                received_total_bytes = received_total_bytes + copysize;
+                //Log.v(TAG, " ----- copy : " + (data_position + 12) + " " + copysize + " remain : " + received_remain_bytes + "  body size : " + body_size);
+                break;
+            }
+            try {
+                byteStream.write(rx_body, (data_position + 12), (body_size - 12));
+                data_position = data_position + body_size;
+                received_total_bytes = received_total_bytes + 12;
+                //Log.v(TAG, " --- COPY : " + (data_position + 12) + " " + (body_size - 12) + " remain : " + received_remain_bytes);
+
+            } catch (Exception e) {
+                Log.v(TAG, "  pos : " + data_position + "  size : " + body_size + " length : " + length);
+                e.printStackTrace();
+            }
+        }
+    }
+
+    @Override
+    public boolean isReceiveMulti()
+    {
+        return (true);
+    }
+
+}
index 8a9a11d..5755114 100644 (file)
@@ -11,6 +11,7 @@ import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommand;
 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandCallback;
 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandPublisher;
 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpMessages;
+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.messages.PtpIpCommandGeneric;
 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.messages.specific.InitEventRequest;
 import net.osdn.gokigen.a01d.liveview.ICameraStatusUpdateNotify;
 
@@ -30,7 +31,6 @@ public class NikonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
 
     private static final int BUFFER_SIZE = 1024 * 1024 + 8;
     private static final int STATUS_MESSAGE_HEADER_SIZE = 14;
-    private int sleepMs;
     private final IPtpIpCommandPublisher issuer;
     private ICameraStatusUpdateNotify notifier = null;
     private NikonStatusHolder statusHolder;
@@ -50,7 +50,6 @@ public class NikonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
         this.statusHolder = new NikonStatusHolder();
         this.ipAddress = ip;
         this.portNumber = portNumber;
-        Log.v(TAG, "POLLING WAIT : " + sleepMs);
     }
 
     @Override
@@ -73,16 +72,18 @@ public class NikonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
             logcat("receivedMessage : " + id + ", length: " + data.length);
             if (id == IPtpIpMessages.SEQ_EVENT_INITIALIZE)
             {
-                // 終わる
+                // 終わる...んじゃなくて、イベント受信待ちに遷移する。
                 Log.v(TAG, " ----- PTP-IP Connection is ESTABLISHED. -----");
+                waitForEvent();
                 return;
             }
+
             if (data.length < STATUS_MESSAGE_HEADER_SIZE)
             {
                 Log.v(TAG, "received status length is short. (" + data.length + " bytes.)");
-                return;
+                // return;
             }
-
+/*
             int nofStatus = (data[13] * 256) + data[12];
             int statusCount = 0;
             int index = STATUS_MESSAGE_HEADER_SIZE;
@@ -93,6 +94,7 @@ public class NikonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
                 index = index + 6;
                 statusCount++;
             }
+*/
         }
         catch (Exception e)
         {
@@ -164,7 +166,6 @@ public class NikonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
         }
         try
         {
-            final IPtpIpCommandCallback callback = this;
             this.notifier = notifier;
             whileFetching = true;
 
@@ -175,34 +176,6 @@ public class NikonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
                 Log.v(TAG, "  CONNECT FAIL...(EVENT) : " + ipAddress + "  " + portNumber);
             }
             issueCommand(new InitEventRequest(this, eventConnectionNumber));
-
-/*
-            Thread thread = new Thread(new Runnable()
-            {
-                @Override
-                public void run()
-                {
-                    logcat("Start status watch. : " + sleepMs + "ms");
-                    while (whileFetching)
-                    {
-                        try
-                        {
-                            issuer.enqueueCommand(new StatusRequestMessage(callback));
-                            Thread.sleep(sleepMs);
-                        }
-                        catch (Exception e)
-                        {
-                            e.printStackTrace();
-                        }
-                    }
-                    logcat("STATUS WATCH STOPPED.");
-                }
-            });
-            thread.start();
-
-            // 切断する
-            disconnect();
-*/
         }
         catch (Exception e)
         {
@@ -285,7 +258,6 @@ public class NikonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
         System.gc();
     }
 
-
     public void setEventConnectionNumber(int connectionNumber)
     {
         eventConnectionNumber = connectionNumber;
@@ -350,8 +322,10 @@ public class NikonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
      *    カメラからにコマンドの結果を受信する(メイン部分)
      *
      */
-    private void receive_from_camera(boolean isDumpReceiveLog, int id, IPtpIpCommandCallback callback, boolean receiveAgain, int delayMs) {
-        try {
+    private void receive_from_camera(boolean isDumpReceiveLog, int id, IPtpIpCommandCallback callback, boolean receiveAgain, int delayMs)
+    {
+        try
+        {
             sleep(delayMs);
 
             boolean isFirstTime = true;
@@ -359,24 +333,31 @@ public class NikonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
             int receive_message_buffer_size = BUFFER_SIZE;
             byte[] byte_array = new byte[receive_message_buffer_size];
             InputStream is = socket.getInputStream();
-            if (is != null) {
+            if (is != null)
+            {
                 int read_bytes = is.read(byte_array, 0, receive_message_buffer_size);
                 byte[] receive_body;
-                if (read_bytes > 4) {
-                    if (receiveAgain) {
+                if (read_bytes > 4)
+                {
+                    if (receiveAgain)
+                    {
                         int length = ((((int) byte_array[3]) & 0xff) << 24) + ((((int) byte_array[2]) & 0xff) << 16) + ((((int) byte_array[1]) & 0xff) << 8) + (((int) byte_array[0]) & 0xff);
-                        if (length > receive_message_buffer_size) {
+                        if (length > receive_message_buffer_size)
+                        {
                             Log.v(TAG, "+++++ TOTAL RECEIVE MESSAGE SIZE IS " + length + " +++++");
                         }
                         totalReadBytes = read_bytes;
-                        while ((length > totalReadBytes) || ((length == read_bytes) && ((int) byte_array[4] == 0x02))) {
+                        while ((length > totalReadBytes) || ((length == read_bytes) && ((int) byte_array[4] == 0x02)))
+                        {
                             // データについて、もう一回受信が必要な場合...
-                            if (isDumpReceiveLog) {
+                            if (isDumpReceiveLog)
+                            {
                                 Log.v(TAG, "--- RECEIVE AGAIN --- [" + length + "(" + read_bytes + ") " + byte_array[4] + "] ");
                             }
                             sleep(delayMs);
                             int read_bytes2 = is.read(byte_array, read_bytes, receive_message_buffer_size - read_bytes);
-                            if (read_bytes2 > 0) {
+                            if (read_bytes2 > 0)
+                            {
                                 read_bytes = read_bytes + read_bytes2;
                                 totalReadBytes = totalReadBytes + read_bytes2;
                             } else {
@@ -384,10 +365,13 @@ public class NikonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
                                 Log.v(TAG, "FINISHED RECEIVE... ");
                                 break;
                             }
-                            if (callback != null) {
-                                if (callback.isReceiveMulti()) {
+                            if (callback != null)
+                            {
+                                if (callback.isReceiveMulti())
+                                {
                                     int offset = 0;
-                                    if (isFirstTime) {
+                                    if (isFirstTime)
+                                    {
                                         // 先頭のヘッダ部分をカットして送る
                                         offset = 12;
                                         isFirstTime = false;
@@ -405,13 +389,16 @@ public class NikonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
                 } else {
                     receive_body = new byte[1];
                 }
-                if (isDumpReceiveLog) {
+                if (isDumpReceiveLog)
+                {
                     // ログに受信メッセージを出力する
                     Log.v(TAG, " receive_from_camera() : " + read_bytes + " bytes.");
                     dump_bytes("RECV[" + receive_body.length + "] ", receive_body);
                 }
-                if (callback != null) {
-                    if (callback.isReceiveMulti()) {
+                if (callback != null)
+                {
+                    if (callback.isReceiveMulti())
+                    {
                         callback.receivedMessage(id, null);
                     } else {
                         callback.receivedMessage(id, receive_body);
@@ -419,7 +406,9 @@ public class NikonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
                     }
                 }
             }
-        } catch (Throwable e) {
+        }
+        catch (Throwable e)
+        {
             e.printStackTrace();
         }
     }
@@ -435,4 +424,93 @@ public class NikonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
             e.printStackTrace();
         }
     }
+
+    private void waitForEvent()
+    {
+        final int delayMs = 25;
+        try
+        {
+            Thread thread = new Thread(new Runnable() {
+                @Override
+                public void run() {
+                    try
+                    {
+                        Log.v(TAG, " waitForEvent : " + whileFetching);
+                        // if (whileFetching)
+                        {
+                            sleep(delayMs);
+
+                            // 受信待ちする...
+                            receive_from_camera(true, IPtpIpMessages.SEQ_EVENT_RECEIVE, new IPtpIpCommandCallback() {
+                                @Override
+                                public void receivedMessage(int id, byte[] rx_body)
+                                {
+                                    try
+                                    {
+                                        //  メッセージを受信。 応答を返さないといけない...
+                                        sendReplyMessage(rx_body);
+
+                                        //  そして次のイベントを待つ
+                                        waitForEvent();
+                                    }
+                                    catch (Exception e)
+                                    {
+                                        e.printStackTrace();
+                                    }
+                                }
+
+                                @Override
+                                public void onReceiveProgress(int currentBytes, int totalBytes, byte[] rx_body)
+                                {
+                                    Log.v(TAG, " onReceiveProgress : [" + currentBytes + "/" + totalBytes + "]");
+                                }
+
+                                @Override
+                                public boolean isReceiveMulti()
+                                {
+                                    return false;
+                                }
+                            }, true, delayMs);
+                        }
+                    }
+                    catch (Exception e)
+                    {
+                        e.printStackTrace();
+                    }
+                }
+            });
+            thread.start();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    private void sendReplyMessage(byte[] received_message)
+    {
+        try
+        {
+            Log.v(TAG, " RECEIVE : " + received_message.length + " bytes.");
+            if (received_message.length >= 26)
+            {
+                // 受信パケットを解析
+                int packetType = (((int) received_message[4]) & 0xff);
+                int eventCode =  ((((int) received_message[9]) & 0xff) << 8) + (((int) received_message[8]) & 0xff);
+                int parameter1 = ((((int) received_message[17]) & 0xff) << 24) + ((((int) received_message[16]) & 0xff) << 16) + ((((int) received_message[15]) & 0xff) << 8) + (((int) received_message[14]) & 0xff);
+                int parameter2 = ((((int) received_message[21]) & 0xff) << 24) + ((((int) received_message[20]) & 0xff) << 16) + ((((int) received_message[19]) & 0xff) << 8) + (((int) received_message[18]) & 0xff);
+                int parameter3 = ((((int) received_message[25]) & 0xff) << 24) + ((((int) received_message[24]) & 0xff) << 16) + ((((int) received_message[23]) & 0xff) << 8) + (((int) received_message[22]) & 0xff);
+                Log.v(TAG, String.format(" event : 0x%x, code: 0x%x, prm1: 0x%x, prm2: 0x%x, prm3 : 0x%x", packetType, eventCode, parameter1, parameter2, parameter3));
+                if (eventCode == 0xc101)
+                {
+                    // イベントの受信指示
+                    issuer.enqueueCommand(new PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_GET_STATUS, true, 0, 0x9116));
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
 }
diff --git a/app/src/main/java/net/osdn/gokigen/a01d/camera/nikon/wrapper/status/NikonStatusWatcher.java b/app/src/main/java/net/osdn/gokigen/a01d/camera/nikon/wrapper/status/NikonStatusWatcher.java
deleted file mode 100644 (file)
index e076868..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-package net.osdn.gokigen.a01d.camera.nikon.wrapper.status;
-
-import androidx.annotation.NonNull;
-
-import net.osdn.gokigen.a01d.camera.ICameraStatusWatcher;
-import net.osdn.gokigen.a01d.liveview.ICameraStatusUpdateNotify;
-
-public class NikonStatusWatcher implements ICameraStatusWatcher
-{
-
-    @Override
-    public void startStatusWatch(@NonNull ICameraStatusUpdateNotify notifier) {
-
-    }
-
-    @Override
-    public void stopStatusWatch() {
-
-    }
-}
index 1bff162..b824009 100644 (file)
@@ -21,7 +21,10 @@ public interface IPtpIpMessages
     int SEQ_GET_VIEWFRAME = 16;
     int SEQ_SET_DEVICE_PROPERTY_2 = 17;
     int SEQ_SET_DEVICE_PROPERTY_3 = 18;
-
+    int SEQ_START_LIVEVIEW = 19;
+    int SEQ_STOP_LIVEVIEW = 20;
+    int SEQ_DEVICE_READY = 21;
+    int SEQ_AFDRIVE = 22;
 
     int GET_STORAGE_ID = 101;
     int GET_STORAGE_INFO = 102;
index e1672bb..72f9d4d 100644 (file)
@@ -61,6 +61,7 @@ public class PtpIpCommandPublisher implements IPtpIpCommandPublisher, IPtpIpComm
     {
         try
         {
+            Log.v(TAG, " connect()");
             socket = new Socket(ipAddress, portNumber);
             return (true);
         }
@@ -129,6 +130,7 @@ public class PtpIpCommandPublisher implements IPtpIpCommandPublisher, IPtpIpComm
             return;
         }
         isStart = true;
+        Log.v(TAG, " start()");
 
         Thread thread = new Thread(new Runnable()
         {
diff --git a/app/src/main/java/net/osdn/gokigen/a01d/camera/ptpip/wrapper/command/PtpIpResponseReceiver.java b/app/src/main/java/net/osdn/gokigen/a01d/camera/ptpip/wrapper/command/PtpIpResponseReceiver.java
new file mode 100644 (file)
index 0000000..d53890b
--- /dev/null
@@ -0,0 +1,53 @@
+package net.osdn.gokigen.a01d.camera.ptpip.wrapper.command;
+
+import android.util.Log;
+
+public class PtpIpResponseReceiver implements IPtpIpCommandCallback
+{
+    private final String TAG = toString();
+
+    public PtpIpResponseReceiver()
+    {
+        //
+    }
+
+    @Override
+    public void receivedMessage(int id, byte[] rx_body)
+    {
+        if (rx_body != null)
+        {
+            try
+            {
+                if (rx_body.length > 10)
+                {
+                    int responseCode = (rx_body[9] & 0xff) + ((rx_body[10] & 0xff) * 256);
+                    Log.v(TAG, String.format(" ID : %d, RESPONSE CODE : 0x%x ", id, responseCode));
+                }
+                else
+                {
+                    Log.v(TAG, " receivedMessage() " + id + " " + rx_body.length + " bytes.");
+                }
+            }
+            catch (Exception e)
+            {
+                e.printStackTrace();
+            }
+        }
+        else
+        {
+            Log.v(TAG, " receivedMessage() " + id);
+        }
+    }
+
+    @Override
+    public void onReceiveProgress(int currentBytes, int totalBytes, byte[] rx_body)
+    {
+        Log.v(TAG, " onReceiveProgress() " + currentBytes + "/" + totalBytes);
+    }
+
+    @Override
+    public boolean isReceiveMulti()
+    {
+        return (false);
+    }
+}
diff --git a/app/src/main/java/net/osdn/gokigen/a01d/camera/ptpip/wrapper/liveview/IPtpIpLiveViewImageCallback.java b/app/src/main/java/net/osdn/gokigen/a01d/camera/ptpip/wrapper/liveview/IPtpIpLiveViewImageCallback.java
new file mode 100644 (file)
index 0000000..749fe9e
--- /dev/null
@@ -0,0 +1,9 @@
+package net.osdn.gokigen.a01d.camera.ptpip.wrapper.liveview;
+
+import java.util.Map;
+
+public interface IPtpIpLiveViewImageCallback
+{
+    void onCompleted(byte[] data, Map<String, Object> metadata);
+    void onErrorOccurred(Exception  e);
+}