1 package net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.playback;
3 import android.app.Activity;
4 import android.util.Log;
6 import androidx.annotation.NonNull;
7 import androidx.annotation.Nullable;
9 import net.osdn.gokigen.pkremote.camera.interfaces.playback.IDownloadContentCallback;
10 import net.osdn.gokigen.pkremote.camera.interfaces.playback.IProgressEvent;
11 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandCallback;
12 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandPublisher;
13 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.PtpIpCommandCanonGetPartialObject;
14 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.PtpIpCommandGeneric;
15 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.specific.CanonRequestInnerDevelopEnd;
16 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.specific.CanonRequestInnerDevelopStart;
18 import java.io.ByteArrayOutputStream;
21 public class PtpIpSmallImageReceiver implements IPtpIpCommandCallback
23 private static final String TAG = PtpIpSmallImageReceiver.class.getSimpleName();
25 private final Activity activity;
26 private final IPtpIpCommandPublisher publisher;
27 private final IPtpIpCommandCallback mine;
28 private IDownloadContentCallback callback = null;
29 private int objectId = 0;
30 private boolean isReceiveMulti = false;
31 private boolean receivedFirstData = false;
33 private int received_total_bytes = 0;
34 private int received_remain_bytes = 0;
36 PtpIpSmallImageReceiver(@NonNull Activity activity, @NonNull IPtpIpCommandPublisher publisher)
38 this.activity = activity;
39 this.publisher = publisher;
43 void issueCommand(final int objectId, IDownloadContentCallback callback)
45 if (this.objectId != 0)
48 Log.v(TAG, " COMMAND IS ALREADY ISSUED. : " + objectId);
51 this.callback = callback;
52 this.objectId = objectId;
53 publisher.enqueueCommand(new CanonRequestInnerDevelopStart(new IPtpIpCommandCallback() {
55 public void receivedMessage(int id, byte[] rx_body) {
56 Log.v(TAG, " getRequestStatusEvent : " + objectId + " " + ((rx_body != null) ? rx_body.length : 0));
57 publisher.enqueueCommand(new PtpIpCommandGeneric(mine, (objectId + 5), false, objectId, 0x9116));
61 public void onReceiveProgress(int currentBytes, int totalBytes, byte[] rx_body) {
65 public boolean isReceiveMulti() {
68 }, objectId, false, objectId, objectId)); // 0x9141 : RequestInnerDevelopStart
72 public void receivedMessage(int id, byte[] rx_body)
76 if (id == objectId + 1)
78 sendTransferComplete(rx_body);
80 else if (id == objectId + 2)
82 Log.v(TAG, " requestInnerDevelopEnd() : " + objectId);
83 publisher.enqueueCommand(new CanonRequestInnerDevelopEnd(this, (objectId + 3), false, objectId)); // 0x9143 : RequestInnerDevelopEnd
85 else if (id == objectId + 3)
87 //Log.v(TAG, " --- COMMAND RESET : " + objectId + " --- ");
90 publisher.enqueueCommand(new PtpIpCommandGeneric(this, (objectId + 4), false, objectId, 0x902f));
92 else if (id == objectId + 4)
95 Log.v(TAG, " ----- SMALL IMAGE RECEIVE SEQUENCE FINISHED : " + objectId);
96 callback.onCompleted();
99 this.received_total_bytes = 0;
100 this.received_remain_bytes = 0;
101 this.receivedFirstData = false;
104 else if (id == objectId + 5)
106 requestGetPartialObject(rx_body);
110 Log.v(TAG, " RECEIVED UNKNOWN ID : " + id);
117 callback.onErrorOccurred(e);
123 public void onReceiveProgress(final int currentBytes, final int totalBytes, byte[] rx_body)
125 byte[] body = cutHeader(rx_body);
126 int length = (body == null) ? 0 : body.length;
127 Log.v(TAG, " onReceiveProgress() " + currentBytes + "/" + totalBytes + " (" + length + " bytes.)");
128 callback.onProgress(body, length, new IProgressEvent() {
130 public float getProgress() {
131 return ((float) currentBytes / (float) totalBytes);
135 public boolean isCancellable() {
140 public void requestCancellation() {
146 private byte[] cutHeader(byte[] rx_body)
152 int length = rx_body.length;
153 int data_position = 0;
154 ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
155 if (!receivedFirstData)
158 receivedFirstData = true;
160 // データを最初に読んだとき。ヘッダ部分を読み飛ばす
161 data_position = (int) rx_body[0] & (0xff);
163 else if (received_remain_bytes > 0)
165 //Log.v(TAG, " >>> [ remain_bytes : " + received_remain_bytes + "] ( length : " + length + ") " + data_position);
166 //SimpleLogDumper.dump_bytes("[zzz]", Arrays.copyOfRange(rx_body, data_position, (data_position + 160)));
168 // データの読み込みが途中だった場合...
169 if (length < received_remain_bytes)
171 // 全部コピーする、足りないバイト数は残す
172 received_remain_bytes = received_remain_bytes - length;
173 received_total_bytes = received_total_bytes + rx_body.length;
178 byteStream.write(rx_body, data_position, received_remain_bytes);
179 data_position = received_remain_bytes;
180 received_remain_bytes = 0;
184 while (data_position <= (length - 12))
186 int body_size = (rx_body[data_position] & 0xff) + ((rx_body[data_position + 1] & 0xff) << 8) +
187 ((rx_body[data_position + 2] & 0xff) << 16) + ((rx_body[data_position + 3] & 0xff) << 24);
190 Log.v(TAG, " BODY SIZE IS SMALL : " + data_position + " (" + body_size + ") [" + received_remain_bytes + "] " + rx_body.length + " ");
191 //int startpos = (data_position > 48) ? (data_position - 48) : 0;
192 //SimpleLogDumper.dump_bytes("[xxx]", Arrays.copyOfRange(rx_body, startpos, (data_position + 48)));
196 // Log.v(TAG, " RX DATA : " + data_position + " (" + body_size + ") [" + received_remain_bytes + "] (" + received_total_bytes + ")");
197 //SimpleLogDumper.dump_bytes("[yyy] " + data_position + ": ", Arrays.copyOfRange(rx_body, data_position, (data_position + 64)));
198 if ((data_position + body_size) > length)
200 // データがすべてバッファ内になかったときは、バッファすべてコピーして残ったサイズを記憶しておく。
201 int copysize = (length - ((data_position + 12)));
202 byteStream.write(rx_body, (data_position + 12), copysize);
203 received_remain_bytes = body_size - copysize - 12; // マイナス12は、ヘッダ分
204 received_total_bytes = received_total_bytes + copysize;
205 // Log.v(TAG, " --- copy : " + (data_position + 12) + " " + copysize + " remain : " + received_remain_bytes + " body size : " + body_size);
210 byteStream.write(rx_body, (data_position + 12), (body_size - 12));
211 data_position = data_position + body_size;
212 received_total_bytes = received_total_bytes + 12;
213 //Log.v(TAG, " --- COPY : " + (data_position + 12) + " " + (body_size - 12) + " remain : " + received_remain_bytes);
217 Log.v(TAG, " pos : " + data_position + " size : " + body_size + " length : " + length);
221 return (byteStream.toByteArray());
225 public boolean isReceiveMulti()
227 return (isReceiveMulti);
230 private void requestGetPartialObject(@Nullable byte[] rx_body)
232 Log.v(TAG, " requestGetPartialObject() : " + objectId);
233 isReceiveMulti = true;
234 receivedFirstData = false;
236 // 0x9107 : GetPartialObject (元は 0x00020000)
238 if ((rx_body != null)&&(rx_body.length > 52))
241 pictureLength = (rx_body[dataIndex] & 0xff);
242 pictureLength = pictureLength + ((rx_body[dataIndex + 1] & 0xff) << 8);
243 pictureLength = pictureLength + ((rx_body[dataIndex + 2] & 0xff) << 16);
244 pictureLength = pictureLength + ((rx_body[dataIndex + 3] & 0xff) << 24);
248 pictureLength = 0x020000;
250 publisher.enqueueCommand(new PtpIpCommandCanonGetPartialObject(this, (objectId + 1), false, objectId, 0x01, 0x00, pictureLength, pictureLength));
253 private void sendTransferComplete(byte[] rx_body)
255 Log.v(TAG, " sendTransferComplete(), id : " + objectId + " size: " + ((rx_body != null) ? rx_body.length : 0));
256 publisher.enqueueCommand(new PtpIpCommandGeneric(this, (objectId + 2), false, objectId, 0x9117, 4,0x01)); // 0x9117 : TransferComplete
257 isReceiveMulti = false;