From 0a88c159684335bf67fb34844d443ef0beb3434d Mon Sep 17 00:00:00 2001 From: MRSa Date: Mon, 18 Nov 2019 23:57:20 +0900 Subject: [PATCH] =?utf8?q?Nikon=E3=81=AE=E3=82=AA=E3=83=96=E3=82=B8?= =?utf8?q?=E3=82=A7=E3=82=AF=E3=83=88ID=E5=8F=96=E5=BE=97=E3=82=B7?= =?utf8?q?=E3=83=BC=E3=82=B1=E3=83=B3=E3=82=B9=E3=81=BE=E3=81=A7=E5=AE=9F?= =?utf8?q?=E8=A3=85=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../wrapper/playback/NikonImageObjectReceiver.java | 83 ++++++++++- .../playback/NikonStorageContentHolder.java | 164 +++++++++++++++++++++ .../ptpip/wrapper/command/IPtpIpMessages.java | 5 + 3 files changed, 244 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/playback/NikonStorageContentHolder.java diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/playback/NikonImageObjectReceiver.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/playback/NikonImageObjectReceiver.java index 48a6f91..0c89b2a 100644 --- a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/playback/NikonImageObjectReceiver.java +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/playback/NikonImageObjectReceiver.java @@ -1,6 +1,7 @@ package net.osdn.gokigen.pkremote.camera.vendor.nikon.wrapper.playback; import android.util.Log; +import android.util.SparseArray; import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraConnection; import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContent; @@ -21,7 +22,7 @@ import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtp import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_STORAGE_INFO; import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_OBJECT_INFO_EX; -public class NikonImageObjectReceiver implements IPtpIpCommandCallback +public class NikonImageObjectReceiver implements IPtpIpCommandCallback, NikonStorageContentHolder.ImageObjectReceivedCallback { private final String TAG = toString(); private final NikonInterfaceProvider provider; @@ -31,7 +32,7 @@ public class NikonImageObjectReceiver implements IPtpIpCommandCallback private ICameraContentListCallback callback = null; private int subDirectoriesCount = -1; private int receivedSubDirectoriesCount = -1; - private List storageIdList; + private SparseArray storageIdList; NikonImageObjectReceiver(NikonInterfaceProvider provider) { @@ -39,15 +40,38 @@ public class NikonImageObjectReceiver implements IPtpIpCommandCallback this.imageObjectList = new ArrayList<>(); this.ptpIpImageObjectList = new ArrayList<>(); - this.storageIdList = new ArrayList<>(); + this.storageIdList = new SparseArray<>(); } private void parseStorageId(byte[] rx_body) { - storageIdList.clear(); - SimpleLogDumper.dump_bytes(" [GetStorageIds] ", rx_body); - } + try + { + storageIdList.clear(); + SimpleLogDumper.dump_bytes(" [GetStorageIds] ", rx_body); + int checkBytes = rx_body[0]; + //int dataLength = rx_body[checkBytes]; + + int nofStorages = rx_body[checkBytes + 12]; + int readPosition = checkBytes + 12 + 4; + Log.v(TAG, " NOF STORAGES : " + nofStorages); + for (int index = 0; index < nofStorages; index++) + { + int storageId = ((int) rx_body[readPosition]) + + ((int) rx_body[readPosition + 1] << 8) + + ((int) rx_body[readPosition + 2] << 16) + + ((int) rx_body[readPosition + 3] << 24); + storageIdList.append(storageId, new NikonStorageContentHolder(provider, storageId, this)); + readPosition = readPosition + 4; + } + Log.v(TAG, " NOF STORAGE IDs : " + storageIdList.size() + " "); + } + catch (Exception e) + { + e.printStackTrace(); + } + } @Override public void receivedMessage(int id, byte[] rx_body) @@ -59,9 +83,14 @@ public class NikonImageObjectReceiver implements IPtpIpCommandCallback switch (id) { case GET_STORAGE_ID: - // TODO: ストレージのIDを 0x00100010 で固定にしている。複数スロットある場合もあるので、このタイミングでちゃんと応答を parse してループさせる必要がある + // ストレージID一覧を解析する parseStorageId(rx_body); - publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_STORAGE_INFO, isDumpLog, 0, 0x9102, 4, 0x00010001)); + for(int index = 0; index < storageIdList.size(); index++) + { + int key = storageIdList.keyAt(index); + NikonStorageContentHolder contentHolder = storageIdList.get(key); + contentHolder.getContents(); + } subDirectoriesCount = -1; // ここから画像取得シーケンスに入るので、、、 break; @@ -122,6 +151,11 @@ public class NikonImageObjectReceiver implements IPtpIpCommandCallback break; default: +/* + if ((id & 0xff) == GET_STORAGE_HANDLE1) + { + } +*/ break; } } @@ -225,4 +259,37 @@ public class NikonImageObjectReceiver implements IPtpIpCommandCallback e.printStackTrace(); } } + + @Override + public void onReceived(int storageId) + { + Log.v(TAG, " ----- STORAGE ID : " + storageId + " -----"); + + List objectList = new ArrayList<>(); + for(int index = 0; index < storageIdList.size(); index++) + { + int key = storageIdList.keyAt(index); + NikonStorageContentHolder contentHolder = storageIdList.get(key); + boolean receivedAll = contentHolder.isObjectIdReceived(); + if (!receivedAll) + { + return; + } + objectList.addAll(contentHolder.getObjectIdList()); + } + // すべてのStorageで Object Id の取得が終わった! + Log.v(TAG," ----- RECEIVED ALL IMAGE OBJECT ID count : " + objectList.size() + "-----"); + for (int id : objectList) + { + Log.v(TAG, " OBJECT ID : " + id); + } + Log.v(TAG, " --------------------"); + } + + @Override + public void onError(Exception e) + { + Log.v(TAG, "onError : " + e.getLocalizedMessage()); + + } } diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/playback/NikonStorageContentHolder.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/playback/NikonStorageContentHolder.java new file mode 100644 index 0000000..6c686c3 --- /dev/null +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/playback/NikonStorageContentHolder.java @@ -0,0 +1,164 @@ +package net.osdn.gokigen.pkremote.camera.vendor.nikon.wrapper.playback; + +import android.util.Log; + +import androidx.annotation.NonNull; + +import net.osdn.gokigen.pkremote.camera.vendor.nikon.wrapper.NikonInterfaceProvider; +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 java.util.ArrayList; +import java.util.List; + +import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_STORAGE_HANDLE1; +import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_STORAGE_HANDLE2; +import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_STORAGE_HANDLE3; + +public class NikonStorageContentHolder implements IPtpIpCommandCallback +{ + private final String TAG = toString(); + private final int storageId; + private final NikonInterfaceProvider provider; + private final ImageObjectReceivedCallback callback; + private boolean isDumpLog = true; + private List objectList; + private int subDirectoryCount = 0; + private int receivedDirectoryCount = 0; + private boolean isObjectReceived = false; + + NikonStorageContentHolder(@NonNull NikonInterfaceProvider provider, int storageId, @NonNull ImageObjectReceivedCallback callback) + { + this.provider = provider; + this.storageId = storageId; + this.callback = callback; + this.objectList = new ArrayList<>(); + } + + void getContents() + { + try + { + isObjectReceived = false; + IPtpIpCommandPublisher publisher = provider.getCommandPublisher(); + publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_STORAGE_HANDLE1, isDumpLog, 0, 0x1007, 12, storageId, 0x00003001, 0xffffffff)); + objectList.clear(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + private List parseObjects(byte[] rx_body) + { + List directoryList = new ArrayList<>(); + try + { + int checkBytes = rx_body[0]; + int readPosition = checkBytes + 12; + int nofSubDirectories = ((int) rx_body[readPosition]) + + ((int) rx_body[readPosition + 1] << 8) + + ((int) rx_body[readPosition + 2] << 16) + + ((int) rx_body[readPosition + 3] << 24); + for (int index = 0; index < nofSubDirectories; index++) + { + readPosition = readPosition + 4; + int directoryId = ((int) rx_body[readPosition]) + + ((int) rx_body[readPosition + 1] << 8) + + ((int) rx_body[readPosition + 2] << 16) + + ((int) rx_body[readPosition + 3] << 24); + directoryList.add(directoryId); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + Log.v(TAG, " Received Objects : " + directoryList.size() + " "); + return (directoryList); + } + + + @Override + public void receivedMessage(int id, byte[] rx_body) + { + try + { + IPtpIpCommandPublisher publisher = provider.getCommandPublisher(); + if (id == GET_STORAGE_HANDLE1) + { + // トップディレクトリを取得した + List directoriesList = parseObjects(rx_body); + for (int subDirectory : directoriesList) + { + Log.v(TAG, " STORAGE ID : " + storageId + " DIRECTORY ID : " + subDirectory); + publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_STORAGE_HANDLE2, isDumpLog, 0, 0x1007, 12, storageId, 0x00000000, subDirectory)); // + } + return; + } + if (id == GET_STORAGE_HANDLE2) + { + // サブディレクトリの一覧を受信した + subDirectoryCount = 0; + receivedDirectoryCount = 0; + List subDirectoriesList = parseObjects(rx_body); + for (int subDirectory : subDirectoriesList) + { + Log.v(TAG, " STORAGE ID : " + storageId + " DIRECTORY ID : " + subDirectory); + publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_STORAGE_HANDLE3, isDumpLog, 0, 0x1007, 12, storageId, 0x00000000, subDirectory)); // + subDirectoryCount++; + } + return; + } + if (id == GET_STORAGE_HANDLE3) + { + // OBJECT IDリストを受信した! + List objectsList = parseObjects(rx_body); + objectList.addAll(objectsList); + receivedDirectoryCount++; + if (subDirectoryCount <= receivedDirectoryCount) + { + // 送信要求したメッセージの応答をすべて受信した! + isObjectReceived = true; + callback.onReceived(storageId); + } + } + } + catch (Exception e) + { + e.printStackTrace(); + callback.onError(e); + } + } + + List getObjectIdList() + { + return (objectList); + } + + boolean isObjectIdReceived() + { + return (isObjectReceived); + } + + @Override + public void onReceiveProgress(int currentBytes, int totalBytes, byte[] rx_body) + { + + } + + @Override + public boolean isReceiveMulti() + { + return (false); + } + + interface ImageObjectReceivedCallback + { + void onReceived(int storageId); + void onError(Exception e); + } + +} diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/command/IPtpIpMessages.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/command/IPtpIpMessages.java index d92a359..bde8108 100644 --- a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/command/IPtpIpMessages.java +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/command/IPtpIpMessages.java @@ -19,6 +19,11 @@ public interface IPtpIpMessages int GET_OBJECT_INFO_EX_2 = 104; int GET_OBJECT_INFO_EX_3 = 105; + int GET_STORAGE_HANDLE1 = 110; + int GET_STORAGE_HANDLE2 = 111; + int GET_STORAGE_HANDLE3 = 112; + + /* int SEQ_REGISTRATION = 1; int SEQ_START = 2; -- 2.11.0