package net.osdn.gokigen.a01d.camera.canon.wrapper.connection;
-
import android.app.Activity;
import android.graphics.Color;
import android.util.Log;
import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.messages.PtpIpCommandGeneric;
import net.osdn.gokigen.a01d.camera.canon.wrapper.status.CanonStatusChecker;
+/**
+ * 従来のCanonカメラ接続シーケンス
+ *
+ */
public class CanonCameraConnectSequence implements Runnable, IPtpIpCommandCallback, IPtpIpMessages
{
private final String TAG = this.toString();
case SEQ_GET_EVENT1:
Log.v(TAG, " SEQ_GET_EVENT1 ");
interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting7), false, false, 0);
- //commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_INFORMATION, isDumpLog, 0, 0x1001));
- commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_SET_REMOTE_SHOOTING_MODE, isDumpLog, 0, 0x1001));
+ commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_INFORMATION, isDumpLog, 0, 0x1001));
break;
case SEQ_DEVICE_INFORMATION:
case SEQ_SET_DEVICE_PROPERTY_3:
Log.v(TAG, " SEQ_SET_DEVICE_PROPERTY_3 ");
interfaceProvider.getInformationReceiver().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(new CanonSetDevicePropertyValue(this, SEQ_DEVICE_PROPERTY_FINISHED, isDumpLog, 0, 300, 0xd1b0, 0x08));
break;
- case SEQ_SET_REMOTE_SHOOTING_MODE:
- Log.v(TAG, " SEQ_SET_REMOTE_SHOOTING_MODE ");
- interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting12), false, false, 0);
- try
- {
- // ちょっと(250ms)待つ
- Thread.sleep(250);
-
- // コマンド発行
- //commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_PROPERTY_FINISHED, isDumpLog, 0, 0x9086, 4, 0x00000001));
- commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_INFORMATION, isDumpLog, 0, 0x9086, 4, 0x00000001));
-
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- break;
-
case SEQ_DEVICE_PROPERTY_FINISHED:
Log.v(TAG, " SEQ_DEVICE_PROPERTY_FINISHED ");
interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.connect_connect_finished), false, false, 0);
interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.connect_connected), false, false, 0);
// ちょっと待つ
- Thread.sleep(1000);
+ Thread.sleep(500);
// 接続成功!のメッセージを出す
interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.connect_connected), false, false, 0);
--- /dev/null
+package net.osdn.gokigen.a01d.camera.canon.wrapper.connection
+
+import android.app.Activity
+import android.graphics.Color
+import android.util.Log
+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.CanonRegistrationMessage
+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.ptpip.wrapper.command.IPtpIpCommandCallback
+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpMessages
+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.messages.PtpIpCommandGeneric
+
+class CanonCameraConnectSequenceType1(val context: Activity, val cameraStatusReceiver: ICameraStatusReceiver, val cameraConnection: ICameraConnection, val interfaceProvider: IPtpIpInterfaceProvider, val statusChecker: CanonStatusChecker) : Runnable, IPtpIpCommandCallback, IPtpIpMessages
+{
+ private val isDumpLog = false
+ private val commandIssuer = interfaceProvider.commandPublisher
+
+ override fun run()
+ {
+ try
+ {
+ // カメラとTCP接続
+ val issuer = interfaceProvider.commandPublisher
+ if (!issuer.isConnected)
+ {
+ if (!interfaceProvider.commandCommunication.connect())
+ {
+ // 接続失敗...
+ interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.dialog_title_connect_failed_canon), false, true, Color.RED)
+ cameraConnection.alertConnectingFailed(context.getString(R.string.dialog_title_connect_failed_canon))
+ return
+ }
+ }
+ else
+ {
+ Log.v(TAG, "SOCKET IS ALREADY CONNECTED...")
+ }
+ // コマンドタスクの実行開始
+ issuer.start()
+
+ // 接続シーケンスの開始
+ sendRegistrationMessage()
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.dialog_title_connect_failed_canon), false, true, Color.RED)
+ cameraConnection.alertConnectingFailed(e.message)
+ }
+ }
+
+ override fun onReceiveProgress(currentBytes: Int, totalBytes: Int, body: ByteArray?)
+ {
+ Log.v(TAG, " $currentBytes/$totalBytes")
+ }
+
+ override fun isReceiveMulti(): Boolean
+ {
+ return false
+ }
+
+ @ExperimentalUnsignedTypes
+ override fun receivedMessage(id: Int, rx_body: ByteArray)
+ {
+ when (id)
+ {
+ IPtpIpMessages.SEQ_REGISTRATION -> if (checkRegistrationMessage(rx_body)) {
+ sendInitEventRequest(rx_body)
+ } else {
+ cameraConnection.alertConnectingFailed(context.getString(R.string.connect_error_message))
+ }
+ 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))
+ } else {
+ cameraConnection.alertConnectingFailed(context.getString(R.string.connect_error_message))
+ }
+ IPtpIpMessages.SEQ_OPEN_SESSION -> {
+ Log.v(TAG, " SEQ_OPEN_SESSION ")
+ interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting2), false, false, 0)
+ commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_INIT_SESSION, isDumpLog, 0, 0x902f))
+ }
+ IPtpIpMessages.SEQ_INIT_SESSION -> {
+ Log.v(TAG, " SEQ_INIT_SESSION ")
+ interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting3), false, false, 0)
+ commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_CHANGE_REMOTE, isDumpLog, 0, 0x9114, 4, 0x15))
+ }
+ IPtpIpMessages.SEQ_CHANGE_REMOTE -> {
+ Log.v(TAG, " SEQ_CHANGE_REMOTE ")
+ interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting4), false, false, 0)
+ commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_SET_EVENT_MODE, isDumpLog, 0, 0x9115, 4, 0x02))
+ }
+ IPtpIpMessages.SEQ_SET_EVENT_MODE -> {
+ Log.v(TAG, " SEQ_SET_EVENT_MODE ")
+ interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting5), false, false, 0)
+ commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_GET_EVENT, isDumpLog, 0, 0x913d, 4, 0x0fff))
+ }
+ IPtpIpMessages.SEQ_GET_EVENT -> {
+ Log.v(TAG, " SEQ_GET_EVENT ")
+ interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting6), false, false, 0)
+ commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_GET_EVENT1, isDumpLog, 0, 0x9033, 4, 0x00000000))
+ }
+ IPtpIpMessages.SEQ_GET_EVENT1 -> {
+ Log.v(TAG, " SEQ_GET_EVENT1 ")
+ interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting7), false, false, 0)
+ //commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_INFORMATION, isDumpLog, 0, 0x1001));
+ commandIssuer!!.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_SET_REMOTE_SHOOTING_MODE, isDumpLog, 0, 0x1001))
+ }
+ IPtpIpMessages.SEQ_DEVICE_INFORMATION -> {
+ Log.v(TAG, " SEQ_DEVICE_INFORMATION ")
+ 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))
+ commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_DEVICE_PROPERTY, isDumpLog, 0, 0x9127, 4, 0x0000d169))
+ commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_DEVICE_PROPERTY, isDumpLog, 0, 0x9127, 4, 0x0000d16a))
+ commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_DEVICE_PROPERTY, isDumpLog, 0, 0x9127, 4, 0x0000d16b))
+ commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_DEVICE_PROPERTY, isDumpLog, 0, 0x9127, 4, 0x0000d1af))
+ }
+ IPtpIpMessages.SEQ_DEVICE_PROPERTY -> {
+ Log.v(TAG, " SEQ_DEVICE_PROPERTY ")
+ interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting9), false, false, 0)
+ if (rx_body[8] == 0x01.toByte() && rx_body[9] == 0x20.toByte()) {
+ // コマンドが受け付けられたときだけ次に進む!
+ try {
+ // ちょっと(250ms)待つ
+ Thread.sleep(250)
+
+ // コマンド発行
+ 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 ")
+ 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))
+ }
+ IPtpIpMessages.SEQ_SET_DEVICE_PROPERTY_2 -> {
+ Log.v(TAG, " SEQ_SET_DEVICE_PROPERTY_2 ")
+ interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting11), false, false, 0)
+ commandIssuer.enqueueCommand(CanonSetDevicePropertyValue(this, IPtpIpMessages.SEQ_SET_DEVICE_PROPERTY_3, isDumpLog, 0, 150, 0xd136, 0x00))
+ }
+ IPtpIpMessages.SEQ_SET_DEVICE_PROPERTY_3 -> {
+ 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))
+ }
+ IPtpIpMessages.SEQ_SET_REMOTE_SHOOTING_MODE -> {
+ Log.v(TAG, " SEQ_SET_REMOTE_SHOOTING_MODE ")
+ interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting12), false, false, 0)
+ try {
+ // ちょっと(250ms)待つ
+ Thread.sleep(250)
+
+ // コマンド発行
+ //commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_PROPERTY_FINISHED, isDumpLog, 0, 0x9086, 4, 0x00000001));
+ commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_DEVICE_INFORMATION, isDumpLog, 0, 0x9086, 4, 0x00000001))
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ IPtpIpMessages.SEQ_DEVICE_PROPERTY_FINISHED -> {
+ Log.v(TAG, " SEQ_DEVICE_PROPERTY_FINISHED ")
+ interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.connect_connect_finished), false, false, 0)
+ connectFinished()
+ Log.v(TAG, "CHANGED MODE : DONE.")
+ }
+ else -> {
+ Log.v(TAG, "RECEIVED UNKNOWN ID : $id")
+ cameraConnection.alertConnectingFailed(context.getString(R.string.connect_receive_unknown_message))
+ }
+ }
+ }
+
+ private fun sendRegistrationMessage()
+ {
+ interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.connect_start), false, false, 0)
+ cameraStatusReceiver.onStatusNotify(context.getString(R.string.connect_start))
+ commandIssuer.enqueueCommand(CanonRegistrationMessage(this))
+ }
+
+ @ExperimentalUnsignedTypes
+ private fun sendInitEventRequest(receiveData: ByteArray)
+ {
+ interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.connect_start_2), false, false, 0)
+ cameraStatusReceiver.onStatusNotify(context.getString(R.string.connect_start_2))
+ try
+ {
+ var eventConnectionNumber: Int = receiveData[8].toUByte().toInt() and 0xff
+ eventConnectionNumber += (receiveData[9].toUByte().toInt() and 0xff shl 8)
+ eventConnectionNumber += (receiveData[10].toUByte().toInt() and 0xff shl 16)
+ eventConnectionNumber += (receiveData[11].toUByte().toInt() and 0xff shl 24)
+ statusChecker.setEventConnectionNumber(eventConnectionNumber)
+ interfaceProvider.cameraStatusWatcher.startStatusWatch(interfaceProvider.statusListener)
+ commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_OPEN_SESSION, isDumpLog, 0, 0x1002, 4, 0x41))
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ private fun checkRegistrationMessage(receiveData: ByteArray?): Boolean
+ {
+ // データ(Connection Number)がないときにはエラーと判断する
+ return !(receiveData == null || receiveData.size < 12)
+ }
+
+ private fun checkEventInitialize(receiveData: ByteArray?): Boolean
+ {
+ Log.v(TAG, "checkEventInitialize() ")
+ return receiveData != null
+ }
+
+ private fun connectFinished()
+ {
+ try
+ {
+ // 接続成功のメッセージを出す
+ interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.connect_connected), false, false, 0)
+
+ // ちょっと待つ
+ Thread.sleep(1000)
+
+ // 接続成功!のメッセージを出す
+ interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.connect_connected), false, false, 0)
+ onConnectNotify()
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ private fun onConnectNotify()
+ {
+ try
+ {
+ val thread = Thread {
+ // カメラとの接続確立を通知する
+ cameraStatusReceiver.onStatusNotify(context.getString(R.string.connect_connected))
+ cameraStatusReceiver.onCameraConnected()
+ Log.v(TAG, " onConnectNotify()")
+ }
+ thread.start()
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ companion object
+ {
+ private const val TAG = "CanonConnectSeq.1"
+ }
+}
\ No newline at end of file
private final String TAG = this.toString();
private final IPtpIpCommandPublisher commandIssuer;
private final int delayMs;
- //private CanonLiveViewImageReceiver imageReceiver;
+ private final boolean isDumpLog = false;
+ private final boolean isSearchJpegHeader;
+ private final int retryCount = 1500;
private final CanonLiveViewImageReceiver imageReceiver;
private IImageDataReceiver dataReceiver = null;
private boolean liveViewIsReceiving = false;
private boolean commandIssued = false;
- public CanonLiveViewControl(@NonNull Activity context, @NonNull IPtpIpInterfaceProvider interfaceProvider, int delayMs)
+ public CanonLiveViewControl(@NonNull Activity context, @NonNull IPtpIpInterfaceProvider interfaceProvider, int delayMs, boolean isSearchJpegHeader)
{
this.commandIssuer = interfaceProvider.getCommandPublisher();
+ this.isSearchJpegHeader = isSearchJpegHeader;
this.delayMs = delayMs;
//this.imageReceiver = new CanonLiveViewImageReceiver(this);
- this.imageReceiver = new CanonLiveViewImageReceiver(this);
+ this.imageReceiver = new CanonLiveViewImageReceiver(context,this);
Log.v(TAG, " -=-=-=-=-=- CanonLiveViewControl : delay " + delayMs + " ms");
}
{
if (!commandIssued)
{
+ if (isDumpLog)
+ {
+ Log.v(TAG, " enqueueCommand() ");
+ }
commandIssued = true;
- commandIssuer.enqueueCommand(new PtpIpCommandGenericWithRetry(imageReceiver, SEQ_GET_VIEWFRAME, delayMs, 2000, false, false, 0, 0x9153, 12, 0x00200000, 0x01, 0x00, 0x00));
+ commandIssuer.enqueueCommand(new PtpIpCommandGenericWithRetry(imageReceiver, SEQ_GET_VIEWFRAME, delayMs, retryCount, false, false, 0, 0x9153, 12, 0x00200000, 0x01, 0x00, 0x00));
}
try
{
{
if ((dataReceiver != null)&&(data != null))
{
- Log.v(TAG, " ---+++--- RECEIVED LV IMAGE ---+++--- : " + data.length + " bytes.");
- //dataReceiver.setImageData(data, metadata);
- if (data.length > 8)
+ if (isDumpLog)
{
- dataReceiver.setImageData(Arrays.copyOfRange(data, 8, data.length), metadata); // ヘッダ部分を切り取って送る
+ Log.v(TAG, " ---+++--- RECEIVED LV IMAGE ---+++--- : " + data.length + " bytes.");
+ }
+ int headerSize = searchJpegHeader(data);
+ if (headerSize >= 0)
+ {
+ dataReceiver.setImageData(Arrays.copyOfRange(data, headerSize, data.length), metadata); // ヘッダ部分を切り取って送る
}
}
}
commandIssued = false;
}
+ private int searchJpegHeader(byte[] data)
+ {
+ if (data.length <= 8)
+ {
+ return (-1);
+ }
+ if (!isSearchJpegHeader)
+ {
+ // JPEG ヘッダを探さない場合は、8バイト固定とする
+ return (8);
+ }
+ try
+ {
+ int size = data.length - 1;
+ int index = 0;
+ while (index < size)
+ {
+ if ((data[index] == (byte) 0xff)&&(data[index + 1] == (byte) 0xd8))
+ {
+ return (index);
+ }
+ index++;
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ // 見つからなかったときは 8 を返す
+ return (8);
+ }
+
@Override
public void onErrorOccurred(Exception e)
{