1 package net.osdn.gokigen.a01d.camera.ptpip.wrapper.status;
3 import android.app.Activity;
4 import android.util.Log;
6 import androidx.annotation.NonNull;
8 import net.osdn.gokigen.a01d.camera.ICameraStatus;
9 import net.osdn.gokigen.a01d.camera.ICameraStatusWatcher;
10 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommand;
11 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandCallback;
12 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandPublisher;
13 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpMessages;
14 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.messages.specific.InitEventRequest;
15 import net.osdn.gokigen.a01d.liveview.ICameraStatusUpdateNotify;
17 import java.io.BufferedReader;
18 import java.io.DataOutputStream;
19 import java.io.InputStream;
20 import java.net.Socket;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.List;
25 import static net.osdn.gokigen.a01d.camera.utils.SimpleLogDumper.dump_bytes;
27 public class PtpIpStatusChecker implements IPtpIpCommandCallback, ICameraStatusWatcher, ICameraStatus
29 private final String TAG = toString();
31 private static final int BUFFER_SIZE = 1024 * 1024 + 8;
32 private static final int STATUS_MESSAGE_HEADER_SIZE = 14;
34 private final IPtpIpCommandPublisher issuer;
35 private ICameraStatusUpdateNotify notifier = null;
36 private PtpIpStatusHolder statusHolder;
37 private boolean whileFetching = false;
38 private boolean logcat = false;
39 private final String ipAddress;
40 private final int portNumber;
42 private Socket socket = null;
43 private DataOutputStream dos = null;
44 private BufferedReader bufferedReader = null;
45 private int eventConnectionNumber = 0;
47 public PtpIpStatusChecker(@NonNull Activity activity, @NonNull IPtpIpCommandPublisher issuer, @NonNull String ip, int portNumber)
50 this.statusHolder = new PtpIpStatusHolder();
52 this.portNumber = portNumber;
53 Log.v(TAG, "POLLING WAIT : " + sleepMs);
57 public void onReceiveProgress(int currentBytes, int totalBytes, byte[] body)
59 Log.v(TAG, " " + currentBytes + "/" + totalBytes);
63 public boolean isReceiveMulti()
69 public void receivedMessage(int id, byte[] data)
73 logcat("receivedMessage : " + id + ", length: " + data.length);
74 if (id == IPtpIpMessages.SEQ_EVENT_INITIALIZE)
77 Log.v(TAG, " ----- PTP-IP Connection is ESTABLISHED. -----");
80 if (data.length < STATUS_MESSAGE_HEADER_SIZE)
82 Log.v(TAG, "received status length is short. (" + data.length + " bytes.)");
86 int nofStatus = (data[13] * 256) + data[12];
88 int index = STATUS_MESSAGE_HEADER_SIZE;
89 while ((statusCount < nofStatus)&&(index < data.length))
91 int dataId = ((((int)data[index + 1]) & 0xff) * 256) + (((int) data[index]) & 0xff);
92 statusHolder.updateValue(notifier, dataId, data[index + 2], data[index + 3], data[index +4], data[index + 5]);
104 public List<String> getStatusList(String key)
108 if (statusHolder == null)
110 return (new ArrayList<>());
112 return (statusHolder.getAvailableItemList(key));
118 return (new ArrayList<>());
122 public String getStatus(String key)
126 if (statusHolder == null)
130 return (statusHolder.getItemStatus(key));
140 public void setStatus(String key, String value)
146 Log.v(TAG, "setStatus(" + key + ", " + value + ")");
158 public void startStatusWatch(@NonNull ICameraStatusUpdateNotify notifier)
162 Log.v(TAG, "startStatusWatch() already starting.");
167 this.notifier = notifier;
168 whileFetching = true;
171 boolean isConnect = connect();
174 Log.v(TAG, " CONNECT FAIL...(EVENT) : " + ipAddress + " " + portNumber);
176 issueCommand(new InitEventRequest(this, eventConnectionNumber));
185 public void stopStatusWatch()
187 Log.v(TAG, "stoptStatusWatch()");
188 whileFetching = false;
189 this.notifier = null;
192 private void logcat(String message)
200 private boolean connect()
204 socket = new Socket(ipAddress, portNumber);
215 private void disconnect()
233 if (bufferedReader != null)
235 bufferedReader.close();
242 bufferedReader = null;
259 public void setEventConnectionNumber(int connectionNumber)
261 eventConnectionNumber = connectionNumber;
264 private void issueCommand(@NonNull IPtpIpCommand command)
268 //Log.v(TAG, "issueCommand : " + command.getId());
269 byte[] commandBody = command.commandBody();
270 if (commandBody != null)
272 // コマンドボディが入っていた場合には、コマンド送信(入っていない場合は受信待ち)
273 send_to_camera(command.dumpLog(), commandBody);
275 receive_from_camera(command.dumpLog(), command.getId(), command.responseCallback(), command.receiveAgainShortLengthMessage(), command.receiveDelayMs());
284 * カメラにコマンドを送信する(メイン部分)
287 private void send_to_camera(boolean isDumpReceiveLog, byte[] byte_array)
291 dos = new DataOutputStream(socket.getOutputStream()); // ここにいたらいけない?
293 // メッセージボディを加工: 最初に4バイトのレングス長をつける
294 byte[] sendData = new byte[byte_array.length + 4];
296 sendData[0] = (byte) (byte_array.length + 4);
300 System.arraycopy(byte_array,0,sendData,4, byte_array.length);
302 if (isDumpReceiveLog)
305 dump_bytes("SEND[" + sendData.length + "] ", sendData);
320 * カメラからにコマンドの結果を受信する(メイン部分)
323 private void receive_from_camera(boolean isDumpReceiveLog, int id, IPtpIpCommandCallback callback, boolean receiveAgain, int delayMs) {
327 boolean isFirstTime = true;
329 int receive_message_buffer_size = BUFFER_SIZE;
330 byte[] byte_array = new byte[receive_message_buffer_size];
331 InputStream is = socket.getInputStream();
333 int read_bytes = is.read(byte_array, 0, receive_message_buffer_size);
335 if (read_bytes > 4) {
337 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);
338 if (length > receive_message_buffer_size) {
339 Log.v(TAG, "+++++ TOTAL RECEIVE MESSAGE SIZE IS " + length + " +++++");
341 totalReadBytes = read_bytes;
342 while ((length > totalReadBytes) || ((length == read_bytes) && ((int) byte_array[4] == 0x02))) {
343 // データについて、もう一回受信が必要な場合...
344 if (isDumpReceiveLog) {
345 Log.v(TAG, "--- RECEIVE AGAIN --- [" + length + "(" + read_bytes + ") " + byte_array[4] + "] ");
348 int read_bytes2 = is.read(byte_array, read_bytes, receive_message_buffer_size - read_bytes);
349 if (read_bytes2 > 0) {
350 read_bytes = read_bytes + read_bytes2;
351 totalReadBytes = totalReadBytes + read_bytes2;
354 Log.v(TAG, "FINISHED RECEIVE... ");
357 if (callback != null) {
358 if (callback.isReceiveMulti()) {
364 //Log.v(TAG, " FIRST TIME : " + read_bytes + " " + offset);
366 callback.onReceiveProgress(read_bytes - offset, length, Arrays.copyOfRange(byte_array, offset, read_bytes));
369 callback.onReceiveProgress(read_bytes, length, null);
374 receive_body = Arrays.copyOfRange(byte_array, 0, read_bytes);
376 receive_body = new byte[1];
378 if (isDumpReceiveLog) {
380 Log.v(TAG, " receive_from_camera() : " + read_bytes + " bytes.");
381 dump_bytes("RECV[" + receive_body.length + "] ", receive_body);
383 if (callback != null) {
384 if (callback.isReceiveMulti()) {
385 callback.receivedMessage(id, null);
387 callback.receivedMessage(id, receive_body);
388 //callback.receivedMessage(id, Arrays.copyOfRange(receive_body, 0, receive_body.length));
392 } catch (Throwable e) {
397 private void sleep(int delayMs)
401 Thread.sleep(delayMs);