OSDN Git Service

7dba88ae5ce79b3d3409c725b1bd4d60759dc449
[gokigen/PKRemote.git] / app / src / main / java / net / osdn / gokigen / pkremote / camera / vendor / ptpip / wrapper / connection / NikonCameraConnectSequenceForPlayback.java
1 package net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.connection;
2
3 import android.app.Activity;
4 import android.graphics.Color;
5 import android.util.Log;
6
7 import androidx.annotation.NonNull;
8
9 import net.osdn.gokigen.pkremote.R;
10 import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraConnection;
11 import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraStatusReceiver;
12 import net.osdn.gokigen.pkremote.camera.vendor.nikon.INikonInterfaceProvider;
13 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandCallback;
14 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandPublisher;
15 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages;
16 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.PtpIpCommandGeneric;
17 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.specific.CanonRegistrationMessage;
18 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.status.PtpIpStatusChecker;
19
20 public class NikonCameraConnectSequenceForPlayback implements Runnable, IPtpIpCommandCallback, IPtpIpMessages
21 {
22     private final String TAG = this.toString();
23
24     private final Activity context;
25     private final ICameraConnection cameraConnection;
26     private final ICameraStatusReceiver cameraStatusReceiver;
27     private final INikonInterfaceProvider interfaceProvider;
28     private final IPtpIpCommandPublisher commandIssuer;
29     private final PtpIpStatusChecker statusChecker;
30     private boolean isDumpLog = false;
31
32     NikonCameraConnectSequenceForPlayback(@NonNull Activity context, @NonNull ICameraStatusReceiver statusReceiver, @NonNull final ICameraConnection cameraConnection, @NonNull INikonInterfaceProvider interfaceProvider, @NonNull PtpIpStatusChecker statusChecker)
33     {
34         Log.v(TAG, " NikonCameraConnectSequenceForPlayback");
35         this.context = context;
36         this.cameraConnection = cameraConnection;
37         this.cameraStatusReceiver = statusReceiver;
38         this.interfaceProvider = interfaceProvider;
39         this.commandIssuer = interfaceProvider.getCommandPublisher();
40         this.statusChecker = statusChecker;
41     }
42
43     @Override
44     public void run()
45     {
46         try
47         {
48             // カメラとTCP接続
49             IPtpIpCommandPublisher issuer = interfaceProvider.getCommandPublisher();
50             if (!issuer.isConnected())
51             {
52                 if (!interfaceProvider.getCommandCommunication().connect())
53                 {
54                     // 接続失敗...
55                     interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.dialog_title_connect_failed_nikon), false, true, Color.RED);
56                     onConnectError(context.getString(R.string.dialog_title_connect_failed_nikon));
57                     return;
58                 }
59             }
60             else
61             {
62                 Log.v(TAG, "SOCKET IS ALREADY CONNECTED...");
63             }
64             // コマンドタスクの実行開始
65             issuer.start();
66
67             // 接続シーケンスの開始
68             sendRegistrationMessage();
69
70         }
71         catch (Exception e)
72         {
73             e.printStackTrace();
74             interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.dialog_title_connect_failed_nikon), false, true, Color.RED);
75             onConnectError(e.getLocalizedMessage());
76         }
77     }
78
79     private void onConnectError(String reason)
80     {
81         cameraConnection.alertConnectingFailed(reason);
82     }
83
84     @Override
85     public void onReceiveProgress(int currentBytes, int totalBytes, byte[] body)
86     {
87         Log.v(TAG, " " + currentBytes + "/" + totalBytes);
88     }
89
90     @Override
91     public boolean isReceiveMulti()
92     {
93         return (false);
94     }
95
96     @Override
97     public void receivedMessage(int id, byte[] rx_body)
98     {
99         switch (id)
100         {
101             case SEQ_REGISTRATION:
102                 if (checkRegistrationMessage(rx_body))
103                 {
104                     sendInitEventRequest(rx_body);
105                 }
106                 else
107                 {
108                     onConnectError(context.getString(R.string.connect_error_message));
109                 }
110                 break;
111
112             case SEQ_EVENT_INITIALIZE:
113                 if (checkEventInitialize(rx_body))
114                 {
115                     interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting1), false, false, 0);
116                     commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_OPEN_SESSION, isDumpLog, 0, 0x1002, 4, 0x41));
117                 }
118                 else
119                 {
120                     onConnectError(context.getString(R.string.connect_error_message));
121                 }
122                 break;
123
124             case SEQ_OPEN_SESSION:
125                 interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting2), false, false, 0);
126                 commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_INIT_SESSION, isDumpLog, 0, 0x902f));
127                 break;
128
129             case SEQ_INIT_SESSION:
130                 interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting3), false, false, 0);
131                 commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_CHANGE_REMOTE, isDumpLog, 0, 0x9114, 4, 0x15));
132                 break;
133
134             case SEQ_CHANGE_REMOTE:
135                 interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting4), false, false, 0);
136                 commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_SET_EVENT_MODE, isDumpLog, 0, 0x902f, 4, 0x02));
137                 break;
138
139             case SEQ_SET_EVENT_MODE:
140                 interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting5), false, false, 0);
141                 interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.connect_connect_finished), false, false, 0);
142                 connectFinished();
143                 Log.v(TAG, "CHANGED PLAYBACK MODE : DONE.");
144                 break;
145
146             default:
147                 Log.v(TAG, "RECEIVED UNKNOWN ID : " + id);
148                 onConnectError(context.getString(R.string.connect_receive_unknown_message));
149                 break;
150         }
151     }
152
153     private void sendRegistrationMessage()
154     {
155         interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.connect_start), false, false, 0);
156         cameraStatusReceiver.onStatusNotify(context.getString(R.string.connect_start));
157         commandIssuer.enqueueCommand(new CanonRegistrationMessage(this));
158     }
159
160     private void sendInitEventRequest(byte[] receiveData)
161     {
162         interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.connect_start_2), false, false, 0);
163         cameraStatusReceiver.onStatusNotify(context.getString(R.string.connect_start_2));
164         try
165         {
166             int eventConnectionNumber = (receiveData[8] & 0xff);
167             eventConnectionNumber = eventConnectionNumber + ((receiveData[9]  & 0xff) << 8);
168             eventConnectionNumber = eventConnectionNumber + ((receiveData[10] & 0xff) << 16);
169             eventConnectionNumber = eventConnectionNumber + ((receiveData[11] & 0xff) << 24);
170             statusChecker.setEventConnectionNumber(eventConnectionNumber);
171             interfaceProvider.getCameraStatusWatcher().startStatusWatch(null);
172
173             commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_OPEN_SESSION, isDumpLog, 0, 0x1002, 4, 0x41));
174         }
175         catch (Exception e)
176         {
177             e.printStackTrace();
178         }
179     }
180
181     private boolean checkRegistrationMessage(byte[] receiveData)
182     {
183         // データ(Connection Number)がないときにはエラーと判断する
184         return (!((receiveData == null)||(receiveData.length < 12)));
185     }
186
187     private boolean checkEventInitialize(byte[] receiveData)
188     {
189         Log.v(TAG, "checkEventInitialize() ");
190         return (!(receiveData == null));
191     }
192
193     private void connectFinished()
194     {
195         try
196         {
197             // 接続成功のメッセージを出す
198             interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.connect_connected), false, false, 0);
199
200             // ちょっと待つ
201             Thread.sleep(1000);
202
203             //interfaceProvider.getAsyncEventCommunication().connect();
204             //interfaceProvider.getCameraStatusWatcher().startStatusWatch(interfaceProvider.getStatusListener());  ステータスの定期確認は実施しない
205
206             // 接続成功!のメッセージを出す
207             interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.connect_connected), false, false, 0);
208
209             onConnectNotify();
210         }
211         catch (Exception e)
212         {
213             e.printStackTrace();
214         }
215     }
216
217     private void onConnectNotify()
218     {
219         try
220         {
221             final Thread thread = new Thread(new Runnable()
222             {
223                 @Override
224                 public void run()
225                 {
226                     // カメラとの接続確立を通知する
227                     cameraStatusReceiver.onStatusNotify(context.getString(R.string.connect_connected));
228                     cameraStatusReceiver.onCameraConnected();
229                     Log.v(TAG, " onConnectNotify()");
230                 }
231             });
232             thread.start();
233         }
234         catch (Exception e)
235         {
236             e.printStackTrace();
237         }
238     }
239 }