OSDN Git Service

Canonのステータス受信部をkotlin化
authorMRSa <mrsa@myad.jp>
Sun, 20 Dec 2020 14:38:54 +0000 (23:38 +0900)
committerMRSa <mrsa@myad.jp>
Sun, 20 Dec 2020 14:38:54 +0000 (23:38 +0900)
app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/CanonInterfaceProvider.java
app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/connection/CanonCameraConnectSequence.java
app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/connection/CanonCameraConnectSequenceType1.kt
app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/connection/CanonConnection.java
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/status/CanonStatusChecker.kt [new file with mode: 0644]
app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/status/CanonStatusChecker0.java [moved from app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/status/CanonStatusChecker.java with 95% similarity]

index edb0fab..6ac6bb7 100644 (file)
@@ -25,6 +25,7 @@ import net.osdn.gokigen.a01d.camera.canon.wrapper.connection.CanonConnection;
 import net.osdn.gokigen.a01d.camera.canon.operation.CanonZoomLensControl;
 import net.osdn.gokigen.a01d.camera.canon.wrapper.hardware.CanonCameraInformation;
 import net.osdn.gokigen.a01d.camera.canon.wrapper.liveview.CanonLiveViewControl;
+import net.osdn.gokigen.a01d.camera.canon.wrapper.status.CanonStatusChecker;
 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;
@@ -33,7 +34,6 @@ import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.PtpIpAsyncResponseRece
 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.PtpIpCommandPublisher;
 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.status.IPtpIpRunModeHolder;
 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.status.PtpIpRunMode;
-import net.osdn.gokigen.a01d.camera.canon.wrapper.status.CanonStatusChecker;
 import net.osdn.gokigen.a01d.liveview.IAutoFocusFrameDisplay;
 import net.osdn.gokigen.a01d.liveview.ICameraStatusUpdateNotify;
 import net.osdn.gokigen.a01d.liveview.IIndicatorControl;
@@ -122,7 +122,7 @@ public class CanonInterfaceProvider implements IPtpIpInterfaceProvider, IDisplay
         commandPublisher = new PtpIpCommandPublisher(ipAddress, CONTROL_PORT, false, false);
         liveViewControl = new CanonLiveViewControl(context, this, delayMs, isSearchJpegHeader);  //
         asyncReceiver = new PtpIpAsyncResponseReceiver(ipAddress, ASYNC_RESPONSE_PORT);
-        statusChecker = new CanonStatusChecker(context, commandPublisher, ipAddress, EVENT_PORT);
+        statusChecker = new CanonStatusChecker(commandPublisher, ipAddress, EVENT_PORT);
         canonConnection = new CanonConnection(context, provider, this, statusChecker);
         cameraInformation = new CanonCameraInformation();
         zoomControl = new CanonZoomLensControl(context, commandPublisher);
index 08872e6..78d3394 100644 (file)
@@ -10,13 +10,13 @@ import net.osdn.gokigen.a01d.R;
 import net.osdn.gokigen.a01d.camera.ICameraConnection;
 import net.osdn.gokigen.a01d.camera.ICameraStatusReceiver;
 import net.osdn.gokigen.a01d.camera.canon.wrapper.command.messages.specific.CanonSetDevicePropertyValue;
