package net.osdn.gokigen.pkremote.camera.utils;
+import android.app.Activity;
+import android.os.Environment;
import android.util.Log;
+import androidx.annotation.NonNull;
+
+import net.osdn.gokigen.pkremote.R;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Locale;
+
public class SimpleLogDumper
{
private static final String TAG = SimpleLogDumper.class.getSimpleName();
System.gc();
}
+
+ public static void binaryOutputToFile(@NonNull Activity activity, String fileNamePrefix, byte[] rx_body)
+ {
+ try
+ {
+ Calendar calendar = Calendar.getInstance();
+ String extendName = new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.getDefault()).format(calendar.getTime());
+ final String directoryPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath() + "/" + activity.getString(R.string.app_name2) + "/";
+ String outputFileName = fileNamePrefix + "_" + extendName + ".bin";
+ String filepath = new File(directoryPath.toLowerCase(), outputFileName.toLowerCase()).getPath();
+ FileOutputStream outputStream = new FileOutputStream(filepath);
+ outputStream.write(rx_body, 0, rx_body.length);
+ outputStream.flush();
+ outputStream.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
}
private static final String TAG = PtpIpCommandPublisher.class.getSimpleName();
private static final int SEQUENCE_START_NUMBER = 1;
- private static final int BUFFER_SIZE = 1024 * 1024 + 8;
+ private static final int BUFFER_SIZE = 1024 * 1024 * 24 + 8;
private static final int COMMAND_SEND_RECEIVE_DURATION_MS = 50;
private static final int COMMAND_SEND_RECEIVE_DURATION_MAX = 1000;
private static final int COMMAND_POLL_QUEUE_MS = 150;
{
try
{
- //Log.v(TAG, "issueCommand : " + command.getId());
- byte[] commandBody = command.commandBody();
- if (commandBody != null)
+ boolean retry_over = true;
+ while (retry_over)
{
- // コマンドボディが入っていた場合には、コマンド送信(入っていない場合は受信待ち)
- send_to_camera(command.dumpLog(), commandBody, command.useSequenceNumber(), command.embeddedSequenceNumberIndex());
- byte[] commandBody2 = command.commandBody2();
- if (commandBody2 != null)
+ //Log.v(TAG, "issueCommand : " + command.getId());
+ byte[] commandBody = command.commandBody();
+ if (commandBody != null)
{
- // コマンドボディの2つめが入っていた場合には、コマンドを連続送信する
- 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());
+ // コマンドボディが入っていた場合には、コマンド送信(入っていない場合は受信待ち)
+ 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(), command.embeddedSequenceNumberIndex2());
+ }
+ byte[] commandBody3 = command.commandBody3();
+ if (commandBody3 != null)
+ {
+ // コマンドボディの3つめが入っていた場合には、コマンドを連続送信する
+ send_to_camera(command.dumpLog(), commandBody3, command.useSequenceNumber(), command.embeddedSequenceNumberIndex3());
+ }
+ if (command.isIncrementSeqNumber())
+ {
+ // シーケンス番号を更新する
+ sequenceNumber++;
+ }
}
- if (command.isIncrementSeqNumber())
+ retry_over = receive_from_camera(command);
+ if ((retry_over)&&(commandBody != null))
{
- // シーケンス番号を更新する
- sequenceNumber++;
+ // 再送信...のために、シーケンス番号を戻す...
+ sequenceNumber--;
}
}
- int delayMs = command.receiveDelayMs();
- if ((delayMs < 0)||(delayMs > COMMAND_SEND_RECEIVE_DURATION_MAX))
- {
- delayMs = COMMAND_SEND_RECEIVE_DURATION_MS;
- }
- receive_from_camera(command.dumpLog(), command.getId(), command.responseCallback(), command.receiveAgainShortLengthMessage(), delayMs);
}
catch (Exception e)
{
* カメラからにコマンドの結果を受信する(メイン部分)
*
*/
- private void receive_from_camera(boolean isDumpReceiveLog, int id, IPtpIpCommandCallback callback, boolean receiveAgain, int delayMs)
+ private void receive_from_camera_old(boolean isDumpReceiveLog, int id, IPtpIpCommandCallback callback, boolean receiveAgain, int delayMs)
{
try
{
}
}
+ /**
+ * カメラからにコマンドの結果を受信する(メイン部分)
+ *
+ */
+ private boolean receive_from_camera(@NonNull IPtpIpCommand command)
+ {
+ boolean isDumpReceiveLog = command.dumpLog();
+ int id = command.getId();
+ IPtpIpCommandCallback callback = command.responseCallback();
+ int delayMs = command.receiveDelayMs();
+ if ((delayMs < 0)||(delayMs > COMMAND_SEND_RECEIVE_DURATION_MAX))
+ {
+ delayMs = COMMAND_SEND_RECEIVE_DURATION_MS;
+ }
+
+ try
+ {
+ boolean isFirstTime = true;
+ int receive_message_buffer_size = BUFFER_SIZE;
+ byte[] byte_array = new byte[receive_message_buffer_size];
+ InputStream is = socket.getInputStream();
+ if (is == null)
+ {
+ Log.v(TAG, " InputStream is NULL... RECEIVE ABORTED");
+ return (false);
+ }
+
+ // 初回データが受信バッファにデータが溜まるまで待つ...
+ int read_bytes = waitForReceive(is, delayMs);
+ if (read_bytes < 0)
+ {
+ // リトライオーバー...
+ Log.v(TAG, " RECEIVE : RETRY OVER...");
+ return (true);
+ }
+
+ int position = 0;
+ int message_length = receive_message_buffer_size;
+ while (read_bytes > 0)
+ {
+ read_bytes = is.read(byte_array, position, receive_message_buffer_size - position);
+ if ((read_bytes <= 0)||(receive_message_buffer_size <= read_bytes + position))
+ {
+ Log.v(TAG, " RECEIVED MESSAGE FINISHED (" + position + ")");
+ break;
+ }
+ if (position == 0)
+ {
+ int lenlen = 0;
+ int len = ((((int) byte_array[3]) & 0xff) << 24) + ((((int) byte_array[2]) & 0xff) << 16) + ((((int) byte_array[1]) & 0xff) << 8) + (((int) byte_array[0]) & 0xff);
+ if ((read_bytes > 20)&&((int) byte_array[5] == 9))
+ {
+ lenlen = ((((int) byte_array[15]) & 0xff) << 24) + ((((int) byte_array[14]) & 0xff) << 16) + ((((int) byte_array[13]) & 0xff) << 8) + (((int) byte_array[12]) & 0xff);
+ }
+ Log.v(TAG, " RECEIVED MESSAGE LENGTH (" + len + ") [" + lenlen + "]. : " + read_bytes);
+ }
+ position = position + read_bytes;
+ //Log.v(TAG, " RECEIVED POSITION ((" + position + "))");
+
+ if (callback != null)
+ {
+ if (callback.isReceiveMulti())
+ {
+ int offset = 0;
+ if (isFirstTime)
+ {
+ // 先頭のヘッダ部分をカットして送る
+ offset = 12;
+ isFirstTime = false;
+ message_length = ((((int) byte_array[3]) & 0xff) << 24) + ((((int) byte_array[2]) & 0xff) << 16) + ((((int) byte_array[1]) & 0xff) << 8) + (((int) byte_array[0]) & 0xff);
+ //Log.v(TAG, " FIRST TIME : " + read_bytes + " " + offset);
+ }
+ callback.onReceiveProgress(read_bytes - offset, message_length, Arrays.copyOfRange(byte_array, offset, read_bytes));
+ }
+ else
+ {
+ callback.onReceiveProgress(read_bytes, message_length, null);
+ }
+ }
+
+ sleep(delayMs);
+ read_bytes = is.available();
+ if (read_bytes <= 0)
+ {
+ //Log.v(TAG, " RECEIVED MESSAGE FINISHED : " + position + " bytes.");
+ }
+ }
+ byte[] receive_body = Arrays.copyOfRange(byte_array, 0, (position < 1) ? 1 : position);
+ Log.v(TAG, " RECEIVED : [" + position + "]");
+ receivedMessage(isDumpReceiveLog, id, receive_body, callback);
+ }
+ catch (Throwable e)
+ {
+ e.printStackTrace();
+ }
+ return (false);
+ }
+
+ private int waitForReceive(InputStream is, int delayMs)
+ {
+ int retry_count = 30;
+ int read_bytes = 0;
+ try
+ {
+ while (read_bytes <= 0)
+ {
+ sleep(delayMs);
+ read_bytes = is.available();
+ if (read_bytes == 0)
+ {
+ Log.v(TAG, " is.available() WAIT... ");
+ retry_count--;
+ if (retry_count < 0)
+ {
+ return (-1);
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ return (read_bytes);
+ }
+
+ private void receivedMessage(boolean isDumpReceiveLog, int id, byte[] body, IPtpIpCommandCallback callback)
+ {
+ if (isDumpReceiveLog)
+ {
+ // ログに受信メッセージを出力する
+ Log.v(TAG, "receive_from_camera() : " + body.length + " bytes.");
+ dump_bytes("RECV[" + body.length + "] ", body);
+ }
+ if (callback != null)
+ {
+ if (callback.isReceiveMulti())
+ {
+ callback.receivedMessage(id, null);
+ }
+ else
+ {
+ callback.receivedMessage(id, body);
+ //callback.receivedMessage(id, Arrays.copyOfRange(receive_body, 0, receive_body.length));
+ }
+ }
+ }
}
+
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.CanonRequestInnerDevelopEnd;
import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.specific.CanonRequestInnerDevelopStart;
import net.osdn.gokigen.pkremote.preference.IPreferencePropertyAccessor;
public void downloadContentScreennail(String path, IDownloadThumbnailImageCallback callback)
{
// Thumbnail と同じ画像を表示する
- downloadContentThumbnail(path, callback);
-/*
+ //downloadContentThumbnail(path, callback);
+/**/
try
{
int start = 0;
int objectId = content.getId();
// Log.v(TAG, "downloadContentThumbnail() " + indexStr + " [" + objectId + "] (" + storageId + ")");
- // RequestInnerDevelopStart
- publisher.enqueueCommand(new CanonRequestInnerDevelopStart(new PtpIpScreennailImageReceiver(objectId, publisher, callback), true, objectId, objectId));
+ // 一連の画像取得シーケンス(RequestInnerDevelopStart, GetPartialObject, TransferComplete, RequestInnerDevelopEnd )を送信キューに積み込む
+ PtpIpScreennailImageReceiver receiver = new PtpIpScreennailImageReceiver(activity, objectId, publisher, callback);
+ publisher.enqueueCommand(new CanonRequestInnerDevelopStart(receiver, true, objectId, objectId)); // 0x9141 : RequestInnerDevelopStart
+ publisher.enqueueCommand(new PtpIpCommandGeneric(receiver, true, (objectId + 1), 0x9107, 12, 0x01, 0x00, 0x00200000)); // 0x9107 : GetPartialObject (元は 0x00020000)
+ publisher.enqueueCommand(new PtpIpCommandGeneric(receiver, true, (objectId + 2), 0x9117, 4,0x01)); // 0x9117 : TransferComplete
+ publisher.enqueueCommand(new CanonRequestInnerDevelopEnd(receiver, true, (objectId + 3))); // 0x9143 : RequestInnerDevelopEnd
}
}
catch (Exception e)
{
e.printStackTrace();
}
-*/
+/**/
}
@Override
package net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.playback;
+import android.app.Activity;
+import android.graphics.BitmapFactory;
+import android.os.Environment;
import android.util.Log;
+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;
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;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Locale;
+
+import static net.osdn.gokigen.pkremote.camera.utils.SimpleLogDumper.binaryOutputToFile;
+
public class PtpIpScreennailImageReceiver implements IPtpIpCommandCallback
{
private static final String TAG = PtpIpScreennailImageReceiver.class.getSimpleName();
-
+ private final Activity activity;
private final IDownloadThumbnailImageCallback callback;
private final IPtpIpCommandPublisher publisher;
private final int objectId;
- PtpIpScreennailImageReceiver(int objectId, IPtpIpCommandPublisher publisher, IDownloadThumbnailImageCallback callback)
+ PtpIpScreennailImageReceiver(Activity activity, int objectId, IPtpIpCommandPublisher publisher, IDownloadThumbnailImageCallback callback)
{
+ this.activity = activity;
this.callback = callback;
this.publisher = publisher;
this.objectId = objectId;
+ Log.v(TAG, "PtpIpScreennailImageReceiver CREATED : " + objectId);
+
}
@Override
}
else if (id == objectId + 1)
{
- getPartialObject();
+ getPartialObject(rx_body);
}
else if (id == objectId + 2)
{
@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.");
+ int length = (rx_body == null) ? 0 : rx_body.length;
+ Log.v(TAG, " onReceiveProgress() " + currentBytes + "/" + totalBytes + " (" + length + " bytes.)");
}
@Override
private void requestGetPartialObject()
{
- publisher.enqueueCommand(new PtpIpCommandGeneric(this, false, (objectId + 1), 0x9107, 12, 0x01, 0x00, 0x00200000));
+ Log.v(TAG, " requestGetPartialObject() : " + objectId);
+ //publisher.enqueueCommand(new PtpIpCommandGeneric(this, false, (objectId + 1), 0x9107, 12, 0x01, 0x00, 0x00200000));
}
- private void getPartialObject()
+ private void getPartialObject(byte[] rx_body)
{
- publisher.enqueueCommand(new PtpIpCommandGeneric(this, false, (objectId + 2), 0x9117, 4,0x01));
+ Log.v(TAG, " getPartialObject(), id : " + objectId + " size: " + rx_body.length);
+ callback.onCompleted(BitmapFactory.decodeStream(new ByteArrayInputStream(rx_body)), null);
+ //publisher.enqueueCommand(new PtpIpCommandGeneric(this, false, (objectId + 2), 0x9117, 4,0x01));
+
+ // ファイルにバイナリデータをダンプする
+ //binaryOutputToFile(activity, objectId + "_", rx_body);
}
private void requestInnerDevelopEnd()
{
- publisher.enqueueCommand(new CanonRequestInnerDevelopEnd(this, true, (objectId + 3)));
+ Log.v(TAG, " requestInnerDevelopEnd() : " + objectId);
+ //publisher.enqueueCommand(new CanonRequestInnerDevelopEnd(this, true, (objectId + 3)));
}
private void finishedGetScreeennail()
{
- Log.v(TAG, " SCREENNAIL RECV FINISHED.");
+ Log.v(TAG, " --- SCREENNAIL RECV FINISHED. : " + objectId + " --- ");
// リセットコマンドを送ってみる
publisher.enqueueCommand(new PtpIpCommandGeneric(this, false, (objectId + 4), 0x902f));