*/
public static void dump_bytes(String header, byte[] data)
{
+ if (data == null)
+ {
+ Log.v(TAG, "DATA IS NULL");
+ return;
+ }
+ if (data.length > 8192)
+ {
+ Log.v(TAG, " --- DUMP DATA IS TOO LONG... " + data.length + " bytes.");
+ return;
+ }
+
int index = 0;
StringBuffer message;
message = new StringBuffer();
// コマンドの受信待ち時間(単位:ms)
int receiveDelayMs();
+ // 埋め込むシーケンス番号の位置
+ int embeddedSequenceNumberIndex();
+
+ // 埋め込むシーケンス番号の位置
+ int embeddedSequenceNumberIndex2();
+
+ // 埋め込むシーケンス番号の位置
+ int embeddedSequenceNumberIndex3();
+
// 送信するメッセージボディ
byte[] commandBody();
// 送信するメッセージボディ(連続送信する場合)
byte[] commandBody2();
+ // 送信するメッセージボディ(連続送信する場合)
+ byte[] commandBody3();
+
// コマンド送信結果(応答)の通知先
IPtpIpCommandCallback responseCallback();
if (commandBody != null)
{
// コマンドボディが入っていた場合には、コマンド送信(入っていない場合は受信待ち)
- send_to_camera(command.dumpLog(), commandBody, command.useSequenceNumber());
+ send_to_camera(command.dumpLog(), commandBody, command.useSequenceNumber(), command.embeddedSequenceNumberIndex());
byte[] commandBody2 = command.commandBody2();
if (commandBody2 != null)
{
// コマンドボディの2つめが入っていた場合には、コマンドを連続送信する
- send_to_camera(command.dumpLog(), commandBody2, command.useSequenceNumber());
+ send_to_camera(command.dumpLog(), commandBody2, command.useSequenceNumber(), command.embeddedSequenceNumberIndex2());
+ }
+ byte[] commandBody3 = command.commandBody3();
+ if (commandBody3 != null)
+ {
+ // コマンドボディの3つめが入っていた場合には、コマンドを連続送信する
+ send_to_camera(command.dumpLog(), commandBody3, command.useSequenceNumber(), command.embeddedSequenceNumberIndex3());
}
if (command.isIncrementSeqNumber())
{
* カメラにコマンドを送信する(メイン部分)
*
*/
- private void send_to_camera(boolean isDumpReceiveLog, byte[] byte_array, boolean useSequenceNumber)
+ private void send_to_camera(boolean isDumpReceiveLog, byte[] byte_array, boolean useSequenceNumber, int embeddedSequenceIndex)
{
try
{
if (useSequenceNumber)
{
// Sequence Number を反映させる
- sendData[14] = (byte) ((0x000000ff & sequenceNumber));
- sendData[15] = (byte) (((0x0000ff00 & sequenceNumber) >>> 8) & 0x000000ff);
- sendData[16] = (byte) (((0x00ff0000 & sequenceNumber) >>> 16) & 0x000000ff);
- sendData[17] = (byte) (((0xff000000 & sequenceNumber) >>> 24) & 0x000000ff);
+ sendData[embeddedSequenceIndex] = (byte) ((0x000000ff & sequenceNumber));
+ sendData[embeddedSequenceIndex + 1] = (byte) (((0x0000ff00 & sequenceNumber) >>> 8) & 0x000000ff);
+ sendData[embeddedSequenceIndex + 2] = (byte) (((0x00ff0000 & sequenceNumber) >>> 16) & 0x000000ff);
+ sendData[embeddedSequenceIndex + 3] = (byte) (((0xff000000 & sequenceNumber) >>> 24) & 0x000000ff);
if (isDumpReceiveLog)
{
Log.v(TAG, "----- SEQ No. : " + sequenceNumber + " -----");
InputStream is = socket.getInputStream();
if (is != null)
{
- int read_bytes = is.read(byte_array, 0, receive_message_buffer_size);
- byte[] receive_body;
- if (read_bytes > 4)
+ byte[] receive_body = null;
+ int read_bytes = 0;
+ while (read_bytes == 0)
+ {
+ read_bytes = is.available();
+ sleep(delayMs);
+ Log.v(TAG, " is.available() WAIT... ");
+ }
+ if (read_bytes > 0)
{
- if (receiveAgain)
+ read_bytes = is.read(byte_array, 0, receive_message_buffer_size);
+ if (read_bytes > 4)
{
- 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)
- {
- Log.v(TAG, "+++++ TOTAL RECEIVE MESSAGE SIZE IS " + length + " +++++");
- }
- totalReadBytes = read_bytes;
- while ((length > totalReadBytes)||((length == read_bytes)&&((int) byte_array[4] == 0x02)))
- {
- // データについて、もう一回受信が必要な場合...
- if (isDumpReceiveLog)
- {
- Log.v(TAG, "--- RECEIVE AGAIN --- [" + length + "(" + read_bytes + ") " + byte_array[4]+ "] ");
- }
- sleep(delayMs);
- int availableReadBytes = is.available();
- if (availableReadBytes <= 0)
- {
- // 読めるデータ数がない...よみだし終了にする。
- Log.v(TAG, " is.availableReadBytes() : " + availableReadBytes);
- break;
- }
- int read_bytes2 = is.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;
+ 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) {
+ Log.v(TAG, "+++++ TOTAL RECEIVE MESSAGE SIZE IS " + length + " +++++");
}
- else
- {
- // よみだし終了。
- Log.v(TAG, "FINISHED RECEIVE... ");
- break;
- }
- if (callback != null)
- {
- if (callback.isReceiveMulti())
- {
- int 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;
+ totalReadBytes = read_bytes;
+ while ((length > totalReadBytes) || ((length == read_bytes) && ((int) byte_array[4] == 0x02))) {
+ // データについて、もう一回受信が必要な場合...
+ if (isDumpReceiveLog) {
+ Log.v(TAG, "--- RECEIVE AGAIN --- [" + length + "(" + read_bytes + ") " + byte_array[4] + "] ");
+ }
+ sleep(delayMs);
+ int availableReadBytes = is.available();
+ if (availableReadBytes <= 0) {
+ // 読めるデータ数がない...よみだし終了にする。
+ Log.v(TAG, " is.availableReadBytes() : " + availableReadBytes);
+ break;
}
- else
- {
- callback.onReceiveProgress(read_bytes, length, null);
+ int read_bytes2 = is.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()) {
+ int 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 = new byte[1];
}
- receive_body = Arrays.copyOfRange(byte_array, 0, read_bytes);
- }
- else
- {
- receive_body = new byte[1];
}
if (isDumpReceiveLog)
{
// ログに受信メッセージを出力する
Log.v(TAG, "receive_from_camera() : " + read_bytes + " bytes.");
- dump_bytes("RECV[" + receive_body.length + "] ", receive_body);
+ if (receive_body != null)
+ {
+ dump_bytes("RECV[" + receive_body.length + "] ", receive_body);
+ }
}
if (callback != null)
{
}
@Override
+ public int embeddedSequenceNumberIndex()
+ {
+ return (14);
+ }
+
+ @Override
+ public int embeddedSequenceNumberIndex2()
+ {
+ return (8);
+ }
+
+ @Override
+ public int embeddedSequenceNumberIndex3()
+ {
+ return (8);
+ }
+
+ @Override
public byte[] commandBody()
{
return (new byte[12]);
}
@Override
+ public byte[] commandBody3()
+ {
+ return (null);
+ }
+
+ @Override
public IPtpIpCommandCallback responseCallback()
{
return (null);
--- /dev/null
+package net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.specific;
+
+import androidx.annotation.NonNull;
+
+import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandCallback;
+import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.PtpIpCommandBase;
+
+public class CanonRequestInnerDevelopEnd extends PtpIpCommandBase
+{
+ private final IPtpIpCommandCallback callback;
+ private final boolean isDumpLog;
+ private final int id;
+
+ public CanonRequestInnerDevelopEnd(@NonNull IPtpIpCommandCallback callback, boolean isDumpLog, int id)
+ {
+ this.callback = callback;
+ this.isDumpLog = isDumpLog;
+ this.id = id;
+ }
+
+ @Override
+ public IPtpIpCommandCallback responseCallback()
+ {
+ return (callback);
+ }
+
+ @Override
+ public int getId()
+ {
+ return (id);
+ }
+
+ @Override
+ public boolean dumpLog()
+ {
+ return (isDumpLog);
+ }
+
+ @Override
+ public byte[] commandBody()
+ {
+ return (new byte[]{
+ // packet type
+ (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+ // data phase info
+ (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+ // operation code
+ (byte) 0x43, (byte) 0x91,
+
+ // sequence number
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+ // ???
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ });
+ }
+
+ @Override
+ public byte[] commandBody2()
+ {
+ return (new byte[]{
+
+ // packet type
+ (byte) 0x09, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+ // sequence number
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+ // データサイズ
+ (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ });
+ }
+
+ @Override
+ public byte[] commandBody3()
+ {
+ return (new byte[]{
+
+ // packet type
+ (byte) 0x0c, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+ // sequence number
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+ // ????
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ });
+ }
+
+}
--- /dev/null
+package net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.specific;
+
+import androidx.annotation.NonNull;
+
+import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandCallback;
+import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.PtpIpCommandBase;
+
+public class CanonRequestInnerDevelopStart extends PtpIpCommandBase
+{
+ private final IPtpIpCommandCallback callback;
+ private final boolean isDumpLog;
+ private final int id;
+
+ private final byte data0;
+ private final byte data1;
+ private final byte data2;
+ private final byte data3;
+
+ public CanonRequestInnerDevelopStart(@NonNull IPtpIpCommandCallback callback, boolean isDumpLog, int id, int objectId)
+ {
+ this.callback = callback;
+ this.isDumpLog = isDumpLog;
+ this.id = id;
+
+ data0 = ((byte) (0x000000ff & objectId));
+ data1 = ((byte)((0x0000ff00 & objectId) >> 8));
+ data2 = ((byte)((0x00ff0000 & objectId) >> 16));
+ data3 = ((byte)((0xff000000 & objectId) >> 24));
+ }
+
+ @Override
+ public IPtpIpCommandCallback responseCallback()
+ {
+ return (callback);
+ }
+
+ @Override
+ public int getId()
+ {
+ return (id);
+ }
+
+ @Override
+ public boolean dumpLog()
+ {
+ return (isDumpLog);
+ }
+
+ @Override
+ public byte[] commandBody()
+ {
+ return (new byte[]{
+ // packet type
+ (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+ // data phase info
+ (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+ // operation code
+ (byte) 0x41, (byte) 0x91,
+
+ // sequence number
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+ // object id
+ data0, data1, data2, data3,
+
+ // ???
+ (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ });
+ }
+
+ @Override
+ public byte[] commandBody2()
+ {
+ return (new byte[]{
+
+ // packet type
+ (byte) 0x09, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+ // sequence number
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+ // データサイズ
+ (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ });
+ }
+
+ @Override
+ public byte[] commandBody3()
+ {
+ return (new byte[]{
+
+ // packet type
+ (byte) 0x0c, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+ // sequence number
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+ // data
+ (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ });
+ }
+
+}
import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.PtpIpInterfaceProvider;
import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandPublisher;
import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.PtpIpCommandGeneric;
+import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.specific.CanonRequestInnerDevelopStart;
import net.osdn.gokigen.pkremote.preference.IPreferencePropertyAccessor;
/**
{
// Thumbnail と同じ画像を表示する
downloadContentThumbnail(path, callback);
+/*
+ try
+ {
+ int start = 0;
+ if (path.indexOf("/") == 0)
+ {
+ start = 1;
+ }
+ final String indexStr = path.substring(start);
+ PtpIpImageContentInfo content = canonImageObjectReceiver.getContentObject(indexStr);
+ if (content != null)
+ {
+ IPtpIpCommandPublisher publisher = provider.getCommandPublisher();
+ int storageId = content.getStorageId();
+ int objectId = content.getId();
+ // Log.v(TAG, "downloadContentThumbnail() " + indexStr + " [" + objectId + "] (" + storageId + ")");
+
+ // RequestInnerDevelopStart
+ publisher.enqueueCommand(new CanonRequestInnerDevelopStart(new PtpIpScreennailImageReceiver(objectId, publisher, callback), true, objectId, objectId));
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+*/
}
@Override
--- /dev/null
+package net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.playback;
+
+import android.util.Log;
+
+import net.osdn.gokigen.pkremote.camera.interfaces.playback.IDownloadThumbnailImageCallback;
+import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandCallback;
+import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandPublisher;
+import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.PtpIpCommandGeneric;
+import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.specific.CanonRequestInnerDevelopEnd;
+
+
+public class PtpIpScreennailImageReceiver implements IPtpIpCommandCallback
+{
+ private static final String TAG = PtpIpScreennailImageReceiver.class.getSimpleName();
+
+ private final IDownloadThumbnailImageCallback callback;
+ private final IPtpIpCommandPublisher publisher;
+ private final int objectId;
+
+ PtpIpScreennailImageReceiver(int objectId, IPtpIpCommandPublisher publisher, IDownloadThumbnailImageCallback callback)
+ {
+ this.callback = callback;
+ this.publisher = publisher;
+ this.objectId = objectId;
+ }
+
+ @Override
+ public void receivedMessage(int id, byte[] rx_body)
+ {
+ try
+ {
+ if (rx_body != null)
+ {
+ Log.v(TAG, " receivedMessage() : " + id + " " + rx_body.length + " bytes.");
+ }
+ else
+ {
+ Log.v(TAG, " receivedMessage() : " + id + " NULL.");
+ }
+ if (id == objectId)
+ {
+ requestGetPartialObject();
+ }
+ else if (id == objectId + 1)
+ {
+ getPartialObject();
+ }
+ else if (id == objectId + 2)
+ {
+ requestInnerDevelopEnd();
+ }
+ else if (id == objectId + 3)
+ {
+ finishedGetScreeennail();
+ }
+ else if (id == objectId + 4)
+ {
+ Log.v(TAG, " RECEIVED : " + id);
+ }
+ else
+ {
+ Log.v(TAG, " RECEIVED UNKNOWN ID : " + id);
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ {
+ callback.onErrorOccurred(e);
+ }
+ }
+ }
+
+ @Override
+ public void onReceiveProgress(int currentBytes, int totalBytes, byte[] rx_body)
+ {
+ if (rx_body == null)
+ {
+ Log.v(TAG, " " + currentBytes + "/" + totalBytes + " " + " NULL");
+ return;
+ }
+ Log.v(TAG, " " + currentBytes + "/" + totalBytes + " " + rx_body.length + " bytes.");
+ }
+
+ @Override
+ public boolean isReceiveMulti()
+ {
+ return (false);
+ }
+
+ private void requestGetPartialObject()
+ {
+ publisher.enqueueCommand(new PtpIpCommandGeneric(this, false, (objectId + 1), 0x9107, 12, 0x01, 0x00, 0x00200000));
+ }
+
+ private void getPartialObject()
+ {
+ publisher.enqueueCommand(new PtpIpCommandGeneric(this, false, (objectId + 2), 0x9117, 4,0x01));
+ }
+
+ private void requestInnerDevelopEnd()
+ {
+ publisher.enqueueCommand(new CanonRequestInnerDevelopEnd(this, true, (objectId + 3)));
+ }
+
+ private void finishedGetScreeennail()
+ {
+ Log.v(TAG, " SCREENNAIL RECV FINISHED.");
+
+ // リセットコマンドを送ってみる
+ publisher.enqueueCommand(new PtpIpCommandGeneric(this, false, (objectId + 4), 0x902f));
+ }
+
+}
import androidx.annotation.NonNull;
+import net.osdn.gokigen.pkremote.R;
import net.osdn.gokigen.pkremote.camera.interfaces.playback.IDownloadThumbnailImageCallback;
import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandCallback;
{
try
{
+ if (rx_body == null)
+ {
+ Log.v(TAG, " BITMAP IS NONE...");
+ callback.onCompleted(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_broken_image_black_24dp), null);
+ return;
+ }
+
//Log.v(TAG, " RECV THUMBNAIL START : " + id + " [" + rx_body.length + "] ");
//SimpleLogDumper.dump_bytes("[THUMB]", rx_body);
//Log.v(TAG, " RECV THUMBNAIL END : " + id + " [" + rx_body.length + "] ");