+import net.osdn.gokigen.a01d.camera.canon.wrapper.status.CanonStatusChecker;
 import net.osdn.gokigen.a01d.camera.ptpip.IPtpIpInterfaceProvider;
 import net.osdn.gokigen.a01d.camera.canon.wrapper.command.messages.specific.CanonRegistrationMessage;
 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.canon.wrapper.status.CanonStatusChecker;
 
 /**
  *   従来のCanonカメラ接続シーケンス
index 1975d33..4bb41ae 100644 (file)
@@ -18,6 +18,7 @@ class CanonCameraConnectSequenceType1(val context: Activity, val cameraStatusRec
 {
     private val isDumpLog = false
     private val commandIssuer = interfaceProvider.commandPublisher
+    private var requestMessageCount = 0
 
     override fun run()
     {
@@ -75,7 +76,7 @@ class CanonCameraConnectSequenceType1(val context: Activity, val cameraStatusRec
             }
             IPtpIpMessages.SEQ_EVENT_INITIALIZE -> if (checkEventInitialize(rx_body)) {
                 interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting1), false, false, 0)
-                commandIssuer!!.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_OPEN_SESSION, isDumpLog, 0, 0x1002, 4, 0x41))
+                commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_OPEN_SESSION, isDumpLog, 0, 0x1002, 4, 0x41))
             } else {
                 cameraConnection.alertConnectingFailed(context.getString(R.string.connect_error_message))
             }
@@ -112,6 +113,7 @@ class CanonCameraConnectSequenceType1(val context: Activity, val cameraStatusRec
             }
             IPtpIpMessages.SEQ_DEVICE_INFORMATION -> {
                 Log.v(TAG, " SEQ_DEVICE_INFORMATION ")
+                requestMessageCount = 0
                 interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting8), false, false, 0)
                 //commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_PROPERTY, isDumpLog, 0, 0x9127, 4, 0x0000d1a6));
                 commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_DEVICE_PROPERTY, isDumpLog, 0, 0x9127, 4, 0x0000d1a6))
@@ -122,22 +124,31 @@ class CanonCameraConnectSequenceType1(val context: Activity, val cameraStatusRec
             }
             IPtpIpMessages.SEQ_DEVICE_PROPERTY -> {
                 Log.v(TAG, " SEQ_DEVICE_PROPERTY ")
+                requestMessageCount++
                 interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting9), false, false, 0)
-                if (rx_body[8] == 0x01.toByte() && rx_body[9] == 0x20.toByte()) {
+                if (rx_body[8] == 0x01.toByte() && rx_body[9] == 0x20.toByte())
+                {
                     // コマンドが受け付けられたときだけ次に進む!
-                    try {
+                    try
+                    {
                         // ちょっと(250ms)待つ
                         Thread.sleep(250)
 
-                        // コマンド発行
-                        commandIssuer.enqueueCommand(CanonSetDevicePropertyValue(this, IPtpIpMessages.SEQ_SET_DEVICE_PROPERTY, isDumpLog, 0, 150, 0xd136, 0x00))
-                    } catch (e: Exception) {
+                        if (requestMessageCount >= 4)
+                        {
+                            // コマンド発行
+                            commandIssuer.enqueueCommand(CanonSetDevicePropertyValue(this, IPtpIpMessages.SEQ_SET_DEVICE_PROPERTY, isDumpLog, 0, 150, 0xd136, 0x00))
+                        }
+                    }
+                    catch (e: Exception)
+                    {
                         e.printStackTrace()
                     }
                 }
             }
             IPtpIpMessages.SEQ_SET_DEVICE_PROPERTY -> {
                 Log.v(TAG, " SEQ_SET_DEVICE_PROPERTY ")
+                requestMessageCount = 0
                 interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting10), false, false, 0)
                 commandIssuer.enqueueCommand(CanonSetDevicePropertyValue(this, IPtpIpMessages.SEQ_SET_DEVICE_PROPERTY_2, isDumpLog, 0, 150, 0xd136, 0x01))
             }
@@ -150,7 +161,7 @@ class CanonCameraConnectSequenceType1(val context: Activity, val cameraStatusRec
                 Log.v(TAG, " SEQ_SET_DEVICE_PROPERTY_3 ")
                 interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting12), false, false, 0)
                 //commandIssuer.enqueueCommand(new CanonSetDevicePropertyValue(this, SEQ_SET_REMOTE_SHOOTING_MODE, isDumpLog, 0, 300, 0xd1b0, 0x08));
-                commandIssuer!!.enqueueCommand(CanonSetDevicePropertyValue(this, IPtpIpMessages.SEQ_DEVICE_PROPERTY_FINISHED, isDumpLog, 0, 300, 0xd1b0, 0x08))
+                commandIssuer.enqueueCommand(CanonSetDevicePropertyValue(this, IPtpIpMessages.SEQ_DEVICE_PROPERTY_FINISHED, isDumpLog, 0, 300, 0xd1b0, 0x08))
             }
             IPtpIpMessages.SEQ_SET_REMOTE_SHOOTING_MODE -> {
                 Log.v(TAG, " SEQ_SET_REMOTE_SHOOTING_MODE ")
index 28f4e69..ccbe80d 100644 (file)
@@ -20,8 +20,8 @@ import androidx.preference.PreferenceManager;
 import net.osdn.gokigen.a01d.R;
 import net.osdn.gokigen.a01d.camera.ICameraConnection;
 import net.osdn.gokigen.a01d.camera.ICameraStatusReceiver;
-import net.osdn.gokigen.a01d.camera.ptpip.IPtpIpInterfaceProvider;
 import net.osdn.gokigen.a01d.camera.canon.wrapper.status.CanonStatusChecker;
+import net.osdn.gokigen.a01d.camera.ptpip.IPtpIpInterfaceProvider;
 import net.osdn.gokigen.a01d.preference.IPreferencePropertyAccessor;
 
 import java.util.concurrent.Executor;
index d849167..49ae960 100644 (file)
@@ -26,7 +26,7 @@ public class CanonLiveViewControl implements ILiveViewControl, ILiveViewListener
     private final int delayMs;
     private final boolean isDumpLog = false;
     private final boolean isSearchJpegHeader;
-    private final int retryCount = 1500;
+    private final int retryCount = 1200;
     private final CanonLiveViewImageReceiver imageReceiver;
     private IImageDataReceiver dataReceiver = null;
     private boolean liveViewIsReceiving = false;
@@ -37,7 +37,6 @@ public class CanonLiveViewControl implements ILiveViewControl, ILiveViewListener
         this.commandIssuer = interfaceProvider.getCommandPublisher();
         this.isSearchJpegHeader = isSearchJpegHeader;
         this.delayMs = delayMs;
-        //this.imageReceiver = new CanonLiveViewImageReceiver(this);
         this.imageReceiver = new CanonLiveViewImageReceiver(context,this);
         Log.v(TAG, " -=-=-=-=-=- CanonLiveViewControl : delay " + delayMs + " ms");
     }
diff --git a/app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/status/CanonStatusChecker.kt b/app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/status/CanonStatusChecker.kt
new file mode 100644 (file)
index 0000000..39b8072
--- /dev/null
@@ -0,0 +1,414 @@
+package net.osdn.gokigen.a01d.camera.canon.wrapper.status
+
+import android.util.Log
+import net.osdn.gokigen.a01d.camera.ICameraStatus
+import net.osdn.gokigen.a01d.camera.ICameraStatusWatcher
+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.PtpIpCommandGenericWithRetry
+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.messages.specific.InitEventRequest
+import net.osdn.gokigen.a01d.camera.utils.SimpleLogDumper
+import net.osdn.gokigen.a01d.liveview.ICameraStatusUpdateNotify
+import java.io.DataOutputStream
+import java.net.Socket
+import java.util.*
+
+class CanonStatusChecker(private val issuer: IPtpIpCommandPublisher, val ipAddress: String, val portNumber: Int) : IPtpIpCommandCallback, ICameraStatusWatcher, ICameraStatus
+{
+    private val statusHolder = CanonStatusHolder()
+    private val logcat = false
+    private lateinit var notifier: ICameraStatusUpdateNotify
+    private lateinit var socket: Socket
+    private lateinit var dos: DataOutputStream
+    private var whileFetching = false
+    private var eventConnectionNumber = 0
+
+    override fun onReceiveProgress(currentBytes: Int, totalBytes: Int, body: ByteArray)
+    {
+        Log.v(TAG, " $currentBytes/$totalBytes")
+    }
+
+    override fun isReceiveMulti(): Boolean
+    {
+        return (false)
+    }
+
+    override fun receivedMessage(id: Int, data: ByteArray)
+    {
+        try
+        {
+            logcat("receivedMessage : " + id + ", length: " + data.size)
+            if (id == IPtpIpMessages.SEQ_EVENT_INITIALIZE)
+            {
+                // 終わる...んじゃなくて、イベント受信待ちに遷移する。
+                Log.v(TAG, " ----- PTP-IP Connection is ESTABLISHED. -----")
+                waitForEvent()
+                return
+            }
+            if (data.size < STATUS_MESSAGE_HEADER_SIZE)
+            {
+                Log.v(TAG, " received status event length is short. (" + data.size + " bytes.)")
+                return
+            }
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+    }
+
+    override fun getStatusList(key: String): List<String>
+    {
+        try
+        {
+            return (statusHolder.getAvailableItemList(key))
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+        return (ArrayList())
+    }
+
+    override fun getStatus(key: String): String
+    {
+        try
+        {
+            return (statusHolder.getItemStatus(key))
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+        return ("")
+    }
+
+    override fun setStatus(key: String, value: String)
+    {
+        try
+        {
+            logcat("setStatus($key, $value)")
+
+            //
+            // ここで設定を行う。
+            //
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+    }
+
+    override fun startStatusWatch(notifier: ICameraStatusUpdateNotify)
+    {
+        if (whileFetching)
+        {
+            Log.v(TAG, "startStatusWatch() already starting.")
+            return
+        }
+        try
+        {
+            this.notifier = notifier
+            whileFetching = true
+
+            // セッションをオープンする
+            val isConnect = connect()
+            if (!isConnect)
+            {
+                Log.v(TAG, "  CONNECT FAIL...(EVENT) : $ipAddress  $portNumber")
+            }
+            issueCommand(InitEventRequest(this, eventConnectionNumber))
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+    }
+
+    override fun stopStatusWatch()
+    {
+        Log.v(TAG, "stoptStatusWatch()")
+        whileFetching = false
+    }
+
+    private fun logcat(message: String)
+    {
+        if (logcat)
+        {
+            Log.v(TAG, message)
+        }
+    }
+
+    private fun connect(): Boolean
+    {
+        try
+        {
+            socket = Socket(ipAddress, portNumber)
+            return (true)
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+        return (false)
+    }
+
+    fun setEventConnectionNumber(connectionNumber: Int)
+    {
+        eventConnectionNumber = connectionNumber
+    }
+
+    private fun issueCommand(command: IPtpIpCommand)
+    {
+        try
+        {
+            val commandBody = command.commandBody()
+            if (commandBody != null)
+            {
+                // コマンドボディが入っていた場合には、コマンド送信(入っていない場合は受信待ち)
+                sendToCamera(command.dumpLog(), commandBody)
+            }
+            receiveFromCamera(command.dumpLog(), command.id, command.responseCallback(), command.receiveAgainShortLengthMessage(), command.receiveDelayMs())
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+    }
+
+    /**
+     * カメラにコマンドを送信する(メイン部分)
+     *
+     */
+    private fun sendToCamera(isDumpReceiveLog: Boolean, byte_array: ByteArray)
+    {
+        try
+        {
+            if (!::socket.isInitialized)
+            {
+                // ソケットが初期化されていないので送らない
+                Log.w(TAG, " DO NOT INITIALIZE Socket. (SEND)")
+                return
+            }
+
+            // メッセージボディを加工: 最初に4バイトのレングス長をつける
+            val sendData = ByteArray(byte_array.size + 4)
+            sendData[0] = (byte_array.size + 4).toByte()
+            sendData[1] = 0x00
+            sendData[2] = 0x00
+            sendData[3] = 0x00
+            System.arraycopy(byte_array, 0, sendData, 4, byte_array.size)
+            if (isDumpReceiveLog)
+            {
+                // ログに送信メッセージを出力する
+                SimpleLogDumper.dump_bytes("Evt.SEND[" + sendData.size + "] ", sendData)
+            }
+
+            // (データを)送信
+            if (!::dos.isInitialized)
+            {
+                dos = DataOutputStream(socket.getOutputStream())
+            }
+            dos.write(sendData)
+            dos.flush()
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+    }
+
+    /**
+     * カメラからにコマンドの結果を受信する(メイン部分)
+     *
+     */
+    private fun receiveFromCamera(isDumpReceiveLog: Boolean, id: Int, callback: IPtpIpCommandCallback?, receiveAgain: Boolean, delayMs: Int)
+    {
+        if (!::socket.isInitialized)
+        {
+            // ソケットが初期化されていないので受信しない
+            Log.w(TAG, " DO NOT INITIALIZE Socket. (RECV)")
+            return
+        }
+
+        try
+        {
+            sleep(delayMs)
+            var isFirstTime = true
+            var totalReadBytes: Int
+            val receive_message_buffer_size = BUFFER_SIZE
+            val byte_array = ByteArray(receive_message_buffer_size)
+            val inputStream = socket.getInputStream()
+            if (inputStream != null) {
+                var read_bytes = inputStream.read(byte_array, 0, receive_message_buffer_size)
+                val receive_body: ByteArray
+                if (read_bytes > 4) {
+                    if (receiveAgain) {
+                        val length = (byte_array[3].toInt() and 0xff shl 24) + (byte_array[2].toInt() and 0xff shl 16) + (byte_array[1].toInt() and 0xff shl 8) + (byte_array[0].toInt() and 0xff)
+                        if (length > receive_message_buffer_size) {
+                            Log.v(TAG, "+++++ TOTAL RECEIVE MESSAGE SIZE IS $length +++++")
+                        }
+                        totalReadBytes = read_bytes
+                        while (length > totalReadBytes || length == read_bytes && byte_array[4].toInt() == 0x02) {
+                            // データについて、もう一回受信が必要な場合...
+                            if (isDumpReceiveLog) {
+                                Log.v(TAG, "--- RECEIVE AGAIN --- [" + length + "(" + read_bytes + ") " + byte_array[4] + "] ")
+                            }
+                            sleep(delayMs)
+                            val read_bytes2 = inputStream.read(byte_array, read_bytes, receive_message_buffer_size - read_bytes)
+                            if (read_bytes2 > 0) {
+                                read_bytes = read_bytes + read_bytes2
+                                totalReadBytes = totalReadBytes + read_bytes2
+                            } else {
+                                // よみだし終了。
+                                Log.v(TAG, "FINISHED RECEIVE... ")
+                                break
+                            }
+                            if (callback != null) {
+                                if (callback.isReceiveMulti) {
+                                    var offset = 0
+                                    if (isFirstTime) {
+                                        // 先頭のヘッダ部分をカットして送る
+                                        offset = 12
+                                        isFirstTime = false
+                                        //Log.v(TAG, " FIRST TIME : " + read_bytes + " " + offset);
+                                    }
+                                    callback.onReceiveProgress(read_bytes - offset, length, Arrays.copyOfRange(byte_array, offset, read_bytes))
+                                    read_bytes = 0
+                                } else {
+                                    callback.onReceiveProgress(read_bytes, length, null)
+                                }
+                            }
+                        }
+                    }
+                    receive_body = Arrays.copyOfRange(byte_array, 0, read_bytes)
+                } else {
+                    receive_body = ByteArray(1)
+                }
+                if (isDumpReceiveLog) {
+                    // ログに受信メッセージを出力する
+                    Log.v(TAG, " receive_from_camera() : $read_bytes bytes.")
+                    SimpleLogDumper.dump_bytes(" Evt.RECV[" + receive_body.size + "] ", receive_body)
+                }
+                if (callback != null) {
+                    if (callback.isReceiveMulti) {
+                        callback.receivedMessage(id, null)
+                    } else {
+                        callback.receivedMessage(id, receive_body)
+                        //callback.receivedMessage(id, Arrays.copyOfRange(receive_body, 0, receive_body.length));
+                    }
+                }
+            }
+        }
+        catch (e: Throwable)
+        {
+            e.printStackTrace()
+        }
+    }
+
+    private fun sleep(delayMs: Int)
+    {
+        try
+        {
+            Thread.sleep(delayMs.toLong())
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+    }
+
+    private fun waitForEvent()
+    {
+        val delayMs = 25
+        try
+        {
+            val thread = Thread(object : Runnable {
+                override fun run()
+                {
+                    try
+                    {
+                        Log.v(TAG, " waitForEvent : $whileFetching")
+                        sleep(delayMs)
+
+                        // 受信待ちする...
+                        receiveFromCamera(true, IPtpIpMessages.SEQ_EVENT_RECEIVE, object : IPtpIpCommandCallback {
+                            override fun receivedMessage(id: Int, rx_body: ByteArray)
+                            {
+                                try
+                                {
+                                    //  メッセージを受信。 応答を返さないといけない...
+                                    sendReplyMessage(rx_body)
+
+                                    //  そして次のイベントを待つ
+                                    waitForEvent()
+                                }
+                                catch (e: Exception)
+                                {
+                                    e.printStackTrace()
+                                }
+                            }
+
+                            override fun onReceiveProgress(currentBytes: Int, totalBytes: Int, rx_body: ByteArray)
+                            {
+                                Log.v(TAG, " onReceiveProgress : [$currentBytes/$totalBytes]")
+                            }
+
+                            override fun isReceiveMulti(): Boolean
+                            {
+                                return (false)
+                            }
+                        }, true, delayMs)
+                    }
+                    catch (e: Exception)
+                    {
+                        e.printStackTrace()
+                    }
+                }
+            })
+            thread.start()
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+    }
+
+    private fun sendReplyMessage(received_message: ByteArray)
+    {
+        try
+        {
+            Log.v(TAG, " RECEIVE : " + received_message.size + " bytes.")
+            if (received_message.size >= 26)
+            {
+                // 受信パケットを解析
+                val packetType = received_message[4].toUByte().toInt() and 0xff
+                val eventCode = (received_message[9].toUByte().toInt() and 0xff shl 8) + (received_message[8].toUByte().toInt() and 0xff)
+                val parameter1 = (received_message[17].toUByte().toInt() and 0xff shl 24) + (received_message[16].toUByte().toInt() and 0xff shl 16) + (received_message[15].toUByte().toInt() and 0xff shl 8) + (received_message[14].toUByte().toInt() and 0xff)
+                val parameter2 = (received_message[21].toUByte().toInt() and 0xff shl 24) + (received_message[20].toUByte().toInt() and 0xff shl 16) + (received_message[19].toUByte().toInt() and 0xff shl 8) + (received_message[18].toUByte().toInt() and 0xff)
+                val parameter3 = (received_message[25].toUByte().toInt() and 0xff shl 24) + (received_message[24].toUByte().toInt() and 0xff shl 16) + (received_message[23].toUByte().toInt() and 0xff shl 8) + (received_message[22].toUByte().toInt() and 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(PtpIpCommandGenericWithRetry(this, IPtpIpMessages.SEQ_GET_STATUS, 50, 200, isRetry = false, isDumpLog = true, holdId = 0, opcode = 0x9116, bodySize = 0, value = 0))
+                    Log.v(TAG, " SEND [Get Status] ")
+                }
+            }
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+    }
+
+    companion object
+    {
+        private const val BUFFER_SIZE = 1024 * 1024 + 8
+        private const val STATUS_MESSAGE_HEADER_SIZE = 14
+        private const val TAG = "CanonStatusChecker"
+    }
+
+}
@@ -25,7 +25,7 @@ import java.util.List;
 
 import static net.osdn.gokigen.a01d.camera.utils.SimpleLogDumper.dump_bytes;
 
-public class CanonStatusChecker implements IPtpIpCommandCallback, ICameraStatusWatcher, ICameraStatus
+public class CanonStatusChecker0 implements IPtpIpCommandCallback, ICameraStatusWatcher, ICameraStatus
 {
     private final String TAG = toString();
 
@@ -33,9 +33,9 @@ public class CanonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
     private static final int STATUS_MESSAGE_HEADER_SIZE = 14;
     private final IPtpIpCommandPublisher issuer;
     private ICameraStatusUpdateNotify notifier = null;
-    private CanonStatusHolder statusHolder;
+    private final CanonStatusHolder statusHolder;
     private boolean whileFetching = false;
-    private boolean logcat = false;
+    private final boolean logcat = false;
     private final String ipAddress;
     private final int portNumber;
 
@@ -44,7 +44,7 @@ public class CanonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
     private BufferedReader bufferedReader = null;
     private int eventConnectionNumber = 0;
 
-    public CanonStatusChecker(@NonNull Activity activity, @NonNull IPtpIpCommandPublisher issuer, @NonNull String ip, int portNumber)
+    public CanonStatusChecker0(@NonNull Activity activity, @NonNull IPtpIpCommandPublisher issuer, @NonNull String ip, int portNumber)
     {
         this.issuer = issuer;
         this.statusHolder = new CanonStatusHolder();
@@ -80,7 +80,7 @@ public class CanonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
 
             if (data.length < STATUS_MESSAGE_HEADER_SIZE)
             {
-                Log.v(TAG, "received status length is short. (" + data.length + " bytes.)");
+                Log.v(TAG, " received status event length is short. (" + data.length + " bytes.)");
                 return;
             }
 /*
@@ -107,10 +107,6 @@ public class CanonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
     {
         try
         {
-            if (statusHolder == null)
-            {
-                return (new ArrayList<>());
-            }
             return (statusHolder.getAvailableItemList(key));
         }
         catch (Exception e)
@@ -125,10 +121,6 @@ public class CanonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
     {
         try
         {
-            if (statusHolder == null)
-            {
-                return ("");
-            }
             return (statusHolder.getItemStatus(key));
         }
         catch (Exception e)
@@ -304,7 +296,7 @@ public class CanonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
             if (isDumpReceiveLog)
             {
                 // ログに送信メッセージを出力する
-                dump_bytes("SEND[" + sendData.length + "] ", sendData);
+                dump_bytes("Evt.SEND[" + sendData.length + "] ", sendData);
             }
 
             // (データを)送信
@@ -393,7 +385,7 @@ public class CanonStatusChecker implements IPtpIpCommandCallback, ICameraStatusW
                 {
                     // ログに受信メッセージを出力する
                     Log.v(TAG, " receive_from_camera() : " + read_bytes + " bytes.");
-                    dump_bytes("RECV[" + receive_body.length + "] ", receive_body);
+                    dump_bytes(" Evt.RECV[" + receive_body.length + "] ", receive_body);
                 }
                 if (callback != null)
                 {