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;
8 import net.osdn.gokigen.pkremote.camera.interfaces.playback.IDownloadContentCallback;
9 import net.osdn.gokigen.pkremote.camera.interfaces.playback.IProgressEvent;
10 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandCallback;
11 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandPublisher;
12 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.PtpIpCommandCanonGetPartialObject;
13 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.PtpIpCommandGeneric;
15 import java.io.ByteArrayOutputStream;
17 public class CanonFullImageReceiver implements IPtpIpCommandCallback
19 private static final String TAG = CanonFullImageReceiver.class.getSimpleName();
21 private final Activity activity;
22 private final IPtpIpCommandPublisher publisher;
23 private IDownloadContentCallback callback = null;
25 private boolean isReceiveMulti = true;
26 private int objectId = 0;
28 private int received_total_bytes = 0;
29 private int received_remain_bytes = 0;
31 private int target_image_size = 0;
32 private boolean receivedFirstData = false;
34 CanonFullImageReceiver(@NonNull Activity activity, @NonNull IPtpIpCommandPublisher publisher)
36 this.activity = activity;
37 this.publisher = publisher;
40 void issueCommand(int objectId, int imageSize, IDownloadContentCallback callback)
42 if (this.objectId != 0)
45 Log.v(TAG, " COMMAND IS ALREADY ISSUED. : " + objectId);
48 this.callback = callback;
49 this.objectId = objectId;
50 this.target_image_size = imageSize;
51 this.isReceiveMulti = true;
52 this.receivedFirstData = false;
54 Log.v(TAG, " getPartialObject (id : " + objectId + ", size:" + imageSize + ")");
55 publisher.enqueueCommand(new PtpIpCommandCanonGetPartialObject(this, (objectId + 1), false, objectId, objectId, 0x00, imageSize, imageSize)); // 0x9107 : GetPartialObject
59 public void receivedMessage(int id, byte[] rx_body)
63 if (id == objectId + 1)
65 getPartialObjectFinished();
67 else if (id == objectId + 2)
69 Log.v(TAG, " TransferComplete() RECEIVED : " + id + " (" + objectId + ") size : " + target_image_size);
71 // end of receive sequence.
72 callback.onCompleted();
73 receivedFirstData = false;
74 received_remain_bytes = 0;
75 received_total_bytes = 0;
76 target_image_size = 0;
83 Log.v(TAG, " RECEIVED UNKNOWN ID : " + id);
90 callback.onErrorOccurred(e);
96 public void onReceiveProgress(final int currentBytes, final int totalBytes, byte[] rx_body)
98 // 受信したデータから、通信のヘッダ部分を削除する
99 byte[] body = cutHeader(rx_body);
100 int length = (body == null) ? 0 : body.length;
101 Log.v(TAG, " onReceiveProgress() " + currentBytes + "/" + totalBytes + " (" + length + " bytes.)");
102 callback.onProgress(body, length, new IProgressEvent() {
104 public float getProgress() {
105 return ((float) currentBytes / (float) target_image_size);
109 public boolean isCancellable() {
114 public void requestCancellation() { }
118 private byte[] cutHeader(byte[] rx_body)
124 int length = rx_body.length;
125 int data_position = 0;
126 ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
127 if (!receivedFirstData)
129 // データを最初に読んだとき。ヘッダ部分を読み飛ばす
130 receivedFirstData = true;
131 data_position = (int) rx_body[0] & (0xff);
132 Log.v(TAG, " FIRST DATA POS. : " + data_position);
133 //SimpleLogDumper.dump_bytes(" [sss]", Arrays.copyOfRange(rx_body, 0, (64)));
135 else if (received_remain_bytes > 0)
137 // データの読み込みが途中だった場合...
138 if (length < received_remain_bytes)
140 // 全部コピーする、足りないバイト数は残す
141 received_remain_bytes = received_remain_bytes - length;
142 received_total_bytes = received_total_bytes + rx_body.length;
147 byteStream.write(rx_body, data_position, received_remain_bytes);
148 data_position = received_remain_bytes;
149 received_remain_bytes = 0;
153 while (data_position <= (length - 12))
155 int body_size = (rx_body[data_position] & 0xff) + ((rx_body[data_position + 1] & 0xff) << 8) +
156 ((rx_body[data_position + 2] & 0xff) << 16) + ((rx_body[data_position + 3] & 0xff) << 24);
159 Log.v(TAG, " --- BODY SIZE IS SMALL : " + data_position + " (" + body_size + ") [" + received_remain_bytes + "] " + rx_body.length + " (" + target_image_size + ")");
160 //int startpos = (data_position > 48) ? (data_position - 48) : 0;
161 //SimpleLogDumper.dump_bytes(" [xxx]", Arrays.copyOfRange(rx_body, startpos, (data_position + 48)));
165 // 受信データ(のヘッダ部分)をダンプする
166 //Log.v(TAG, " RX DATA : " + data_position + " (" + body_size + ") [" + received_remain_bytes + "] (" + received_total_bytes + ")");
167 //SimpleLogDumper.dump_bytes(" [zzz] " + data_position + ": ", Arrays.copyOfRange(rx_body, data_position, (data_position + 48)));
169 if ((data_position + body_size) > length)
171 // データがすべてバッファ内になかったときは、バッファすべてコピーして残ったサイズを記憶しておく。
172 int copysize = (length - ((data_position + 12)));
173 byteStream.write(rx_body, (data_position + 12), copysize);
174 received_remain_bytes = body_size - copysize - 12; // マイナス12は、ヘッダ分
175 received_total_bytes = received_total_bytes + copysize;
176 //Log.v(TAG, " ----- copy : " + (data_position + 12) + " " + copysize + " remain : " + received_remain_bytes + " body size : " + body_size);
181 byteStream.write(rx_body, (data_position + 12), (body_size - 12));
182 data_position = data_position + body_size;
183 received_total_bytes = received_total_bytes + 12;
184 //Log.v(TAG, " --- COPY : " + (data_position + 12) + " " + (body_size - 12) + " remain : " + received_remain_bytes);
189 Log.v(TAG, " pos : " + data_position + " size : " + body_size + " length : " + length);
193 return (byteStream.toByteArray());
197 public boolean isReceiveMulti()
199 return (isReceiveMulti);
202 private void getPartialObjectFinished()
206 // すべてのデータを受信した後に...終わりを送信する
207 Log.v(TAG, " getPartialObjectFinished(), id : " + objectId + " (size : " + target_image_size + ")");
208 isReceiveMulti = false;
209 publisher.enqueueCommand(new PtpIpCommandGeneric(this, (objectId + 2), false, objectId, 0x9117, 4,0x01)); // 0x9117 : TransferComplete