1 /****************************************************************************
2  *
3  * File: usb.c
4  *
5  * USB communication layer.
6  *
7  ****************************************************************************/
8 
9 #include "config.h"
10 
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <stdarg.h>
14 #include <string.h>
15 #include <time.h>
16 #include <sys/time.h>
17 #include <ctype.h>
18 #ifdef CANON_EXPERIMENTAL_UPLOAD
19 /* For filestat to get file time for upload */
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23 #endif /* CANON_EXPERIMENTAL_UPLOAD */
24 #ifdef OS2
25 #include <db.h>
26 #endif
27 
28 #ifdef ENABLE_NLS
29 #  include <libintl.h>
30 #  undef _
31 #  define _(String) dgettext (GETTEXT_PACKAGE, String)
32 #  ifdef gettext_noop
33 #    define N_(String) gettext_noop (String)
34 #  else
35 #    define N_(String) (String)
36 #  endif
37 #else
38 #  define textdomain(String) (String)
39 #  define gettext(String) (String)
40 #  define dgettext(Domain,Message) (Message)
41 #  define dcgettext(Domain,Message,Type) (Message)
42 #  define bindtextdomain(Domain,Directory) (Domain)
43 #  define _(String) (String)
44 #  define N_(String) (String)
45 #endif
46 
47 #include <gphoto2/gphoto2.h>
48 
49 #include "usb.h"
50 #include "canon.h"
51 #include "util.h"
52 
53 #ifdef __GNUC__
54 # define __unused__ __attribute__((unused))
55 #else
56 # define __unused__
57 #endif
58 
59 #define CHECK_RESULT(result) {int r = (result); if (r < 0) return (r);}
60 
61 /* IDENTIFY_INIT_TIMEOUT: the starting timeout (in milliseconds)
62  * to wait for the camera to respond to an "identify camera" request.
63  * This timeout is doubled for each retry */
64 /* It was originally 10, but this made the communication fail, so
65  * bump up to 100. */
66 #define IDENTIFY_INIT_TIMEOUT 100
67 
68 /* IDENTIFY_MAX_ATTEMPTS: how many "identify camera" requests to send
69  * to the camera, until we give up for lack of response. */
70 #define IDENTIFY_MAX_ATTEMPTS 5
71 
72 /* CANON_FAST_TIMEOUT: how long (in milliseconds) we should wait for
73  * an URB to come back on an interrupt endpoint */
74 #define CANON_FAST_TIMEOUT 500
75 
76 /* WARNING: This destroys reentrancy of the code. Better to put this
77  * in the camera descriptor somewhere. */
78 static int serial_code = 0;
79 
80 /* Map camera status codes (from offset 0x50 in reply block) to
81  * messages. */
82 static struct canon_usb_status canon_usb_status_table[] = {
83         {0x00000000, NULL},
84         {0x02000022, "File not found"},
85         {0x02000029, "File was protected"},
86         {0x0200002a, "Compact Flash card full"},
87         {0x02000081, "Failed to lock EOS keys"},
88         {0x02000082, "Failed to unlock EOS keys"},
89         {0x02000085, "Could not switch to capture mode"},
90         {0x02000086, "Invalid command parameters"},
91         {0x00000086, "Can't unlock EOS keys (new)"},
92         {0x02000087, "No storage card in camera"},
93 	{0x82200040, "Unknown error (new protocol)"},
94 	{0x82220040, "Unknown error (new protocol)"}
95 };
96 
97 
98 /*
99  * Command codes are structured:
100  *   cmd2=11 -> camera control,
101  *   cmd2=12 -> storage control.
102  *
103  *   cmd3=201 -> fixed length response
104  *   cmd3=202 -> variable length response
105  */
106 
107 static const struct canon_usb_cmdstruct canon_usb_cmd[] = {
108 	{CANON_USB_FUNCTION_GET_FILE,		"Get file",			0x01, 0x11, 0x202,	0x40},
109 	{CANON_USB_FUNCTION_MKDIR,		"Make directory",		0x05, 0x11, 0x201,	0x54},
110 	{CANON_USB_FUNCTION_RMDIR,		"Remove directory",		0x06, 0x11, 0x201,	0x54},
111 	{CANON_USB_FUNCTION_DISK_INFO,		"Disk info request",		0x09, 0x11, 0x201,	0x5c},
112 	/* 0x0a is overloaded: "flash device ident" and "delete file",
113 	 * with different responses */
114 	{CANON_USB_FUNCTION_FLASH_DEVICE_IDENT,	"Flash device ident",	0x0a, 0x11, 0x202,	0x40},
115 	{CANON_USB_FUNCTION_DELETE_FILE_2,	"Delete file",		0x0a, 0x11, 0x201,	0x54},
116 	{CANON_USB_FUNCTION_GET_DIRENT,		"Get directory entries",	0x0b, 0x11, 0x202,	0x40},
117 	/* Command code 0x0d is overloaded: delete file (old),
118 	 * disk info request ID (new). */
119 	{CANON_USB_FUNCTION_DELETE_FILE,	"Delete file",		0x0d, 0x11, 0x201,	0x54},
120 	{CANON_USB_FUNCTION_DISK_INFO_2,	"Disk info request (new)",	0x0d, 0x11, 0x201,	0x5c},
121 	/* Command code 0x0e is overloaded: set file attribute (old),
122 	 * flash device ID (new). And the response is different: fixed
123 	 * length in old, variable length in new. */
124 	{CANON_USB_FUNCTION_SET_ATTR,		"Set file attributes",	0x0e, 0x11, 0x201,	0x54},
125 	{CANON_USB_FUNCTION_FLASH_DEVICE_IDENT_2, "Flash device ident (new)", 0x0e, 0x11, 0x202,	0x40},
126 	{CANON_USB_FUNCTION_SET_FILE_TIME,	"Set file time",		0x0f, 0x11, 0x201,	0x54},
127 
128 	{CANON_USB_FUNCTION_IDENTIFY_CAMERA,	"Identify camera",		0x01, 0x12, 0x201,	0x9c},
129 	{CANON_USB_FUNCTION_GET_TIME,		"Get time",			0x03, 0x12, 0x201,	0x60},
130 	{CANON_USB_FUNCTION_SET_TIME,		"Set time",			0x04, 0x12, 0x201,	0x54},
131 	/* 0x05 is overloaded: "change owner" and "get owner", with
132 	 * different responses */
133 	{CANON_USB_FUNCTION_CAMERA_CHOWN,	"Change camera owner",		0x05, 0x12, 0x201,	0x54},
134 	{CANON_USB_FUNCTION_GET_OWNER,		"Get owner name (new)",		0x05, 0x12, 0x201,	0x74},
135 	{CANON_USB_FUNCTION_CAMERA_CHOWN_2,	"Change owner (new)",	0x06, 0x12, 0x201,	0x54},
136 	{CANON_USB_FUNCTION_POWER_STATUS,	"Power supply status",		0x0a, 0x12, 0x201,	0x58},
137 	/* 0x13 is overloaded: remote camera control in the original
138 	   protocol, power status in the new protocol. */
139 	{CANON_USB_FUNCTION_CONTROL_CAMERA,	"Remote camera control",	0x13, 0x12, 0x201,      0x40},
140 	{CANON_USB_FUNCTION_POWER_STATUS_2,	"Power supply status (new)",	0x13, 0x12, 0x201,      0x58},
141 	{CANON_USB_FUNCTION_RETRIEVE_CAPTURE,	"Download a captured image",	0x17, 0x12, 0x202,      0x40},
142 	{CANON_USB_FUNCTION_RETRIEVE_PREVIEW,	"Download a captured preview",	0x18, 0x12, 0x202,      0x40},
143 	{CANON_USB_FUNCTION_UNKNOWN_FUNCTION,	"Unknown function",		0x1a, 0x12, 0x201,	0x80},
144 	{CANON_USB_FUNCTION_EOS_LOCK_KEYS,	"EOS lock keys",		0x1b, 0x12, 0x201,	0x54},
145 	{CANON_USB_FUNCTION_EOS_UNLOCK_KEYS,	"EOS unlock keys",		0x1c, 0x12, 0x201,	0x54},
146 	{CANON_USB_FUNCTION_EOS_GET_BODY_ID,	"EOS get body ID",		0x1d, 0x12, 0x201,	0x58},
147 	{CANON_USB_FUNCTION_GET_PIC_ABILITIES,	"Get picture abilities",	0x1f, 0x12, 0x201,	0x384},
148 	{CANON_USB_FUNCTION_GENERIC_LOCK_KEYS,	"Lock keys and turn off LCD",	0x20, 0x12, 0x201,	0x54},
149 	{CANON_USB_FUNCTION_20D_UNKNOWN_1,	"Unknown EOS 20D function",	0x21, 0x12, 0x201,	0x54},
150 	{CANON_USB_FUNCTION_20D_UNKNOWN_2,	"Unknown EOS 20D function",	0x22, 0x12, 0x201,	0x54},
151 	{CANON_USB_FUNCTION_EOS_GET_BODY_ID_2,	"Get body ID (new)",		0x23, 0x12, 0x201,	0x58},
152 	{CANON_USB_FUNCTION_GET_PIC_ABILITIES_2, "Get picture abilities (new)",	0x24, 0x12, 0x201,	0x474},
153 	{CANON_USB_FUNCTION_CONTROL_CAMERA_2,	"Remote camera control (new)",	0x25, 0x12, 0x201,	0x40},
154 	{CANON_USB_FUNCTION_RETRIEVE_CAPTURE_2, "Download captured image (new)", 0x26, 0x12, 0x202,	0x40},
155 	{CANON_USB_FUNCTION_LOCK_KEYS_2,	"Lock keys (new)",		0x35, 0x12, 0x201,	0x5c},
156 	{CANON_USB_FUNCTION_UNLOCK_KEYS_2,	"Unlock keys (new)",		0x36, 0x12, 0x201,	0x54},
157 	/* WARNING: I don't think this is really the right value, but
158 	 * it gives no error on EOS 20D -- swestin 22-Mar-05 */
159 	{CANON_USB_FUNCTION_SET_ATTR_2,		"Set file attributes (new))", 0x07, 0x11, 0x201,	0x54},
160 	{ 0, NULL, 0, 0, 0, 0 }
161 };
162 
163 
164 const struct canon_usb_control_cmdstruct canon_usb_control_cmd[] = {
165 	/* COMMAND NAME                         Description            Value   CmdLen ReplyLen */
166 	{CANON_USB_CONTROL_INIT,                "Camera control init",  0x00,  0x18,  0x1c},  /* load 0x00, 0x00 */
167 	{CANON_USB_CONTROL_SHUTTER_RELEASE,     "Release shutter",      0x04,  0x18,  0x1c},  /* load 0x04, 0x00 */
168 	{CANON_USB_CONTROL_SET_PARAMS,          "Set release params",   0x07,  0x3c,  0x1c},  /* ?? */
169 	{CANON_USB_CONTROL_SET_TRANSFER_MODE,   "Set transfer mode",    0x09,  0x1c,  0x1c},  /* load (0x09, 0x04, 0x03) or (0x09, 0x04, 0x02000003) */
170 	{CANON_USB_CONTROL_GET_PARAMS,          "Get release params",   0x0a,  0x18,  0x4c},  /* load 0x0a, 0x00 */
171 	{CANON_USB_CONTROL_GET_ZOOM_POS,        "Get zoom position",    0x0b,  0x18,  0x20},  /* load 0x0b, 0x00 */
172 	{CANON_USB_CONTROL_SET_ZOOM_POS,        "Set zoom position",    0x0c,  0x1c,  0x1c},  /* load 0x0c, 0x04, 0x01 (or 0x0c, 0x04, 0x0b) (or 0x0c, 0x04, 0x0a) or (0x0c, 0x04, 0x09) or (0x0c, 0x04, 0x08) or (0x0c, 0x04, 0x07) or (0x0c, 0x04, 0x06) or (0x0c, 0x04, 0x00) */
173 	{CANON_USB_CONTROL_GET_AVAILABLE_SHOT,  "Get available shot",   0x0d,  0x18,  0x20},
174 	{CANON_USB_CONTROL_GET_CUSTOM_FUNC,     "Get custom func.",     0x0f,  0x22,  0x26},
175 	{CANON_USB_CONTROL_GET_EXT_PARAMS_SIZE, "Get ext. release params size",
176 	 0x10,  0x1c,  0x20},  /* load 0x10, 0x00 */
177 	{CANON_USB_CONTROL_GET_EXT_PARAMS,      "Get ext. release params",
178 	 0x12,  0x1c,  0x2c},  /* load 0x12, 0x04, 0x10 */
179 	{CANON_USB_CONTROL_SET_EXT_PARAMS,      "Set extended params",  0x13,  0x15,  0x1c}, /* based on EOS 20D */
180 
181 	{CANON_USB_CONTROL_EXIT,                "Exit release control", 0x01,  0x18,  0x1c},
182 	/* New subcodes for new version of protocol */
183 	{CANON_USB_CONTROL_UNKNOWN_1,		"Unknown remote subcode",
184 	 0x1b,  0x08,  0x5e},
185 	{CANON_USB_CONTROL_UNKNOWN_2,		"Unknown remote subcode",
186 	 0x1c,  0x00,  0x00},
187 	/* unobserved, commands present in canon headers defines, but need more usb snoops to get reply lengths */
188 	{CANON_USB_CONTROL_VIEWFINDER_START,    "Start viewfinder",     0x02,  0x00,  0x00},
189 	{CANON_USB_CONTROL_VIEWFINDER_STOP,     "Stop viewfinder",      0x03,  0x00,  0x00},
190 	{CANON_USB_CONTROL_SET_CUSTOM_FUNC,     "Set custom func.",     0x0e,  0x00,  0x00},
191 	{CANON_USB_CONTROL_GET_EXT_PARAMS_VER,  "Get extended params version",
192 	 0x11,  0x00,  0x00},
193 	{CANON_USB_CONTROL_SELECT_CAM_OUTPUT,   "Select camera output", 0x14,  0x00,  0x00}, /* LCD (0x1), Video out (0x2), or OFF (0x3) */
194 	{CANON_USB_CONTROL_DO_AE_AF_AWB,        "Do AE, AF, and AWB",   0x15,  0x00,  0x00},
195 	{ 0, NULL, 0, 0, 0 }
196 };
197 
198 static int canon_usb_identify (Camera *camera, GPContext *context);
199 
200 /**
201  * canon_usb_camera_init:
202  * @camera: camera to initialize
203  * @context: context for error reporting
204  *
205  * Initializes the USB camera through a series of read/writes
206  *
207  * Returns: gphoto2 error code
208  *  @GP_OK on success.
209  *  @GP_ERROR_OS_FAILURE if it seems to be an OS error
210  *  @GP_ERROR_CORRUPTED_DATA if communication was completed, but the
211  *               response was other than expected.
212  *
213  */
214 static int
canon_usb_camera_init(Camera * camera,GPContext * context)215 canon_usb_camera_init (Camera *camera, GPContext *context)
216 {
217         unsigned char msg[0x58];
218         unsigned char buffer[0x44];
219         int i, read_bytes, timeout;
220         char *camstat_str = _("NOT RECOGNIZED");
221         unsigned char camstat;
222 
223         GP_DEBUG ("canon_usb_camera_init()");
224 
225         memset (msg, 0, sizeof (msg));
226         memset (buffer, 0, sizeof (buffer));
227 
228         i = canon_usb_identify (camera, context);
229         if (i != GP_OK)
230                 return i;
231 
232         /* Read one byte from the control pipe. */
233         i = gp_port_usb_msg_read (camera->port, 0x0c, 0x55, 0, (char *)msg, 1);
234         if (i != 1) {
235                 gp_context_error (context, _("Could not establish initial contact with camera"));
236 		if (i < GP_OK)
237 			return i;
238                 return GP_ERROR_CORRUPTED_DATA;
239         }
240         camstat = msg[0];
241         switch (camstat) {
242 	case 'A':
243 		camstat_str = _("Camera was already active");
244 		break;
245 	case 'C':
246 		camstat_str = _("Camera was woken up");
247 		break;
248 	case 'I':
249 	case 'E':
250 	default:
251 		gp_context_error (context, _("Initial camera response '%c' unrecognized"),
252 				  camstat);
253 		return GP_ERROR_CORRUPTED_DATA;
254         }
255 
256         GP_DEBUG ("canon_usb_camera_init() initial camera response: %c/'%s'",
257                   camstat, camstat_str);
258 
259         i = gp_port_usb_msg_read (camera->port, 0x04, 0x1, 0, (char *)msg, 0x58);
260         if (i != 0x58) {
261                 if ( i < 0 ) {
262 			gp_context_error (context,
263 				_("Step #2 of initialization failed: (\"%s\" on read of %i). "
264 				"Camera not operational"), gp_result_as_string(i), 0x58);
265                         return GP_ERROR_OS_FAILURE;
266 		} else {
267 			gp_context_error (context,
268 				_("Step #2 of initialization failed! (returned %i bytes, expected %i). "
269 				"Camera not operational"), i, 0x58);
270 			return GP_ERROR_CORRUPTED_DATA;
271 		}
272         }
273         /* Get maximum download transfer length from camera, if
274          * provided */
275         camera->pl->xfer_length = le32atoh (msg+0x4c);
276         if ( camera->pl->xfer_length == 0xFFFFFFFF )
277                 camera->pl->xfer_length = USB_BULK_READ_SIZE; /* Use default */
278         GP_DEBUG ("canon_usb_camera_init() set transfer length to 0x%x",
279                   camera->pl->xfer_length );
280 
281         if (camstat == 'A') {
282                 /* read another 0x50 bytes */
283                 i = gp_port_usb_msg_read (camera->port, 0x04, 0x4, 0, (char *)msg, 0x50);
284                 if (i != 0x50) {
285                         if ( i < 0 ) {
286 				gp_context_error (context,
287 						  _("Step #3 of initialization failed: "
288 						    "\"%s\" on read of %i. "
289 						    "Camera not operational"), gp_result_as_string(i), 0x50);
290                                 return GP_ERROR_OS_FAILURE;
291 			}
292                         else {
293 				gp_context_error (context,
294 						  _("Step #3 of initialization failed! "
295 						    "(returned %i, expected %i). "
296 						    "Camera not operational"), i, 0x50);
297                                 return GP_ERROR_CORRUPTED_DATA;
298 			}
299                 }
300 
301         }
302         else {
303                 /* set byte 0 in msg to new "canon length" (0x10) (which is total
304                  * packet size - 0x40) and then move the last 0x10 bytes of msg to
305                  * offset 0x40 and write it back to the camera.
306                  */
307                 memset ( msg, 0, 0x40 );
308                 msg[0] = 0x10;
309                 memmove (msg + 0x40, msg + 0x48, 0x10);
310                 i = gp_port_usb_msg_write (camera->port, 0x04, 0x11, 0, (char *)msg, 0x50);
311                 if (i != 0x50) {
312                         if ( i < 0 ) {
313 				gp_context_error (context,
314 						  _("Step #3 of initialization failed: "
315 						    "\"%s\" on write of %i. "
316 						    "Camera not operational"), gp_result_as_string(i), 0x50);
317                                 return GP_ERROR_OS_FAILURE;
318 			}
319                         else {
320 				gp_context_error (context,
321 						  _("Step #3 of initialization failed! "
322 						    "(returned %i, expected %i). "
323 						    "Camera not operational"), i, 0x50);
324                                 return GP_ERROR_CORRUPTED_DATA;
325 			}
326                 }
327 		/* Temp hack for SD500/IXUS 700/IXY 600 for testing */
328                 if ( camera->pl->md->model != CANON_CLASS_6 && camera->pl->md->usb_product != 0x30f2 ) {
329                         /* We expect to get 0x44 bytes here, but the camera is picky at this stage and
330                          * we must read 0x40 bytes and then read 0x4 bytes more.
331                          */
332                         i = gp_port_read (camera->port, (char *)buffer, 0x40);
333                         if ((i >= 4)
334                             && (buffer[i - 4] == 0x54) && (buffer[i - 3] == 0x78)
335                             && (buffer[i - 2] == 0x00) && (buffer[i - 1] == 0x00)) {
336 
337                                 /* We have some reports that sometimes the camera takes a long
338                                  * time to respond to the above read request and then comes back with
339                                  * the 54 78 00 00 packet, instead of telling us to read four more
340                                  * bytes which is the normal 54 78 00 00 packet.
341                                  */
342 
343                                 GP_DEBUG ("canon_usb_camera_init() "
344                                           "expected %i bytes, got %i bytes with \"54 78 00 00\" "
345                                           "at the end, so we just ignore the whole bunch and call it a day",
346                                           0x40, i);
347                         }
348                         else {
349                                 if (i != 0x40) {
350                                         if ( i < 0 ) {
351 						gp_context_error (context,
352 								  _("Step #4 failed: "
353 								    "\"%s\" on read of %i. Camera not operational"),
354 								  gp_result_as_string(i), 0x40);
355                                                 return GP_ERROR_OS_FAILURE;
356 					}
357                                         else {
358 						gp_context_error (context,
359 								  _("Step #4 failed "
360 								    "(returned %i, expected %i). Camera not operational"),
361 								  i, 0x40);
362                                                 return GP_ERROR_CORRUPTED_DATA;
363 					}
364                                 }
365                         }
366                         /* just check if (int) buffer[0] says 0x4 or not, log a warning if it doesn't. */
367                         read_bytes = le32atoh (buffer);
368                         if (read_bytes != 4)
369                                 GP_DEBUG ("canon_usb_camera_init() camera says to read %i more bytes, "
370                                           "we would have expected 4 - overriding since some cameras are "
371                                           "known not to give correct numbers of bytes.", read_bytes);
372                         i = gp_port_read (camera->port, (char *)buffer, 4);
373                         if (i != 4) {
374 				if ( i < 0 )
375 					GP_DEBUG ("canon_usb_camera_init() "
376 						  "Step #5 of initialization failed: \"%s\" from read of %i. "
377 						  "Camera might still work though. Continuing.",
378 						  gp_result_as_string(i), 4);
379 				else
380 					GP_DEBUG ("canon_usb_camera_init() "
381 						  "Step #5 of initialization failed! (returned %i, expected %i) "
382 						  "Camera might still work though. Continuing.",
383 						  i, 4);
384 			}
385                 }
386                 else {
387                         /* Newer cameras can give us all 0x44 bytes at
388                          * once; some insist on it. */
389                         i = gp_port_read (camera->port, (char *)buffer, 0x44);
390                         if (i != 0x44) {
391 				if ( i < 0 ) {
392 					gp_context_error (context,
393 							  _("Step #4 failed: "
394 							    "\"%s\" on read of %i. Camera not operational"),
395 							  gp_result_as_string(i), 0x44);
396 					return GP_ERROR_OS_FAILURE;
397 				}
398 				else {
399 					gp_context_error (context,
400 							  _("Step #4 failed "
401 							    "(returned %i, expected %i). Camera not operational"),
402 							  i, 0x44);
403 					return GP_ERROR_CORRUPTED_DATA;
404 				}
405                         }
406                 }
407 
408                 read_bytes = 0;
409 
410 		gp_port_get_timeout ( camera->port, &timeout );
411 		gp_port_set_timeout ( camera->port, CANON_FAST_TIMEOUT );
412 
413                 do {
414                         GP_DEBUG ( "canon_usb_camera_init() read_bytes=0x%x", read_bytes );
415                         i = gp_port_check_int ( camera->port, (char *)buffer, 0x10 );
416                         if ( i > 0 )
417                                 read_bytes += i;
418                 } while ( read_bytes < 0x10 && i >= 0 );
419 
420 		gp_port_set_timeout ( camera->port, timeout );
421 
422                 if ( read_bytes < 0x10 ) {
423                         GP_DEBUG ( "canon_usb_camera_init() interrupt read returned only %d bytes, status=%d", read_bytes, i );
424                         if ( i < 0 )
425                                 return GP_ERROR_OS_FAILURE;
426                         else
427                                 return GP_ERROR_CORRUPTED_DATA;
428                 }
429                 else if ( i < 0 ) {
430                         GP_DEBUG ( "canon_usb_camera_init() interrupt read failed, status=%d", i );
431                         return GP_ERROR_CORRUPTED_DATA;
432                 }
433                 else if ( i > 0x10 )
434                         GP_DEBUG ( "canon_usb_camera_init() interrupt read %d bytes, expected 16", read_bytes );
435                 else
436                         GP_DEBUG ( "canon_usb_camera_init() interrupt read OK" );
437         }
438 
439         GP_DEBUG ("canon_usb_camera_init() "
440                   "PC sign on LCD should be lit now (if your camera has a PC sign)");
441 
442         read_bytes = 0;
443         return camstat;
444 }
445 
446 /* Forward reference for use within canon_usb_init() */
447 static int canon_usb_get_body_id (Camera *camera, GPContext *context);
448 
449 /**
450  * canon_usb_init:
451  * @camera: camera to initialize
452  * @context: context for error reporting
453  *
454  * Initializes the given USB device.
455  *
456  * Returns: gphoto2 error code (%GP_OK on success).
457  *
458  */
459 int
canon_usb_init(Camera * camera,GPContext * context)460 canon_usb_init (Camera *camera, GPContext *context)
461 {
462         /* unsigned char buffer[0x44]; */
463         int res, id_retry, i, camstat;
464         /* int read_bytes; */
465 	int orig_mstimeout = -1;
466 	int id_mstimeout = IDENTIFY_INIT_TIMEOUT; /* separate timeout for
467 						     identify camera */
468 
469         GP_DEBUG ("Initializing the (USB) camera.");
470 
471 #if 0
472 	/* FIXME: as raspberry user confirmed the need for those...
473  	 * I am currently not sure why I added them.
474 	 */
475 	gp_port_usb_clear_halt (camera->port, GP_PORT_USB_ENDPOINT_IN);
476 	gp_port_usb_clear_halt (camera->port, GP_PORT_USB_ENDPOINT_OUT);
477 	gp_port_usb_clear_halt (camera->port, GP_PORT_USB_ENDPOINT_INT);
478 #endif
479         camstat = canon_usb_camera_init (camera, context);
480         if ( camstat < 0 )
481                 return camstat;
482 
483 	/* Save the original timeout value and set up the initial
484 	   identify camera timeout value */
485 	gp_port_get_timeout (camera->port, &orig_mstimeout);
486 	gp_port_set_timeout (camera->port, id_mstimeout);
487 
488         /* We retry the identify camera because sometimes (camstat == 'A'
489          * in canon_usb_camera_init()) this is necessary to get the camera
490          * back in sync, and the windows driver actually executes four of
491          * these in a row before downloading thumbnails.
492          */
493         res = GP_ERROR;
494         for (id_retry = 1; id_retry <= IDENTIFY_MAX_ATTEMPTS; id_retry++) {
495                 res = canon_int_identify_camera (camera, context);
496                 if (res != GP_OK) {
497                         GP_DEBUG ("Identify camera try %i/%i failed %s", id_retry, IDENTIFY_MAX_ATTEMPTS,
498                                   id_retry <
499                                   IDENTIFY_MAX_ATTEMPTS ? "(this is OK)" : "(now it's not OK any more)");
500 			id_mstimeout *= 2;
501 			gp_port_set_timeout (camera->port, id_mstimeout);
502 		}
503                 else
504                         break;
505         }
506 
507 	/* Restore the original timeout value */
508 	gp_port_set_timeout (camera->port, orig_mstimeout);
509 
510         if (res != GP_OK) {
511                 gp_context_error (context,
512                                   _("Camera not ready, "
513                                     "multiple 'Identify camera' requests failed: %s"),
514                                   gp_result_as_string (res));
515                 if ( res < 0 )
516                         return GP_ERROR_OS_FAILURE;
517                 else
518                         return GP_ERROR_CORRUPTED_DATA;
519         }
520 
521         if ( camera->pl->md->model == CANON_CLASS_6 ) {
522                 unsigned char *c_res;
523                 unsigned int bytes_read = 0;
524 
525                 /* Get body ID here */
526                 GP_DEBUG ( "canon_usb_init: camera uses newer protocol, so we get body ID" );
527                 res = canon_usb_get_body_id ( camera, context );
528                 if ( res < 0 ) {
529                         GP_DEBUG ( "canon_usb_init: \"Get body ID\" failed, code %d", res );
530                         return ( res );
531                 }
532 
533                 GP_DEBUG ( "canon_usb_init: camera uses newer protocol, so we get camera abilities" );
534                 c_res = canon_usb_dialogue (camera,
535                                             CANON_USB_FUNCTION_GET_PIC_ABILITIES_2,
536                                             &bytes_read, NULL, 0);
537 
538                 if ( c_res == NULL ) {
539                         GP_DEBUG ( "canon_usb_init: \"get picture abilities\" failed; continuing anyway." );
540                 }
541                 else if ( bytes_read == 0x424 ) {
542                         GP_DEBUG ( "canon_usb_init: Got the expected length back from \"get picture abilities.\"" );
543                 } else {
544                         GP_DEBUG ( "canon_usb_init: "
545 				   "Unexpected return of %i bytes (expected %i) from \"get picture abilities.\" We will continue.",
546 				   bytes_read, 0x424 );
547                 }
548                 res = canon_int_get_battery(camera, NULL, NULL, context);
549                 if (res != GP_OK) {
550                         gp_context_error (context, _("Camera not ready, get_battery failed: %s"),
551                                           gp_result_as_string (res));
552                         return res;
553                 }
554         }
555         else {
556                 if ( camera->pl->md->model != CANON_CLASS_4 ) {
557                         i = canon_usb_lock_keys(camera,context);
558                         if( i < 0 ) {
559                                 gp_context_error (context, _("lock keys failed."));
560                                 return i;
561                         }
562                 }
563 
564                 res = canon_int_get_battery(camera, NULL, NULL, context);
565                 if (res != GP_OK) {
566                         gp_context_error (context, _("Camera not ready, get_battery failed: %s"),
567                                           gp_result_as_string (res));
568                         return res;
569                 }
570 
571         }
572 
573         return GP_OK;
574 }
575 
576 /**
577  * canon_usb_lock_keys:
578  * @camera: camera to lock keys on
579  * @context: context for error reporting
580  *
581  * Lock the keys on the camera and turn off the display
582  *
583  * Returns: gphoto2 error code
584  *
585  */
586 int
canon_usb_lock_keys(Camera * camera,GPContext * context)587 canon_usb_lock_keys (Camera *camera, GPContext *context)
588 {
589         unsigned char *c_res;
590         unsigned int bytes_read;
591         unsigned char payload[4];
592 
593         GP_DEBUG ("canon_usb_lock_keys()");
594 
595         switch (camera->pl->md->model) {
596 	case CANON_CLASS_NONE:
597 	case CANON_CLASS_0:
598 		GP_DEBUG ("canon_usb_lock_keys: Your camera model does not need the keylock.");
599 		break;
600 
601 	case CANON_CLASS_1:
602 	case CANON_CLASS_2:
603 	case CANON_CLASS_3:
604 		/* Previous default; I doubt that any new
605 		 * cameras will work this way. */
606 		GP_DEBUG ("canon_usb_lock_keys: Locking camera and turning off LCD using 'normal' locking code...");
607 
608 		c_res = canon_usb_dialogue (camera,
609 					    CANON_USB_FUNCTION_GET_PIC_ABILITIES,
610 					    &bytes_read, NULL, 0);
611 
612 		if ( c_res == NULL )
613 			return GP_ERROR_OS_FAILURE;
614 		if ( bytes_read == 0x334 ) {
615 			GP_DEBUG ( "canon_usb_lock_keys: Got the expected length back from \"get picture abilities.\"" );
616 		} else {
617 			GP_DEBUG ( "canon_usb_lock_keys: "
618 				   "Unexpected return of %i bytes (expected %i) from "
619 				   "\"get picture abilities.\" We will continue.",
620 				   bytes_read, 0x334 );
621 		}
622 		c_res = canon_usb_dialogue (camera,
623 					    CANON_USB_FUNCTION_GENERIC_LOCK_KEYS,
624 					    &bytes_read, NULL, 0);
625 		if ( c_res == NULL )
626 			return GP_ERROR_OS_FAILURE;
627 		if (bytes_read == 0x4) {
628 			GP_DEBUG ("canon_usb_lock_keys: Got the expected length back.");
629 		} else {
630 			gp_context_error (context,
631 					  _("canon_usb_lock_keys: "
632 					    "Unexpected length returned from \"lock keys\" function (%i bytes, expected %i)"),
633 					  bytes_read, 0x4);
634 			return GP_ERROR_CORRUPTED_DATA;
635 		}
636 		camera->pl->keys_locked = TRUE;
637 		break;
638 
639 	case CANON_CLASS_4:
640 		GP_DEBUG ("canon_usb_lock_keys: Locking camera and turning off LCD using 'EOS' locking code...");
641 
642 		memset (payload, 0, sizeof (payload));
643 		payload[0] = 0x06;
644 
645 		c_res = canon_usb_dialogue (camera, CANON_USB_FUNCTION_EOS_LOCK_KEYS,
646 					    &bytes_read, payload, 4);
647 		if ( c_res == NULL )
648 			return GP_ERROR_OS_FAILURE;
649 		if (bytes_read == 0x4) {
650 			GP_DEBUG ("canon_usb_lock_keys: Got the expected length back.");
651 		} else {
652 			gp_context_error (context,
653 					  _("canon_usb_lock_keys: "
654 					    "Unexpected length returned (%i bytes, expected %i)"),
655 					  bytes_read, 0x4);
656 			return GP_ERROR_CORRUPTED_DATA;
657 		}
658 		camera->pl->keys_locked = TRUE;
659 		break;
660 
661 	case CANON_CLASS_5:
662 		/* Doesn't implement "get picture abilities",
663 		   but isn't an EOS camera, so we have to use
664 		   the "normal" key lock command. Since the
665 		   S45 is a relatively new model (in
666 		   Jan. 2003), I suspect that we will find
667 		   more cameras in the future that work this
668 		   way. */
669 		GP_DEBUG ("canon_usb_lock_keys: Locking camera and turning off LCD using class 5 locking code...");
670 		c_res = canon_usb_dialogue (camera,
671 					    CANON_USB_FUNCTION_GENERIC_LOCK_KEYS,
672 					    &bytes_read, NULL, 0);
673 		if ( c_res == NULL )
674 			return GP_ERROR_OS_FAILURE;
675 		if (bytes_read == 0x4) {
676 			GP_DEBUG ("canon_usb_lock_keys: Got the expected length back.");
677 		} else {
678 			gp_context_error (context,
679 					  _("canon_usb_lock_keys: "
680 					    "Unexpected length returned (%i bytes, expected %i)"),
681 					  bytes_read, 0x4);
682 			return GP_ERROR_CORRUPTED_DATA;
683 		}
684 		camera->pl->keys_locked = TRUE;
685 		break;
686 	case CANON_CLASS_6:
687 		/* Newest variation of protocol, and quite
688 		 * different. "Get picture abilities" is
689 		 * implemented, but with a different command
690 		 * code and a longer buffer returned. */
691 		GP_DEBUG ("Camera uses newer protocol: Locking camera keys and turning off LCD...");
692 
693 		c_res = canon_usb_dialogue (camera,
694 					    CANON_USB_FUNCTION_GET_PIC_ABILITIES_2,
695 					    &bytes_read, NULL, 0);
696 
697 		if ( c_res == NULL ) {
698 			GP_DEBUG ( "canon_usb_lock_keys: \"get picture abilities\" failed; continuing anyway." );
699 		}
700 		else if ( bytes_read == 0x424 ) {
701 			GP_DEBUG ( "canon_usb_lock_keys: Got the expected length back from \"get picture abilities.\"" );
702 		} else {
703 			GP_DEBUG ( "canon_usb_lock_keys: "
704 				   "Unexpected return of %i bytes (expected %i) from \"get picture abilities.\" We will continue.",
705 				   bytes_read, 0x424 );
706 		}
707 
708 		memset (payload, 0, sizeof (payload));
709 		payload[0] = 0x06;
710 
711 		c_res = canon_usb_dialogue (camera, CANON_USB_FUNCTION_LOCK_KEYS_2,
712 					    &bytes_read, payload, 4);
713 		if ( c_res == NULL )
714 			return GP_ERROR_OS_FAILURE;
715 		if (bytes_read == 0xc) {
716 			GP_DEBUG ("canon_usb_lock_keys: Got the expected length back.");
717 		} else {
718 			gp_context_error (context,
719 					  _("canon_usb_lock_keys: "
720 					    "Unexpected length returned (%i bytes, expected %i)"),
721 					  bytes_read, 0xc);
722 			return GP_ERROR_CORRUPTED_DATA;
723 		}
724 		camera->pl->keys_locked = TRUE;
725 		break;
726 
727         }
728 
729         return GP_OK;
730 }
731 
732 /**
733  * canon_usb_unlock_keys:
734  * @camera: camera to unlock keys on
735  * @context: context for error reporting
736  *
737  * Unlocks the keys on cameras that support this
738  *
739  * Returns: gphoto2 error code
740  *
741  */
742 int
canon_usb_unlock_keys(Camera * camera,GPContext * context)743 canon_usb_unlock_keys (Camera *camera, GPContext *context)
744 {
745         unsigned char *c_res;
746         unsigned int bytes_read;
747 
748         GP_DEBUG ("canon_usb_unlock_keys()");
749 
750         if ( !camera->pl->keys_locked )
751                 GP_DEBUG ("canon_usb_unlock_keys: keys aren't locked" );
752         else
753                 if ( camera->pl->md->model == CANON_CLASS_4 ) {
754                         c_res = canon_usb_dialogue (camera, CANON_USB_FUNCTION_EOS_UNLOCK_KEYS,
755                                                     &bytes_read, NULL, 0);
756                         if ( c_res == NULL )
757                                 return GP_ERROR_OS_FAILURE;
758                         if (bytes_read == 0x4) {
759                                 GP_DEBUG ("canon_usb_unlock_keys: Got the expected length back.");
760                         } else {
761                                 gp_context_error (context,
762                                                   _("canon_usb_unlock_keys: "
763                                                     "Unexpected length returned (%i bytes, expected %i)"),
764                                                   bytes_read, 0x4);
765                                 return GP_ERROR_CORRUPTED_DATA;
766                         }
767                         camera->pl->keys_locked = FALSE;
768                 }
769                 else if ( camera->pl->md->model == CANON_CLASS_6 ) {
770                         c_res = canon_usb_dialogue (camera, CANON_USB_FUNCTION_UNLOCK_KEYS_2,
771                                                     &bytes_read, NULL, 0);
772                         if ( c_res == NULL )
773                                 return GP_ERROR_OS_FAILURE;
774                         if (bytes_read == 0x4) {
775                                 GP_DEBUG ("canon_usb_unlock_keys: Got the expected length back.");
776                         } else {
777                                 gp_context_error (context,
778                                                   _("canon_usb_unlock_keys: "
779                                                     "Unexpected length returned (%i bytes, expected %i)"),
780                                                   bytes_read, 0x4);
781                                 return GP_ERROR_CORRUPTED_DATA;
782                         }
783                         camera->pl->keys_locked = FALSE;
784                 }
785                 else {
786                         /* Your camera model does not need unlocking, cannot do unlocking or
787                          * we don't know how to unlock its keys.
788                          */
789                         GP_DEBUG ("canon_usb_unlock_keys: Key unlocking not implemented for this camera model. "
790                                   "If unlocking works when using the Windows software with your camera, "
791                                   "please contact %s.", MAIL_GPHOTO_DEVEL);
792                 }
793 
794         return GP_OK;
795 }
796 
797 /**
798  * canon_usb_get_body_id:
799  * @camera: camera to query
800  * @context: context for error reporting
801  *
802  * Gets the body ID (hardware serial number) from an EOS camera.
803  *
804  * Returns: body ID (hardware serial number of camera) or gphoto2
805  *          error code.
806  *
807  */
808 static int
canon_usb_get_body_id(Camera * camera,GPContext * context)809 canon_usb_get_body_id (Camera *camera, GPContext *context)
810 {
811         unsigned char *c_res;
812         unsigned int bytes_read;
813 
814         GP_DEBUG ("canon_usb_get_body_id()");
815 
816         switch ( camera->pl->md->model ) {
817         case CANON_CLASS_4:
818                 c_res = canon_usb_dialogue (camera, CANON_USB_FUNCTION_EOS_GET_BODY_ID,
819                                             &bytes_read, NULL, 0);
820                 if ( c_res == NULL )
821                         return GP_ERROR_OS_FAILURE;
822                 else if (bytes_read == 0x8) {
823                         int body_id = le32atoh ( c_res+0x4 );
824                         GP_DEBUG ("canon_usb_get_body_id: Got the expected length back.");
825                         if ( camera->pl->md->usb_product == 0x3044 )
826                                 /* EOS D30 is a special case */
827                                 GP_DEBUG ("canon_usb_get_body_id: body ID is %04x%05d", (body_id>>16)&0xffff, body_id&0xffff );
828                         else
829                                 GP_DEBUG ("canon_usb_get_body_id: body ID is %u", body_id );
830                         camera->pl->body_id = body_id;
831                         return GP_OK;
832                 } else {
833                         gp_context_error (context,
834                                           _("canon_usb_get_body_id: "
835                                             "Unexpected data length returned (%i bytes, expected %i)"),
836                                           bytes_read, 0x58);
837                         return GP_ERROR_CORRUPTED_DATA;
838                 }
839                 break;
840         case CANON_CLASS_6:
841                 c_res = canon_usb_dialogue (camera, CANON_USB_FUNCTION_EOS_GET_BODY_ID_2,
842                                             &bytes_read, NULL, 0);
843                 if ( c_res == NULL )
844                         return GP_ERROR_OS_FAILURE;
845                 else if (bytes_read == 0x8) {
846                         unsigned int body_id = le32atoh ( c_res+0x4 );
847                         GP_DEBUG ("canon_usb_get_body_id: Got the expected length back.");
848                         GP_DEBUG ("canon_usb_get_body_id: body ID is %010u", body_id );
849                         camera->pl->body_id = body_id;
850                         return GP_OK;
851                 } else {
852                         gp_context_error (context,
853                                           _("canon_usb_get_body_id: "
854                                             "Unexpected data length returned (%i bytes, expected %i)"),
855                                           bytes_read, 0x58);
856                         return GP_ERROR_CORRUPTED_DATA;
857                 }
858                 break;
859         default:
860                 /* As far as we know, only EOS models implement the "get body ID" function. */
861                 GP_DEBUG ("canon_usb_get_body_id: \"Get body ID\" not implemented for this camera model. "
862                           "If the Windows software can read a body ID (hardware serial number) from your camera, "
863                           "please contact %s.", MAIL_GPHOTO_DEVEL);
864                 break;
865         }
866 
867         return GP_OK;
868 }
869 
870 /**
871  * canon_usb_poll_interrupt_pipe:
872  * @camera: the Camera to work with
873  * @buf: buffer to receive data read from the pipe.
874  * @timeout: time in 1/1000 of a second
875  *
876  * Reads the interrupt pipe repeatedly until either
877  * 1. a non-zero length is returned,
878  * 2. an error code is returned, or
879  * 3. the timeout is reached
880  *
881  * Returns:
882  *  length of read, or
883  *  zero if the timeout is reached
884  *  gphoto2 error code from read that results in an I/O error.
885  *
886  */
canon_usb_poll_interrupt_pipe(Camera * camera,unsigned char * buf,unsigned int timeout)887 static int canon_usb_poll_interrupt_pipe ( Camera *camera, unsigned char *buf, unsigned int timeout )
888 {
889         int i = 0, status = 0, oldtimeout;
890         struct timeval start, end, cur;
891         double duration;
892 
893         memset ( buf, 0x81, 0x40 ); /* Put weird stuff in buffer */
894 
895 	gp_port_get_timeout ( camera->port, &oldtimeout );
896 	gp_port_set_timeout ( camera->port, CANON_FAST_TIMEOUT );
897 
898         /* Read repeatedly until we get either an
899            error, a non-zero size or hit the timeout. */
900         gettimeofday ( &start, NULL );
901 	while (1) {
902 		unsigned long curduration;
903 
904 		i++;
905                 status = gp_port_check_int ( camera->port, (char *)buf, 0x40 );
906                 /* Either some real data, or failure */
907                 if ( status != 0 && status != GP_ERROR_TIMEOUT)
908                         break;
909         	gettimeofday ( &cur, NULL );
910 		curduration =	(cur.tv_sec-start.tv_sec)*1000 +
911 				(cur.tv_usec-start.tv_usec)/1000;
912 		if (curduration >= timeout) {
913 			/* Timeout is not an error */
914 			status = 0;
915 			break;
916 		}
917         }
918         gettimeofday ( &end, NULL );
919 
920 	gp_port_set_timeout ( camera->port, oldtimeout );
921 
922         duration  =   (double)end.tv_sec +   end.tv_usec/1e6;
923         duration -= (double)start.tv_sec + start.tv_usec/1e6;
924         if ( status <= 0 )
925                 GP_DEBUG ( "canon_usb_poll_interrupt_pipe:"
926 			   " interrupt read failed after %i tries, %6.3f sec \"%s\"",
927                            i, duration, gp_result_as_string(status) );
928         else
929                 GP_DEBUG ( "canon_usb_poll_interrupt_pipe:"
930                            " interrupt packet took %d tries, %6.3f sec",
931                            i+1, duration );
932 
933         return status;
934 }
935 
936 
937 int
canon_usb_wait_for_event(Camera * camera,int timeout,CameraEventType * eventtype,void ** eventdata,GPContext * context)938 canon_usb_wait_for_event (Camera *camera, int timeout,
939 		CameraEventType *eventtype, void **eventdata,
940 		GPContext *context)
941 {
942         unsigned char buf2[0x40]; /* for reading from interrupt endpoint */
943 	unsigned char *final_state = NULL; /* For comparing
944 					     * before/after
945 					     * directories */
946 	unsigned int directory_state_len, final_state_len;
947         int status = GP_OK;
948 
949 	if (!camera->pl->directory_state)
950 		status = canon_usb_list_all_dirs ( camera, &camera->pl->directory_state, &directory_state_len, context );
951 	if (status < GP_OK) {
952 		GP_DEBUG ("canon_usb_wait_for_event: status %d", status);
953 		return status;
954 	}
955 
956 	*eventtype = GP_EVENT_TIMEOUT;
957 	*eventdata = NULL;
958 	status = canon_usb_poll_interrupt_pipe ( camera, buf2, timeout );
959 	GP_DEBUG ("canon_usb_wait_for_event: status %d", status);
960 	if (status <= GP_OK)
961 		return status;
962 	*eventtype = GP_EVENT_UNKNOWN;
963 	GP_DEBUG ("canon_usb_wait_for_event: bytes %x %x %x %x %x", buf2[0],buf2[1],buf2[2],buf2[3],buf2[4]);
964 	switch (buf2[4]) {
965 	case 0x0e: {
966 		CameraFilePath *path;
967 		*eventtype = GP_EVENT_FILE_ADDED;
968 		*eventdata = path = malloc(sizeof(CameraFilePath));
969 		status = canon_usb_list_all_dirs ( camera, &final_state, &final_state_len, context );
970 		if (status < GP_OK)
971 			return status;
972 		/* Find new file name in camera directory */
973 		canon_int_find_new_image ( camera, camera->pl->directory_state, final_state, path );
974 		if (path->folder[0] != '/') {
975 			free (path);
976 			*eventtype = GP_EVENT_UNKNOWN;
977 			*eventdata = malloc(strlen("Failed to get added filename?")+1);
978 			strcpy (*eventdata, "Failed to get added filename?");
979 		}
980 		free ( camera->pl->directory_state );
981 		camera->pl->directory_state = final_state;
982 		return GP_OK;
983 	}
984 	default:
985 		*eventtype = GP_EVENT_UNKNOWN;
986 		*eventdata = malloc(strlen("Unknown CANON event 0x01 0x02 0x03 0x04 0x05")+1);
987 		sprintf (*eventdata,"Unknown CANON event 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",buf2[0],buf2[1],buf2[2],buf2[3],buf2[4]);
988 		return GP_OK;
989 	}
990 	return GP_OK;
991 }
992 /**
993  * canon_usb_capture_dialogue:
994  * @camera: the Camera to work with
995  * @return_length: number of bytes to read from the camera as response
996  * @photo_status: a pointer to an int that returns a photographic status
997  *                error codes from the camera (if any) if this function
998  *                returns NULL
999  * @context: context for error reporting
1000  *
1001  * Handles the "capture image" command, where we must read the
1002  *  interrupt pipe before getting the normal command response.
1003  *
1004  * We call canon_usb_dialogue() for the actual "release shutter"
1005  *  command, then handle the interrupt pipe here.
1006  *
1007  * Returns: a char * that points to the data read from the camera (or
1008  * NULL on failure), and sets what @return_length points to the number
1009  * of bytes read. If this function returns NULL, return any photographic
1010  * failure error codes in what @photo_status points to.
1011  *
1012  */
1013 unsigned char *
canon_usb_capture_dialogue(Camera * camera,unsigned int * return_length,int * photo_status,GPContext * context)1014 canon_usb_capture_dialogue (Camera *camera, unsigned int *return_length, int *photo_status, GPContext *context )
1015 {
1016         int status;
1017         unsigned char payload[9]; /* used for sending data to camera */
1018         static unsigned char *buffer; /* used for receiving data from camera */
1019         unsigned char buf2[0x40]; /* for reading from interrupt endpoint */
1020 
1021         int mstimeout = -1;                  /* To save original timeout after shutter release */
1022 
1023         /* clear this to indicate that no data is there if we abort */
1024         if (return_length)
1025                 *return_length = 0;
1026 
1027 	/* for later wait_event */
1028 	if (!camera->pl->directory_state) {
1029 		unsigned int directory_state_len;
1030 
1031 		status = canon_usb_list_all_dirs ( camera, &camera->pl->directory_state, &directory_state_len, context );
1032 	}
1033 
1034         GP_DEBUG ("canon_usb_capture_dialogue()");
1035 
1036 	*photo_status = 0; /* This should only be checked by the caller
1037 			      if canon_usb_capture_dialogue() returns null */
1038 
1039         /* Build payload for command, which contains subfunction code */
1040         memset (payload, 0x00, sizeof (payload));
1041         payload[0] = 4;
1042 
1043 
1044         /* First, let's try to make sure the interrupt pipe is clean. */
1045         while ( (status = canon_usb_poll_interrupt_pipe ( camera, buf2, CANON_FAST_TIMEOUT )) > 0 );
1046 
1047         /* Shutter release can take a long time sometimes on EOS
1048          * cameras; perhaps buffer is full and needs to be flushed? */
1049         gp_port_get_timeout (camera->port, &mstimeout);
1050         GP_DEBUG("canon_usb_capture_dialogue: usb port timeout starts at %dms", mstimeout);
1051         gp_port_set_timeout (camera->port, 15000);
1052 
1053         /* now send the packet to the camera */
1054         if ( camera->pl->md->model != CANON_CLASS_6 )
1055                 buffer = canon_usb_dialogue ( camera, CANON_USB_FUNCTION_CONTROL_CAMERA,
1056                                               return_length,
1057                                               payload, 8 );
1058         else {
1059                 buffer = canon_usb_dialogue ( camera, CANON_USB_FUNCTION_CONTROL_CAMERA_2,
1060                                               return_length,
1061                                               payload, 9 );
1062         }
1063 
1064         if ( buffer == NULL )
1065                 return NULL;
1066 
1067         gp_port_set_timeout (camera->port, mstimeout);
1068         GP_DEBUG("canon_usb_capture_dialogue:"
1069                  " set camera port timeout back to %d seconds...", mstimeout / 1000 );
1070 
1071         /* Check the status code from the camera. */
1072         if ( le32atoh ( buffer ) != 0 ) {
1073                 GP_DEBUG ( "canon_usb_capture_dialogue:"
1074                            " got nonzero camera status code"
1075                            " %08x in response to capture command", le32atoh ( buffer ) );
1076                 goto FAIL;
1077         }
1078 
1079 	if ( camera->pl->md->model == CANON_CLASS_6 ) {
1080 		/* Don't know what this command does, but the Windows
1081 		 * software issues it here. */
1082 		htole32a ( payload, 0x0f );
1083 		GP_DEBUG ( "canon_usb_capture_dialogue: Issuing unknown command 0x22 for class 6 camera." );
1084                 buffer = canon_usb_dialogue ( camera,
1085 					      CANON_USB_FUNCTION_20D_UNKNOWN_2,
1086 					      return_length, payload, 4 );
1087 
1088                 if ( buffer == NULL )
1089                         GP_DEBUG ( "canon_usb_capture_dialogue: Unknown command 0x22 returned null buffer; continuing anyway." );
1090 		else if ( *return_length != 0x4 )
1091                         GP_DEBUG ( "canon_usb_capture_dialogue: Unknown command 0x22 returned buffer of unexpected size 0x%x; continuing anyway.",
1092 				   *return_length );
1093 		else if ( le32atoh ( buffer+0x50 ) != 0 )
1094                         GP_DEBUG ( "canon_usb_capture_dialogue: Unknown command 0x22 returned status code 0x%x; continuing anyway.",
1095 				   le32atoh ( buffer+0x50 ) );
1096 	}
1097         /* Now we need to read from the interrupt pipe. Since we have
1098            to use the short timeout (50 ms), we need to try several
1099            times.
1100            Read until we have completion signaled (0x0a for PowerShot,
1101            0x0f for EOS, 0x0e for newer EOS) */
1102         camera->pl->capture_step = 0;
1103         camera->pl->thumb_length = 0; camera->pl->image_length = 0;
1104         camera->pl->image_key = 0x81818181;
1105 
1106         while ( buf2[4] != 0x0f ) {
1107 		/* Give the camera a long time ... (even covering bulb exposures) */
1108                 status = canon_usb_poll_interrupt_pipe ( camera, buf2, MAX_INTERRUPT_TRIES*CANON_FAST_TIMEOUT );
1109                 if ( status > 0x17 )
1110                         GP_DEBUG ( "canon_usb_capture_dialogue:"
1111                                    " interrupt read too long (length=%i)", status );
1112                 else if (  status <= 0 )
1113                         goto FAIL;
1114 
1115                 switch ( buf2[4] ) {
1116                 case 0x08:
1117                         /* Thumbnail size */
1118                         if ( status != 0x17 )
1119                                 gp_log (GP_LOG_ERROR, "canon/usb.c",
1120 					"canon_usb_capture_dialogue:"
1121 					  " bogus length 0x%04x"
1122 					  " for thumbnail size packet", status );
1123                         camera->pl->thumb_length = le32atoh ( buf2+0x11 );
1124                         camera->pl->image_key = le32atoh ( buf2+0x0c );
1125                         GP_DEBUG ( "canon_usb_capture_dialogue: thumbnail size %ld, tag=0x%08lx",
1126                                    camera->pl->thumb_length, camera->pl->image_key );
1127 			camera->pl->transfer_mode &= ~REMOTE_CAPTURE_THUMB_TO_PC;
1128 			/* Special case for class 6 (newer protocol) and the EOS 300D */
1129 			if ( camera->pl->transfer_mode == 0
1130 			     && ( camera->pl->md->model == CANON_CLASS_6 || camera->pl->md->usb_product == 0x3084 ) )
1131 				goto EXIT;
1132                         break;
1133                 case 0x0c:
1134                         /* Full image size */
1135                         if ( status != 0x17 )
1136                                 gp_log (GP_LOG_ERROR, "canon/usb.c",
1137 					"canon_usb_capture_dialogue:"
1138 					  " bogus length 0x%04x"
1139 					  " for full image size packet", status );
1140                         camera->pl->image_length = le32atoh ( buf2+0x11 );
1141                         camera->pl->image_key = le32atoh ( buf2+0x0c );
1142                         GP_DEBUG ( "canon_usb_capture_dialogue: full image size: 0x%08lx, tag=0x%08lx",
1143                                    camera->pl->image_length, camera->pl->image_key );
1144 			camera->pl->transfer_mode &= ~REMOTE_CAPTURE_FULL_TO_PC;
1145 			/* Special case for class 6 (newer protocol) and the EOS 300D */
1146 			if (!camera->pl->secondary_image &&
1147 			    camera->pl->transfer_mode == 0
1148 			     && ( camera->pl->md->model == CANON_CLASS_6 || camera->pl->md->usb_product == 0x3084 ) )
1149 				goto EXIT;
1150 
1151                         break;
1152 		case 0x10:
1153                         /* Secondary image size, key */
1154 			/* (only for RAW + JPEG modes) */
1155 			GP_DEBUG ( "canon_usb_capture_dialogue: "
1156 				   "secondary image descriptor received");
1157 
1158 			camera->pl->image_b_length = le32atoh ( buf2+0x11 );
1159 			camera->pl->image_b_key = le32atoh ( buf2+0x0c );
1160 
1161 			GP_DEBUG ( "canon_usb_capture_dialogue: secondary image size: 0x%08lx, tag=0x%08lx",
1162 				   camera->pl->image_b_length, camera->pl->image_b_key);
1163 			camera->pl->transfer_mode &= ~REMOTE_CAPTURE_FULL_TO_PC;
1164 			/* Special case for class 6 (newer protocol) and the EOS 300D */
1165 			if ( camera->pl->transfer_mode == 0
1166 			     && ( camera->pl->md->model == CANON_CLASS_6 || camera->pl->md->usb_product == 0x3084 ) )
1167 				goto EXIT;
1168                         break;
1169 		case 0x0a:
1170                         if ( buf2[12] == 0x1c ) {
1171                                 GP_DEBUG ( "canon_usb_capture_dialogue: first interrupt read" );
1172                                 if ( camera->pl->capture_step == 0 )
1173                                         camera->pl->capture_step++;
1174                                 else if ( camera->pl->capture_step == 2 ) {
1175                                         /* I think this may be a signal that this is the last shot
1176                                            that will fit on the CF card. */
1177                                         GP_DEBUG ( "canon_usb_capture_dialogue: redundant \"1c\" code; full CF card?" );
1178                                         camera->pl->capture_step = 1;
1179                                 }
1180                                 else {
1181                                         gp_log (GP_LOG_ERROR, "canon/usb.c",
1182 						"canon_usb_capture_dialogue:"
1183 						  " first interrupt read out of sequence");
1184                                         goto FAIL;
1185                                 }
1186                         }
1187                         else if ( buf2[12] == 0x1d ) {
1188                                 GP_DEBUG ( "canon_usb_capture_dialogue: second interrupt read (after image sizes)" );
1189                                 if ( camera->pl->capture_step != 1 ) {
1190                                         gp_log (GP_LOG_ERROR, "canon/usb.c",
1191 						"canon_usb_capture_dialogue:"
1192 						  " second interrupt read out of sequence");
1193                                         goto FAIL;
1194                                 }
1195                                 camera->pl->capture_step++;
1196                                 /* PowerShot cameras end with this message */
1197                                 if ( camera->pl->md->model != CANON_CLASS_4 )
1198                                         goto EXIT;
1199                         }
1200                         else if ( buf2[12] == 0x0a ) {
1201                                 gp_log (GP_LOG_ERROR, "canon/usb.c",
1202 					"canon_usb_capture_dialogue:"
1203 					  " photographic failure signaled, code = 0x%08x",
1204                                          le32atoh ( buf2+16 ) );
1205 				*photo_status = le32atoh ( buf2+16 );
1206                                 goto FAIL2;
1207                         }
1208                         else {
1209                                 GP_DEBUG ( "canon_usb_capture_dialogue: unknown subcode 0x%08x in 0x0a interrupt read",
1210                                            le32atoh ( buf2+12 ) );
1211                         }
1212                         break;
1213                 case 0x0e:
1214                         /* The image has been written to local
1215                          * storage. Never seen if the transfer
1216                          * mode didn't include any local
1217                          * storage. */
1218                         GP_DEBUG ( "canon_usb_capture_dialogue:"
1219                                    " EOS flash write complete from interrupt read" );
1220                         if ( camera->pl->capture_step != 2 && camera->pl->md->model != CANON_CLASS_6 ) {
1221                                 gp_log (GP_LOG_ERROR, "canon/usb.c",
1222 					"canon_usb_capture_dialogue:"
1223 					  " third EOS interrupt read out of sequence");
1224                                 goto FAIL;
1225                         }
1226                         camera->pl->capture_step++;
1227                         /* Canon SDK unlocks the keys here for EOS cameras. */
1228                         if ( canon_usb_unlock_keys ( camera, context ) < 0 ) {
1229                                 GP_DEBUG ( "canon_usb_capture_dialogue: couldn't unlock keys after capture, ignoring." );
1230                                 /* goto FAIL; ... known to not work on EOS 10D and 20D. -Marcus */
1231                         }
1232 			camera->pl->transfer_mode &= ~(REMOTE_CAPTURE_THUMB_TO_DRIVE|REMOTE_CAPTURE_FULL_TO_DRIVE);
1233 			/* Special case for class 6 (newer protocol) and the EOS 300D */
1234 			if (	camera->pl->md->model == CANON_CLASS_6 ||
1235 				camera->pl->md->usb_product == 0x3083 ||/* EOS 10D */
1236 				camera->pl->md->usb_product == 0x3084 	/* EOS 300D */
1237 			) {
1238 				GP_DEBUG ( "canon_usb_capture_dialogue:"
1239 					   " final interrupt read at step %i", camera->pl->capture_step );
1240 				goto EXIT;
1241                         }
1242 
1243                         break;
1244                 case 0x0f:
1245                         /* We allow this message as third or
1246                          * fourth, since we may or may not be
1247                          * writing to camera storage. */
1248                         if ( camera->pl->capture_step == 2 ) {
1249                                 /* Keys were never unlocked, as that message never came. */
1250                                 if ( canon_usb_unlock_keys ( camera, context ) < 0 ) {
1251                                         GP_DEBUG ( "canon_usb_capture_dialogue: couldn't unlock keys after capture." );
1252                                         goto FAIL;
1253                                 }
1254                         }
1255                         else if ( camera->pl->capture_step == 3 ) {
1256                                 GP_DEBUG ( "canon_usb_capture_dialogue:"
1257                                            " final EOS interrupt read" );
1258                         }
1259                         else {
1260                                 gp_log (GP_LOG_ERROR, "canon/usb.c",
1261 					"canon_usb_capture_dialogue:"
1262 					  " fourth EOS interrupt read out of sequence");
1263                                 goto FAIL;
1264                         }
1265                         break;
1266                 default:
1267                         /* Unknown */
1268                         GP_DEBUG ( "canon_usb_capture_dialogue:"
1269                                    " unknown code 0x%02x in interrupt read",
1270                                    buf2[4] );
1271                         goto FAIL;
1272                 }
1273         }
1274 
1275 EXIT:
1276         *return_length = 0x1c;
1277         return buffer;
1278 FAIL:  /* Try to purge interrupt pipe, which was left in an unknown state. */
1279         status = canon_usb_poll_interrupt_pipe ( camera, buf2, 1000 );
1280 FAIL2:	/* After "photographic error" is signaled, we know pipe is clean. */
1281         canon_usb_unlock_keys ( camera, context );    /* Ignore status code, as we can't fix it anyway. */
1282         return NULL;
1283 }
1284 
1285 /**
1286  * canon_usb_decode_status
1287  * @code: status code returned in offset 0x50 in the response
1288  *
1289  * Returns: a string with the error message, or NUL if status is OK.
1290  */
canon_usb_decode_status(int code)1291 static char *canon_usb_decode_status ( int code ) {
1292         unsigned int i;
1293         static char message[100];
1294 
1295         for ( i=0;
1296               i<sizeof(canon_usb_status_table)/sizeof(struct canon_usb_status);
1297               i++ )
1298                 if ( canon_usb_status_table[i].code == code )
1299                         return canon_usb_status_table[i].message;
1300 
1301         sprintf ( message, "Unknown status code 0x%08x from camera", code );
1302         return message;
1303 }
1304 
1305 /**
1306  * canon_usb_dialogue_full:
1307  * @camera: the Camera to work with
1308  * @canon_funct: integer constant that identifies function we are execute
1309  * @return_length: number of bytes to read from the camera as response
1310  * @payload: data we are to send to the camera
1311  * @payload_length: length of #payload
1312  *
1313  * USB version of the #canon_serial_dialogue function.
1314  *
1315  * We construct a packet with the known command values (cmd{1,2,3}) of
1316  * the function requested (#canon_funct) to the camera. If #return_length
1317  * exists for this function, we read #return_length bytes back from the
1318  * camera and return this camera response to the caller.
1319  *
1320  * Example :
1321  *
1322  *      This function gets called with
1323  *              #canon_funct = %CANON_USB_FUNCTION_SET_TIME
1324  *              #payload = already constructed payload with the new time
1325  *      we construct a complete command packet and send this to the camera.
1326  *      The canon_usb_cmdstruct indicates that command
1327  *      CANON_USB_FUNCTION_SET_TIME returns four bytes, so we read those
1328  *      four bytes into our buffer and return a pointer to the buffer to
1329  *      the caller.
1330  *
1331  *      This should probably be changed so that the caller supplies a
1332  *      unsigned char ** which can be pointed to our buffer and an int
1333  *      returned with GP_OK or some error code.
1334  *
1335  * Returns: a char * that points to all of the packet data read from
1336  * the camera (or NULL on failure), and sets what @return_length
1337  * points to the number of bytes read.  Note that, unlike this
1338  * function, canon_usb_dialogue() chops off the first 0x50 bytes to
1339  * generate its output.
1340  *
1341  */
1342 unsigned char *
canon_usb_dialogue_full(Camera * camera,canonCommandIndex canon_funct,unsigned int * return_length,const unsigned char * payload,unsigned int payload_length)1343 canon_usb_dialogue_full (Camera *camera, canonCommandIndex canon_funct, unsigned int *return_length, const unsigned char *payload,
1344                     unsigned int payload_length)
1345 {
1346         int msgsize, status, i;
1347         char cmd1 = 0, cmd2 = 0, *funct_descr = "";
1348         int cmd3 = 0, read_bytes1 = 0, read_bytes2 = 0;
1349 	unsigned int read_bytes = 0;
1350         unsigned char packet[1024];     /* used for sending data to camera */
1351         static unsigned char buffer[0x474];     /* used for receiving data from camera */
1352 	char *msg;
1353         int j, canon_subfunc = 0;
1354         int additional_read_bytes = 0;
1355 
1356         /* clear this to indicate that no data is there if we abort */
1357         if (return_length)
1358                 *return_length = 0;
1359 
1360         /* clearing the receive buffer could be done right before the gp_port_read()
1361          * but by clearing it here we eliminate the possibility that a caller thinks
1362          * data in this buffer is a result of this particular canon_usb_dialogue() call
1363          * if we return error but this is not checked for... good or bad I don't know.
1364          */
1365         memset (buffer, 0x00, sizeof (buffer));
1366 
1367         /* search through the list of known canon commands (canon_usb_cmd)
1368          * and look for parameters to be used for function 'canon_funct'
1369          */
1370         i = 0;
1371         while (canon_usb_cmd[i].num != 0) {
1372                 if (canon_usb_cmd[i].num == canon_funct) {
1373                         funct_descr = canon_usb_cmd[i].description;
1374                         cmd1 = canon_usb_cmd[i].cmd1;
1375                         cmd2 = canon_usb_cmd[i].cmd2;
1376                         cmd3 = canon_usb_cmd[i].cmd3;
1377                         read_bytes = canon_usb_cmd[i].return_length;
1378                         break;
1379                 }
1380                 i++;
1381         }
1382         if (canon_usb_cmd[i].num == 0) {
1383                 GP_DEBUG ("canon_usb_dialogue_full() called for ILLEGAL function %i! Aborting.",
1384                           canon_funct);
1385                 return NULL;
1386         }
1387         GP_DEBUG ("canon_usb_dialogue_full() cmd 0x%x 0x%x 0x%x (%s)", cmd1, cmd2, cmd3,
1388                   funct_descr);
1389 
1390         /*
1391          * The CONTROL_CAMERA function is special in that its payload specifies a
1392          * subcommand, and the size of the return data is dependent on which
1393          * subcommand we're sending the camera.  See "Protocol" file for details.
1394          */
1395         if ( ( camera->pl->md->model != CANON_CLASS_6
1396                && canon_usb_cmd[i].num == CANON_USB_FUNCTION_CONTROL_CAMERA )
1397              || ( camera->pl->md->model == CANON_CLASS_6
1398 		  && canon_usb_cmd[i].num == CANON_USB_FUNCTION_CONTROL_CAMERA_2 ) ) {
1399                 canon_subfunc = le32atoh (payload);
1400                 j = 0;
1401                 while (canon_usb_control_cmd[j].num != 0) {
1402                         if (canon_usb_control_cmd[j].subcmd == canon_subfunc) {
1403                                 additional_read_bytes = canon_usb_control_cmd[j].additional_return_length;
1404                                 break;
1405                         }
1406                         j++;
1407                 }
1408                 if (canon_usb_control_cmd[j].num == 0) {
1409                         GP_DEBUG("canon_usb_dialogue_full(): CONTROL_CAMERA called for ILLEGAL "
1410                                  "sub function %i! Aborting.", canon_subfunc);
1411                         return NULL;
1412                 }
1413                 read_bytes += additional_read_bytes;
1414 
1415                 GP_DEBUG ("canon_usb_dialogue_full() called with CONTROL_CAMERA, %s",
1416                           canon_usb_control_cmd[j].description);
1417 		if ( !strcmp ( "Set transfer mode", canon_usb_control_cmd[j].description ) ) {
1418 			/* We need to remember the transfer mode, as with
1419 			 * newer cameras it changes capture
1420 			 * completion. */
1421 			camera->pl->transfer_mode = payload[8];
1422 			GP_DEBUG ( "canon_usb_dialogue_full() setting transfer mode to %d",
1423 				   camera->pl->transfer_mode );
1424 		}
1425         }
1426 
1427         if (read_bytes > sizeof (buffer)) {
1428                 /* If this message is ever printed, chances are that you just added
1429                  * a new command to canon_usb_cmd with a return_length greater than
1430                  * all the others and did not update the declaration of 'buffer' in
1431                  * this function.
1432                  */
1433                 GP_DEBUG ("canon_usb_dialogue_full() "
1434                           "read_bytes %i won't fit in buffer of size %li!", read_bytes,
1435                           (long)sizeof (buffer));
1436                 return NULL;
1437         }
1438 
1439         if (payload_length)
1440                 GP_LOG_DATA ((char *)payload, (long)payload_length, "Payload:");
1441 
1442         if ((payload_length + 0x50) > sizeof (packet)) {
1443                 gp_log (GP_LOG_DEBUG, "canon/usb.c",
1444                         "canon_usb_dialogue:"
1445 			  " payload too big, won't fit into buffer (%i > %i)",
1446                         (payload_length + 0x50), (int)sizeof (packet));
1447                 return NULL;
1448         }
1449 
1450         /* OK, we have now checked for all errors I could think of,
1451          * proceed with the actual work.
1452          */
1453 
1454         /* construct packet to send to camera, including the three
1455          * commands, serial number and a payload if one has been supplied
1456          */
1457 
1458         memset (packet, 0x00, sizeof (packet)); /* zero block */
1459         htole32a (packet, 0x10 + payload_length);
1460         packet[0x40] = 0x2;
1461         packet[0x44] = cmd1;
1462         packet[0x47] = cmd2;
1463         htole32a (packet + 0x04, cmd3);
1464         if ( camera->pl->md->model == CANON_CLASS_6 ) {
1465                 /* New style of protocol is picky about this byte. */
1466                 if ( cmd3 == 0x202 )
1467                         packet[0x46] = 0x20;
1468                 else
1469                         packet[0x46] = 0x10;
1470         }
1471 
1472         htole32a (packet + 0x4c, serial_code++);        /* serial number */
1473         htole32a (packet + 0x48, 0x10 + payload_length);
1474         msgsize = 0x50 + payload_length;        /* TOTAL msg size */
1475 
1476         if (payload_length > 0)
1477                 memcpy (packet + 0x50, payload, payload_length);
1478 
1479         /* now send the packet to the camera */
1480         status = gp_port_usb_msg_write (camera->port, msgsize > 1 ? 0x04 : 0x0c, 0x10, 0,
1481                                         (char *)packet, msgsize);
1482         if (status != msgsize) {
1483                 GP_DEBUG ("canon_usb_dialogue_full: write failed! (returned %i)", status);
1484                 return NULL;
1485         }
1486 
1487         /* and, if this canon_funct is known to generate a response from the camera,
1488          * read this response back.
1489          */
1490 
1491         /* Even the new cameras use multiple reads sometimes,
1492          * e.g. "Get camera abilities". */
1493         if ( camera->pl->md->model != CANON_CLASS_6 && read_bytes <= 0x400 ) {
1494                 /*
1495                  * Divide read_bytes into two parts.
1496                  *
1497                  * - The first read is for the length rounded down to a length
1498                  *   divisible by 0x40. The 32 bits starting at the beginning
1499                  *   of the buffer may contain the length information; if not,
1500                  *   the 32 bits starting at offset 0x48 will contain the
1501                  *   length information, which we check against the expected
1502                  *   length and log a warning if the two do not agree. We then
1503                  *   read the rest of the data, if any, in a single chunk.
1504                  *
1505                  * - The final read is for the remainder of the data. This
1506                  *   can never be longer than 0x37 bytes.
1507                  *
1508                  * Read two is optional. If the requested length is only
1509                  * 0x40, only the first read will be issued.  If the length is
1510                  * divisible by 0x40, the second read will be skipped.
1511                  *
1512                  * We read like this because the Windows driver reads in two
1513                  * operations, and some cameras (EOS D30 for example) seem to
1514                  * not like it if we were to read read_bytes in a single read
1515                  * instead.
1516                  *
1517                  * We check the size a safety measure: if we are mistaken
1518                  * about the length of data returned for some command, we can
1519                  * work around it with just a warning. The "get camera
1520                  * abilities" command, in particular, seems to vary from
1521                  * camera to camera.
1522                  */
1523                 read_bytes1 = read_bytes - (read_bytes % 0x40);
1524                 status = gp_port_read (camera->port, (char *)buffer, read_bytes1);
1525                 if (status != read_bytes1) {
1526                         if ( status >= 0 )
1527                                 GP_DEBUG ("canon_usb_dialogue_full: read 1 of 0x%x bytes failed! (returned %i)",
1528                                           read_bytes1, status);
1529                         else                         /* Error code */
1530                                 GP_DEBUG ("canon_usb_dialogue_full: read 1 of 0x%x bytes failed! (%s)",
1531                                           read_bytes1, gp_result_as_string ( status ) );
1532                         return NULL;
1533                 }
1534 
1535                 if ( cmd3 != 0x202 ) {
1536                         unsigned int reported_length = le32atoh (buffer);
1537                         if ( reported_length == 0 ) {
1538                                 /* No length at start of packet. Did we read enough to
1539                                  * see the length later on? */
1540                                 GP_DEBUG ( "canon_usb_dialogue_full: no length at start of packet." );
1541                                 if ( read_bytes1 >= 0x50 ) {
1542                                         reported_length = le32atoh (buffer+0x48);
1543                                         GP_DEBUG ( "canon_usb_dialogue_full: got length from offset 0x48." );
1544                                 }
1545                         }
1546                         GP_DEBUG ("canon_usb_dialogue_full: camera reports 0x%x bytes (0x%x total)",
1547                                   reported_length, reported_length+0x40 );
1548 
1549                         if ( reported_length > 0 && reported_length+0x40 != read_bytes ) {
1550                                 gp_log (GP_LOG_DEBUG, "canon/usb.c",
1551 					"canon_usb_dialogue:"
1552 					  " expected 0x%x bytes, but camera reports 0x%x",
1553                                          read_bytes, reported_length+0x40 );
1554                                 read_bytes = reported_length+0x40;
1555                         }
1556                 }
1557 
1558                 read_bytes2 = read_bytes - read_bytes1;
1559 
1560                 if ( read_bytes2 > 0 ) {
1561                         status = gp_port_read (camera->port, (char *)buffer + read_bytes1, read_bytes2);
1562                         if (status != read_bytes2) {
1563                                 if ( status >= 0 )
1564                                         GP_DEBUG ("canon_usb_dialogue_full: read 2 of %i bytes failed! (returned %i)",
1565                                                   read_bytes2, status);
1566                                 else                         /* Error code */
1567                                         GP_DEBUG ("canon_usb_dialogue_full: read 2 of %i bytes failed! (%s)",
1568                                                   read_bytes2, gp_result_as_string ( status ) );
1569                                 return NULL;
1570                         }
1571                 }
1572         }
1573         else {
1574                 /* Newer protocol: these cameras allow (and some
1575                  * demand) the host software to read the entire
1576                  * response in one operation. */
1577                 status = gp_port_read (camera->port, (char *)buffer, read_bytes );
1578                 if ( status != (int)read_bytes ) {
1579                         if ( status >= 0 )
1580                                 GP_DEBUG ("canon_usb_dialogue_full: single read of %i bytes failed! (returned %i)",
1581                                           read_bytes, status);
1582                         else                         /* Error code */
1583                                 GP_DEBUG ("canon_usb_dialogue_full: single read of %i bytes failed! (%s)",
1584                                           read_bytes, gp_result_as_string ( status ) );
1585                         return NULL;
1586                 }
1587         }
1588 
1589                 msg = canon_usb_decode_status ( le32atoh ( buffer+0x50 ) );
1590                 if ( msg != NULL ) {
1591                         GP_DEBUG ( "canon_usb_dialogue_full: camera status \"%s\""
1592 				   " in response to command 0x%x 0x%x 0x%x (%s)",
1593 				   msg, cmd1, cmd2, cmd3, funct_descr );
1594 			return NULL;
1595                 }
1596 
1597 	if (return_length)
1598 		*return_length = read_bytes;
1599 	return buffer;
1600         }
1601 
1602 /**
1603  * canon_usb_dialogue:
1604  * @camera: the Camera to work with
1605  * @canon_funct: integer constant that identifies function we are execute
1606  * @return_length: number of bytes to read from the camera as response
1607  * @payload: data we are to send to the camera
1608  * @payload_length: length of #payload
1609  *
1610  * USB version of the #canon_serial_dialogue function.
1611  *
1612  * We construct a packet with the known command values (cmd{1,2,3}) of
1613  * the function requested (#canon_funct) to the camera. If #return_length
1614  * exists for this function, we read #return_length bytes back from the
1615  * camera and return this camera response to the caller.
1616  *
1617  * Example :
1618  *
1619  *      This function gets called with
1620  *              #canon_funct = %CANON_USB_FUNCTION_SET_TIME
1621  *              #payload = already constructed payload with the new time
1622  *      we construct a complete command packet and send this to the camera.
1623  *      The canon_usb_cmdstruct indicates that command
1624  *      CANON_USB_FUNCTION_SET_TIME returns four bytes, so we read those
1625  *      four bytes into our buffer and return a pointer to the buffer to
1626  *      the caller.
1627  *
1628  *      This should probably be changed so that the caller supplies a
1629  *      unsigned char ** which can be pointed to our buffer and an int
1630  *      returned with GP_OK or some error code.
1631  *
1632  * Returns: a char * that points to the data read from the camera (or
1633  * NULL on failure), and sets what @return_length points to the number
1634  * of bytes read.
1635  *
1636  */
1637 unsigned char *
canon_usb_dialogue(Camera * camera,canonCommandIndex canon_funct,unsigned int * return_length,const unsigned char * payload,unsigned int payload_length)1638 canon_usb_dialogue (Camera *camera, canonCommandIndex canon_funct, unsigned int *return_length, const unsigned char *payload,
1639                     unsigned int payload_length)
1640 {
1641 	unsigned char *buffer;
1642 
1643 	buffer = canon_usb_dialogue_full (camera, canon_funct, return_length,
1644 					  payload, payload_length);
1645 
1646 	/* Remove the packet header from the response */
1647 	if (return_length)
1648 		*return_length = *return_length - 0x50;
1649 	if (buffer)
1650 		return buffer + 0x50;
1651 	else
1652 		return NULL;
1653 }
1654 
1655 
1656 /**
1657  * canon_usb_long_dialogue:
1658  * @camera: the Camera to work with
1659  * @canon_funct: integer constant that identifies function we are execute
1660  * @data: Pointer to pointer to allocated memory holding the data returned from the camera
1661  * @data_length: Pointer to where you want the number of bytes read from the camera
1662  * @max_data_size: Max realistic data size so that we can abort if something goes wrong
1663  * @payload: data we are to send to the camera
1664  * @payload_length: length of #payload
1665  * @display_status: Whether you want progress bar for this operation or not
1666  * @context: context for error reporting
1667  *
1668  * This function is used to invoke camera commands which return L (long) data.
1669  * It calls #canon_usb_dialogue(), if it gets a good response it will malloc()
1670  * memory and read the entire returned data into this malloc'd memory and store
1671  * a pointer to the malloc'd memory in 'data'.
1672  *
1673  * Returns: gphoto2 error code
1674  *
1675  */
1676 int
canon_usb_long_dialogue(Camera * camera,canonCommandIndex canon_funct,unsigned char ** data,unsigned int * data_length,unsigned int max_data_size,const unsigned char * payload,unsigned int payload_length,int display_status,GPContext * context)1677 canon_usb_long_dialogue (Camera *camera, canonCommandIndex canon_funct, unsigned char **data,
1678                          unsigned int *data_length, unsigned int max_data_size, const unsigned char *payload,
1679                          unsigned int payload_length, int display_status, GPContext *context)
1680 {
1681         int bytes_read;
1682 	unsigned int dialogue_len;
1683         unsigned int total_data_size = 0, bytes_received = 0, read_bytes = camera->pl->xfer_length;
1684         unsigned char *lpacket;         /* "length packet" */
1685         unsigned int id = 0;
1686 
1687         /* indicate there is no data if we bail out somewhere */
1688         *data_length = 0;
1689 
1690         GP_DEBUG ("canon_usb_long_dialogue() function %i, payload = %i bytes", canon_funct,
1691                   payload_length);
1692 
1693         /* Call canon_usb_dialogue_full(), this will not return any data "the usual way"
1694          * but after this we read 0x40 bytes from the USB port, the int at pos 6 in
1695          * the returned data holds the total number of bytes we are to read.
1696          */
1697         lpacket =
1698                 canon_usb_dialogue_full (camera, canon_funct, &dialogue_len, payload, payload_length);
1699         if (lpacket == NULL) {
1700                 GP_DEBUG ("canon_usb_long_dialogue: canon_usb_dialogue returned error!");
1701                 return GP_ERROR_OS_FAILURE;
1702         }
1703         /* This check should not be needed since we check the return of canon_usb_dialogue()
1704          * above, but as the saying goes: better safe than sorry.
1705          */
1706         if (dialogue_len != 0x40) {
1707                 GP_DEBUG ("canon_usb_long_dialogue: canon_usb_dialogue "
1708                           "returned %i bytes, not the length "
1709                           "we expected (%i)!. Aborting.", dialogue_len, 0x40);
1710                 return GP_ERROR_CORRUPTED_DATA;
1711         }
1712 
1713         total_data_size = le32atoh (lpacket + 0x6);
1714 
1715         if (display_status)
1716                 id = gp_context_progress_start (context, total_data_size,
1717                                                 _("Receiving data..."));
1718 
1719         if (max_data_size && (total_data_size > max_data_size)) {
1720                 GP_DEBUG ("canon_usb_long_dialogue: ERROR: Packet of size %i is too big "
1721                           "(max reasonable size specified is %i)", total_data_size,
1722                           max_data_size);
1723                 return GP_ERROR_CORRUPTED_DATA;
1724         }
1725         *data = malloc (total_data_size);
1726         if (!*data) {
1727                 GP_DEBUG ("canon_usb_long_dialogue: "
1728                           "ERROR: Could not allocate %i bytes of memory", total_data_size);
1729                 return GP_ERROR_NO_MEMORY;
1730         }
1731 
1732         bytes_received = 0;
1733         while (bytes_received < total_data_size) {
1734                 if ((total_data_size - bytes_received) > camera->pl->xfer_length )
1735                         /* Limit max transfer length */
1736                         read_bytes = camera->pl->xfer_length;
1737                 else if ((total_data_size - bytes_received) > 0x040 && camera->pl->md->model != CANON_CLASS_6 )
1738                         /* Round longer transfers down to nearest 0x40 */
1739                         read_bytes = (total_data_size - bytes_received) / 0x40 * 0x40;
1740                 else
1741                         /* Final transfer; use true length */
1742                         read_bytes = (total_data_size - bytes_received);
1743 
1744                 GP_DEBUG ("canon_usb_long_dialogue: total_data_size = %i, "
1745                           "bytes_received = %i, read_bytes = %i (0x%x)", total_data_size,
1746                           bytes_received, read_bytes, read_bytes);
1747                 bytes_read = gp_port_read (camera->port, (char *)*data + bytes_received, read_bytes);
1748                 if (bytes_read < 1) {
1749                         GP_DEBUG ("canon_usb_long_dialogue: gp_port_read() returned error (%i) or no data",
1750                                   bytes_read);
1751                         free (*data);
1752                         *data = NULL;
1753 
1754                         /* here, it is an error to get 0 bytes from gp_port_read()
1755                          * too, but 0 is GP_OK so if bytes_read is 0 return GP_ERROR_CORRUPTED_DATA
1756                          * instead, otherwise return bytes_read since that is the
1757                          * error code returned by gp_port_read()
1758                          */
1759                         if (bytes_read < 0)
1760                                 return bytes_read;
1761                         else
1762                                 return GP_ERROR_CORRUPTED_DATA;
1763                 } else if ((unsigned int)bytes_read < read_bytes)
1764                         GP_DEBUG ("canon_usb_long_dialogue: WARNING: gp_port_read() resulted in short read "
1765                                   "(returned %i bytes, expected %i)", bytes_read, read_bytes);
1766                 bytes_received += bytes_read;
1767 
1768                 if (display_status)
1769                         gp_context_progress_update (context, id, bytes_received);
1770         }
1771         if (display_status)
1772                 gp_context_progress_stop (context, id);
1773 
1774         *data_length = total_data_size;
1775 
1776         return GP_OK;
1777 }
1778 
1779 /**
1780  * canon_usb_get_file:
1781  * @camera: camera to use
1782  * @name: name of file to fetch
1783  * @data: to receive image data
1784  * @length: to receive length of image data
1785  * @context: context for error reporting
1786  *
1787  * Get a file from a USB-connected Canon camera.
1788  *
1789  * Returns: gphoto2 error code, length in @length, and image data in @data.
1790  *
1791  */
1792 int
canon_usb_get_file(Camera * camera,const char * name,unsigned char ** data,unsigned int * length,GPContext * context)1793 canon_usb_get_file (Camera *camera, const char *name, unsigned char **data, unsigned int *length,
1794                     GPContext *context)
1795 {
1796         char payload[100];
1797         int payload_length, res, offset;
1798 
1799         GP_DEBUG ("canon_usb_get_file() called for file '%s'", name);
1800 
1801         /* Construct payload containing file name, buffer size and
1802          * function request.  See the file Protocol.xml in the doc/
1803          * directory for more information.
1804          */
1805         if ( camera->pl->md->model == CANON_CLASS_6 ) {
1806                 offset = 4;
1807                 if ( offset + strlen (name) > sizeof (payload) - 2 ) {
1808                         GP_DEBUG ("canon_usb_get_file: ERROR: "
1809                                   "Supplied file name '%s' does not fit in payload buffer.", name);
1810                         return GP_ERROR_BAD_PARAMETERS;
1811                 }
1812                 htole32a (payload, 0x0);        /* get picture */
1813                 strncpy ( payload+offset, name, sizeof(payload)-offset-1 );
1814                 payload[offset + strlen (payload+offset)] = 0;
1815                 payload_length = offset + strlen (payload+offset) + 2;
1816                 GP_DEBUG ( "canon_usb_get_file: payload 0x%08x:%s",
1817                            le32atoh(payload), payload+offset );
1818         }
1819         else {
1820                 offset = 8;
1821                 if ( offset + strlen (name) > sizeof (payload) - 1 ) {
1822                         GP_DEBUG ("canon_usb_get_file: ERROR: "
1823                                   "Supplied file name '%s' does not fit in payload buffer.", name);
1824                         return GP_ERROR_BAD_PARAMETERS;
1825                 }
1826                 htole32a (payload, 0x0);        /* get picture */
1827                 htole32a (payload + 0x4, camera->pl->xfer_length);
1828                 strncpy ( payload+offset, name, sizeof(payload)-offset );
1829                 payload_length = offset + strlen (payload+offset) + 1;
1830                 GP_DEBUG ( "canon_usb_get_file: payload 0x%08x:0x%08x:%s",
1831                            le32atoh(payload), le32atoh(payload+4), payload+offset );
1832         }
1833 
1834         /* the 1 is to show status */
1835         res = canon_usb_long_dialogue (camera, CANON_USB_FUNCTION_GET_FILE, data, length,
1836                                        camera->pl->md->max_movie_size, (unsigned char *)payload,
1837                                        payload_length, 1, context);
1838         if (res != GP_OK) {
1839                 GP_DEBUG ("canon_usb_get_file: canon_usb_long_dialogue() "
1840                           "returned error (%i).", res);
1841                 return res;
1842         }
1843 
1844         return GP_OK;
1845 }
1846 
1847 /**
1848  * canon_usb_get_thumbnail:
1849  * @camera: camera to use
1850  * @name: name of thumbnail to fetch
1851  * @data: to receive image data
1852  * @length: to receive length of image data
1853  * @context: context for error reporting
1854  *
1855  * Gets a thumbnail, including EXIF info, from a USB_connected Canon
1856  *   camera.
1857  *
1858  * Returns: gphoto2 error code, length in @length, and image data in
1859  *    @data.
1860  *
1861  */
1862 int
canon_usb_get_thumbnail(Camera * camera,const char * name,unsigned char ** data,unsigned int * length,GPContext * context)1863 canon_usb_get_thumbnail (Camera *camera, const char *name, unsigned char **data, unsigned int *length,
1864                          GPContext *context)
1865 {
1866         char payload[100];
1867         unsigned int payload_length;
1868 	int res, offset;
1869 
1870         GP_DEBUG ("canon_usb_get_thumbnail() called for file '%s'", name);
1871 
1872         if ( camera->pl->md->model == CANON_CLASS_6 ) {
1873 		/* Construct payload containing file name and function
1874 		 * request.  See the file Protocol.xml in directory
1875 		 * camlibs/canon/doc for more information.
1876 		 */
1877 
1878                 offset = 4;
1879                 if ( offset + strlen (name) > sizeof (payload) - 2 ) {
1880                         GP_DEBUG ("canon_usb_get_thumbnail: ERROR: "
1881                                   "Supplied file name '%s' does not fit in payload buffer.", name);
1882                         return GP_ERROR_BAD_PARAMETERS;
1883                 }
1884                 strncpy ( payload+offset, name, sizeof(payload)-offset-1 );
1885                 payload[offset + strlen (payload+offset)] = 0;
1886                 payload_length = offset + strlen (payload+offset) + 2;
1887 		htole32a (payload, 0x1);        /* get thumbnail */
1888                 GP_DEBUG ( "canon_usb_get_thumbnail: payload 0x%08x:%s",
1889                            le32atoh(payload), payload+offset );
1890         }
1891         else {
1892 		/* Construct payload containing file name, buffer size
1893 		 * and function request.  See the file Protocol.xml in
1894 		 * directory camlibs/canon/doc for more information.
1895 		 */
1896 
1897                 offset = 8;
1898                 if ( offset + strlen (name) > sizeof (payload) - 1 ) {
1899                         GP_DEBUG ("canon_usb_get_thumbnail: ERROR: "
1900                                   "Supplied file name '%s' does not fit in payload buffer.", name);
1901                         return GP_ERROR_BAD_PARAMETERS;
1902                 }
1903 		htole32a (payload, 0x1);        /* get thumbnail */
1904                 htole32a (payload + 0x4, camera->pl->xfer_length);
1905                 strncpy ( payload+offset, name, sizeof(payload)-offset );
1906                 payload_length = offset + strlen (payload+offset) + 1;
1907                 GP_DEBUG ( "canon_usb_get_thumbnail: payload 0x%08x:0x%08x:%s",
1908                            le32atoh(payload), le32atoh(payload+4), payload+offset );
1909         }
1910 
1911         /* 0 is to not show status */
1912         res = canon_usb_long_dialogue (camera, CANON_USB_FUNCTION_GET_FILE, data, length,
1913                                        camera->pl->md->max_thumbnail_size, (unsigned char *)payload,
1914                                        payload_length, 0, context);
1915 
1916         if (res != GP_OK) {
1917                 GP_DEBUG ("canon_usb_get_thumbnail: canon_usb_long_dialogue() "
1918                           "returned error (%i).", res);
1919                 return res;
1920         }
1921 
1922         return GP_OK;
1923 }
1924 
1925 /**
1926  * canon_usb_get_captured_image:
1927  * @camera: camera to lock keys on
1928  * @key: index of image to fetch, returned from canon_usb_capture_dialogue()
1929  * @data: to receive image data
1930  * @length: to receive length of image data
1931  * @context: context for error reporting
1932  *
1933  * Gets the just-captured image from a USB-connected Canon
1934  * camera. This function must be called soon after an image capture,
1935  * and needs the image key returned by canon_usb_capture_dialogue().
1936  *
1937  * Returns: gphoto2 error code, length in @length, and image data in @data.
1938  *
1939  */
1940 int
canon_usb_get_captured_image(Camera * camera,const int key,unsigned char ** data,unsigned int * length,GPContext * context)1941 canon_usb_get_captured_image (Camera *camera, const int key, unsigned char **data, unsigned int *length,
1942                               GPContext *context)
1943 {
1944         unsigned char payload[16];
1945         int payload_length = 16, result;
1946 
1947         GP_DEBUG ("canon_usb_get_captured_image() called");
1948 
1949         /* Construct payload containing buffer size and function request.
1950          * See the file Protocol in this directory for more information.
1951          */
1952         htole32a (payload, 0x0);        /* always zero */
1953         htole32a (payload + 0x4, camera->pl->xfer_length);
1954         htole32a (payload + 0x8, CANON_DOWNLOAD_FULL);
1955         htole32a (payload + 0xc, key);
1956 
1957         /* the 1 is to show status */
1958 	if ( camera->pl->md->model == CANON_CLASS_6 )
1959 		result = canon_usb_long_dialogue (camera, CANON_USB_FUNCTION_RETRIEVE_CAPTURE_2, data, length,
1960 						  0, payload,
1961 						  payload_length, 1, context);
1962 	else
1963 		result = canon_usb_long_dialogue (camera, CANON_USB_FUNCTION_RETRIEVE_CAPTURE, data, length,
1964 						  0, payload,
1965 						  payload_length, 1, context);
1966         if (result != GP_OK) {
1967                 GP_DEBUG ("canon_usb_get_captured_image: canon_usb_long_dialogue() "
1968                           "returned error (%i).", result);
1969                 return result;
1970         }
1971 
1972         return GP_OK;
1973 }
1974 
1975 /**
1976  * canon_usb_get_captured_secondary_image:
1977  * @camera: camera to work on
1978  * @key: index of image to fetch, returned from canon_usb_capture_dialogue()
1979  * @data: to receive image data
1980  * @length: to receive length of image data
1981  * @context: context for error reporting
1982  *
1983  * Gets the just-captured image from a USB-connected Canon
1984  * camera. This function must be called soon after an image capture,
1985  * and needs the image key returned by canon_usb_capture_dialogue().
1986  * This function is only used for "secondary images," e.g., the JPEGs
1987  * downloaded when the camera's capture image format mode is set to "RAW + JPEG"
1988  *
1989  * Returns: gphoto2 error code, length in @length, and image data in @data.
1990  *
1991  */
1992 int
canon_usb_get_captured_secondary_image(Camera * camera,const int key,unsigned char ** data,unsigned int * length,GPContext * context)1993 canon_usb_get_captured_secondary_image (Camera *camera, const int key, unsigned char **data, unsigned int *length,
1994 					GPContext *context)
1995 {
1996         unsigned char payload[16];
1997         int payload_length = 16, result;
1998 
1999         GP_DEBUG ("canon_usb_get_captured_secondary_image() called");
2000 
2001         /* Construct payload containing buffer size and function request.
2002          * See the file Protocol in this directory for more information.
2003          */
2004         htole32a (payload, 0x0);        /* always zero */
2005         htole32a (payload + 0x4, camera->pl->xfer_length);
2006         htole32a (payload + 0x8, CANON_DOWNLOAD_SECONDARY);
2007         htole32a (payload + 0xc, key);
2008 
2009         /* the 1 is to show status */
2010 	if ( camera->pl->md->model == CANON_CLASS_6 )
2011 		result = canon_usb_long_dialogue (camera, CANON_USB_FUNCTION_RETRIEVE_CAPTURE_2, data, length,
2012 						  0, payload,
2013 						  payload_length, 1, context);
2014 	else
2015 		result = canon_usb_long_dialogue (camera, CANON_USB_FUNCTION_RETRIEVE_CAPTURE, data, length,
2016 						  0, payload,
2017 						  payload_length, 1, context);
2018         if (result != GP_OK) {
2019                 GP_DEBUG ("canon_usb_get_captured_secondary_image: canon_usb_long_dialogue() "
2020                           "returned error (%i).", result);
2021                 return result;
2022         }
2023 
2024         return GP_OK;
2025 }
2026 
2027 /**
2028  * canon_usb_get_captured_thumbnail:
2029  * @camera: camera to lock keys on
2030  * @key: index of image to fetch, returned from canon_usb_capture_dialog()
2031  * @data: to receive thumbnail data
2032  * @length: to receive length of thumbnail data
2033  * @context: context for error reporting
2034  *
2035  * Gets the just-captured thumbnail from a USB-connected Canon
2036  * camera. This function must be called after a remote image capture,
2037  * before leaving remote capture mode, and needs the image key
2038  * returned by canon_usb_capture_dialog().
2039  *
2040  * Returns: gphoto2 error code, length in @length, and thumbnail data in @data.
2041  *
2042  */
2043 int
canon_usb_get_captured_thumbnail(Camera * camera,const int key,unsigned char ** data,unsigned int * length,GPContext * context)2044 canon_usb_get_captured_thumbnail (Camera *camera, const int key, unsigned char **data, unsigned int *length,
2045 				  GPContext *context)
2046 {
2047         unsigned char payload[16];
2048         int payload_length = 16, result;
2049 
2050         GP_DEBUG ("canon_usb_get_captured_thumbnail() called");
2051 
2052         /* Construct payload containing buffer size and function request.
2053          * See the file Protocol in this directory for more information.
2054          */
2055         htole32a (payload, 0x0);        /* get picture */
2056         htole32a (payload + 0x4, camera->pl->xfer_length);
2057         htole32a (payload + 0x8, CANON_DOWNLOAD_THUMB);
2058         htole32a (payload + 0xc, key);
2059 
2060         /* the 1 is to show status */
2061 	if ( camera->pl->md->model == CANON_CLASS_6 )
2062 		result = canon_usb_long_dialogue (camera, CANON_USB_FUNCTION_RETRIEVE_CAPTURE_2, data, length,
2063 						  0, payload,
2064 						  payload_length, 1, context);
2065 	else
2066 		result = canon_usb_long_dialogue (camera, CANON_USB_FUNCTION_RETRIEVE_CAPTURE, data, length,
2067 						  0, payload,
2068 						  payload_length, 1, context);
2069         if (result != GP_OK) {
2070                 GP_DEBUG ("canon_usb_get_captured_thumbnail: canon_usb_long_dialogue() "
2071                           "returned error (%i).", result);
2072                 return result;
2073         }
2074 
2075         return GP_OK;
2076 }
2077 
2078 /**
2079  * canon_usb_set_file_time:
2080  * @camera: camera to unlock keys on
2081  * @camera_filename: Full pathname to use on camera
2082  * @time: Unix time to store in camera directory
2083  * @context: context for error reporting
2084  *
2085  * Finishes the upload of an image to a Canon camera. Must be called
2086  * after the last data transfer completes.
2087  *
2088  * Returns: gphoto2 error code
2089  *
2090  */
canon_usb_set_file_time(Camera * camera,char * camera_filename,time_t time,GPContext * context)2091 int canon_usb_set_file_time ( Camera *camera, char *camera_filename, time_t time, GPContext *context)
2092 {
2093         unsigned char *result_buffer;
2094         unsigned int payload_size =  0x4 + strlen(camera_filename) + 2,
2095                 bytes_read;
2096         unsigned char *payload = malloc ( payload_size );
2097 
2098         if ( payload == NULL ) {
2099                 GP_DEBUG ( "canon_usb_set_file_time:"
2100                            " failed to allocate payload block." );
2101                 gp_context_error(context, _("Out of memory: %d bytes needed."),
2102                                  payload_size );
2103                 return GP_ERROR_NO_MEMORY;
2104         }
2105         memset ( payload, 0, payload_size );
2106 
2107         strcpy ( (char *)payload + 0x4, camera_filename );
2108         htole32a ( payload, time );          /* Load specified time for camera directory. */
2109         result_buffer = canon_usb_dialogue ( camera, CANON_USB_FUNCTION_SET_FILE_TIME,
2110 					     &bytes_read, payload, payload_size );
2111         free ( payload );
2112         if ( result_buffer == NULL ) {
2113                 GP_DEBUG ( "canon_usb_set_file_time:"
2114                            " dialogue failed." );
2115                 return GP_ERROR_OS_FAILURE;
2116         }
2117         return GP_OK;
2118 }
2119 
2120 /**
2121  * canon_usb_set_file_attributes:
2122  * @camera: camera to initialize
2123  * @attr_bits: bits to write in the camera directory entry
2124  * @pathname: pathname of file whose attributes are to be changed.
2125  * @context: context for error reporting
2126  *
2127  * Changes the attribute bits in a specified directory entry.
2128  *
2129  * Returns: gphoto2 error code
2130  *
2131  */
2132 int
canon_usb_set_file_attributes(Camera * camera,unsigned int attr_bits,const char * dir,const char * file,GPContext * context)2133 canon_usb_set_file_attributes (Camera *camera, unsigned int attr_bits,
2134                                const char *dir, const char *file,
2135                                GPContext *context)
2136 {
2137         /* Pathname string plus 32-bit parameter plus two NULs. */
2138         unsigned int payload_length = 4 + strlen (dir) + 1 + strlen (file) + 2;
2139         unsigned char *payload = calloc ( payload_length, sizeof ( unsigned char ) );
2140         unsigned int bytes_read;
2141         unsigned char *res;
2142 
2143         GP_DEBUG ( "canon_usb_set_file_attributes()" );
2144         GP_DEBUG ( "canon_usb_set_file_attributes(): payload is %d=0x%x bytes; string length is %d=0x%x",
2145                    payload_length, payload_length, (int)strlen(dir), (int)strlen(dir) );
2146         /* build payload :
2147          *
2148          * <attr bits> directory 0x00 file 0x00 0x00
2149          *
2150          * The attribute bits will be a 32-bit little-endian integer.
2151          */
2152         memset (payload, 0x00, payload_length);
2153         memcpy (payload + 4, dir, strlen (dir));
2154         memcpy (payload + 4 + strlen(dir) + 1, file, strlen (file) );
2155         htole32a ( payload, (unsigned long)attr_bits );
2156 
2157         if ( camera->pl->md->model == CANON_CLASS_6 )
2158                 res = canon_usb_dialogue ( camera, CANON_USB_FUNCTION_SET_ATTR_2, &bytes_read,
2159                                            payload, payload_length );
2160         else
2161                 res = canon_usb_dialogue ( camera, CANON_USB_FUNCTION_SET_ATTR, &bytes_read,
2162                                            payload, payload_length );
2163         if ( res == NULL ) {
2164                 gp_context_error (context,
2165                                   _("canon_usb_set_file_attributes: "
2166 				    "canon_usb_dialogue failed"));
2167                 free ( payload );
2168                 return GP_ERROR_OS_FAILURE;
2169         }
2170         else if ( le32atoh ( res+0x50 ) != 0 ) {
2171                 gp_context_message (context,
2172 				    _("Warning in canon_usb_set_file_attributes: "
2173 				      "canon_usb_dialogue returned error status 0x%08x from camera"),
2174 				    le32atoh ( res+0x50 ) );
2175         }
2176 
2177         free ( payload );
2178         return GP_OK;
2179 }
2180 
2181 
2182 /**
2183  * canon_usb_put_file:
2184  * @camera: camera to lock keys on
2185  * @file: CameraFile object to upload
2186  * @destname: name file should have on camera
2187  * @destpath: pathname for directory to put file
2188  * @context: context for error reporting
2189  *
2190  * Uploads file to USB camera
2191  *
2192  * Bugs:
2193  * at the moment, files bigger than 65572-length(filename), while being
2194  * correctly uploaded, cause the camera to not accept any more uploads.
2195  * Smaller files work fine.
2196  * s10sh (http://www.kyuzz.org/antirez/s10sh.html) has the same problem.
2197  * The problem only appears when USB deinitialisation and initialisation
2198  * is performed between uploads. You can call this function more than
2199  * once with big files during one session without encountering the problem
2200  * described. <kramm@quiss.org>
2201  *
2202  * Returns: gphoto2 error code
2203  *
2204  */
2205 
2206 #ifndef CANON_EXPERIMENTAL_UPLOAD
2207 int
canon_usb_put_file(Camera __unused__ * camera,CameraFile __unused__ * file,const char __unused__ * filename,const char __unused__ * destname,const char __unused__ * destpath,GPContext __unused__ * context)2208 canon_usb_put_file (Camera __unused__ *camera, CameraFile __unused__ *file,
2209 		    const char __unused__ *filename, const char __unused__ *destname, const char __unused__ *destpath,
2210                     GPContext __unused__ *context)
2211 {
2212         return GP_ERROR_NOT_SUPPORTED;
2213 }
2214 
2215 #else /* else ifdef CANON_EXPERIMENTAL_UPLOAD */
2216 
2217 int
canon_usb_put_file(Camera * camera,CameraFile * file,const char * xfilename,const char * destname,const char * destpath,GPContext * context)2218 canon_usb_put_file (Camera *camera, CameraFile *file,
2219 		    const char *xfilename, const char *destname, const char *destpath,
2220                     GPContext *context)
2221 {
2222         long int packet_size = USB_BULK_WRITE_SIZE;
2223         char buffer[0x80];
2224         long int len1,len2;
2225         int status;
2226         long int offs = 0;
2227         char filename[256];
2228         int filename_len;
2229         char *data;
2230         char *newdata = NULL;
2231         long int size;                       /* Total size of file to upload */
2232         FILE *fi;
2233         const char *srcname;
2234         char *packet;
2235         struct stat filestat;                /* To get time from Unix file */
2236 
2237         GP_DEBUG ( "canon_put_file_usb()" );
2238 
2239         sprintf(filename, "%s%s", destpath, destname);
2240         filename_len = strlen(filename);
2241 
2242         packet = malloc(packet_size + filename_len + 0x5d);
2243 
2244         if(!packet) {
2245 		int len = packet_size + filename_len + 0x5d;
2246 		GP_DEBUG ("canon_put_file_usb: Couldn't reserve %d bytes of memory", len);
2247 		gp_context_error(context, _("Out of memory: %d bytes needed."), len);
2248 		return GP_ERROR_NO_MEMORY;
2249         }
2250 
2251         GP_DEBUG ( "canon_put_file_usb: converting file name" );
2252         status = gp_file_get_name (file, &srcname)
2253 	if (status < GP_OK) {
2254 		free (packet);
2255 		return status;
2256 	}
2257 
2258         /* Open input file and read all its data into a buffer. */
2259         if(!gp_file_get_data_and_size (file, (const char **)&data, &size)) {
2260 		fi = fopen(srcname, "rb");
2261 		if(!fi) {
2262 			gp_context_error(context, _("Couldn't read from file \"%s\""), srcname);
2263 			free(packet);
2264 			return GP_ERROR_OS_FAILURE;
2265 		}
2266 		fstat ( fileno(fi), &filestat );
2267 		fseek(fi, 0, SEEK_END);
2268 		size = ftell(fi);
2269 		fseek(fi, 0, SEEK_SET);
2270 		newdata = data = malloc(size);
2271 		if(!newdata) {
2272 			gp_context_error(context, _("Out of memory: %ld bytes needed."), size);
2273 			free(packet);
2274 			return GP_ERROR_NO_MEMORY;
2275 		}
2276 		fread(newdata, size, 1, fi);
2277 		fclose(fi);
2278         }
2279 
2280         GP_DEBUG ( "canon_put_file_usb:"
2281                    " finished reading file, %ld bytes (0x%lx)",
2282                    size, size );
2283 
2284         /* Take the buffer and send it to the camera, breaking it into
2285          * packets of suitable size. */
2286         while(offs < size) {
2287 		len2 = packet_size;
2288 		if(size - offs < len2)
2289 			len2 = size - offs;
2290 		len1 = len2 + 0x1c + filename_len + 1;
2291 
2292 		GP_DEBUG ( "canon_put_file_usb: len1=%lx, len2=%lx", len1, len2 );
2293 
2294 		memset(packet, 0, 0x40);
2295 		packet[4]=3;
2296 		packet[5]=2;
2297 		htole32a ( packet + 0x6, len1 + 0x40 );
2298 		htole32a (packet + 0x4c, serial_code++); /* Serial number */
2299 
2300 		/* now send the packet to the camera */
2301 		status = gp_port_usb_msg_write (camera->port, 0x04, 0x10, 0,
2302 						packet, 0x40);
2303 		if (status != 0x40) {
2304 			GP_DEBUG ("canon_put_file_usb: write 1 failed! (returned %i)", status);
2305 			gp_context_error(context, _("File upload failed."));
2306 			if(newdata)
2307 				free(newdata);
2308 			free(packet);
2309 			return GP_ERROR_CORRUPTED_DATA;
2310 		}
2311 
2312 		status = gp_port_read (camera->port, buffer, 0x40);
2313 		if (status != 0x40) {
2314 			GP_DEBUG ("canon_put_file_usb: read 1 failed! "
2315 				  "(returned %i, expected %i)", status, 0x40);
2316 			gp_context_error(context, _("File upload failed."));
2317 			if(newdata)
2318 				free(newdata);
2319 			free(packet);
2320 			return GP_ERROR_CORRUPTED_DATA;
2321 		}
2322 
2323 		memset(packet, 0, len1 + 0x40);
2324 		/* Length of this block (minus 0x40) */
2325 		htole32a ( packet, len1 );
2326 
2327 		/* Fill in codes */
2328 		packet[0x04] = 3;
2329 		packet[0x05] = 4;
2330 		packet[0x40] = 2;
2331 		packet[0x44] = 3;
2332 		packet[0x47] = 0x11;
2333 
2334 		/* Copy of bytes 0:3 */
2335 		htole32a ( packet+0x48, len1 );
2336 
2337 		/* Serial number */
2338 		htole32a (packet + 0x4c, serial_code++);
2339 
2340 		htole32a ( packet+0x54, offs );
2341 
2342 		/* Max length of data block */
2343 		htole32a ( packet+0x58, len2 );
2344 
2345 		strcpy(&packet[0x5c], filename);
2346 		memcpy(&packet[0x5c+filename_len+1], &data[offs], len2);
2347 
2348 		status = gp_port_write (camera->port, packet, len1+0x40);
2349 		if (status != len1+0x40) {
2350 			GP_DEBUG ("canon_put_file_usb: write 2 failed! "
2351 				  "(returned %i, expected %li)", status, len1+0x40);
2352 			gp_context_error(context, _("File upload failed."));
2353 			if(newdata)
2354 				free(newdata);
2355 			free(packet);
2356 			if ( status < 0 )
2357 				return GP_ERROR_OS_FAILURE;
2358 			else
2359 				return GP_ERROR_CORRUPTED_DATA;
2360 		}
2361 
2362 		status = gp_port_read (camera->port, buffer, 0x40);
2363 		if (status != 0x40) {
2364 			GP_DEBUG ("canon_put_file_usb: read 2 failed! "
2365 				  "(returned %i, expected %i)", status, 0x5c);
2366 			gp_context_error(context, _("File upload failed."));
2367 			if(newdata)
2368 				free(newdata);
2369 			free(packet);
2370 			if ( status < 0 )
2371 				return GP_ERROR_OS_FAILURE;
2372 			else
2373 				return GP_ERROR_CORRUPTED_DATA;
2374 		}
2375 
2376 		status = gp_port_read (camera->port, buffer, 0x1c);
2377 		if (status != 0x1c) {
2378 			GP_DEBUG ("canon_put_file_usb: read 3 failed! "
2379 				  "(returned %i, expected %i)", status, 0x5c);
2380 			gp_context_error(context, _("File upload failed."));
2381 			if(newdata)
2382 				free(newdata);
2383 			free(packet);
2384 			if ( status < 0 )
2385 				return GP_ERROR_OS_FAILURE;
2386 			else
2387 				return GP_ERROR_CORRUPTED_DATA;
2388 		}
2389 		else {
2390 			char *msg = canon_usb_decode_status ( le32atoh ( buffer+0x50 ) );
2391 			if ( msg != NULL ) {
2392 				GP_DEBUG ( "canon_put_file_usb: camera status \"%s\" during upload",
2393 					   msg );
2394 			}
2395 		}
2396 		offs += len2;
2397         }
2398 
2399         /* Now we finish the job. */
2400         canon_usb_set_file_time ( camera, filename, filestat.st_mtime, context );
2401 
2402         canon_usb_set_file_attributes ( camera, (unsigned int)0,
2403                                         destpath, destname, context );
2404 
2405         if(size > 65572-filename_len) {
2406 		gp_context_message(context, _("File was too big. You may have to turn your camera off and back on before uploading more files."));
2407         }
2408 
2409         if(newdata)
2410 		free(newdata);
2411         free(packet);
2412         return GP_OK;
2413 }
2414 #endif /* CANON_EXPERIMENTAL_UPLOAD */
2415 
2416 
2417 /**
2418  * canon_usb_get_dirents:
2419  * @camera: camera to initialize
2420  * @dirent_data: to receive directory data
2421  * @dirents_length: to receive length of @dirent_data
2422  * @path: pathname of directory to list
2423  * @context: context for error reporting
2424  *
2425  * Lists a directory.
2426  *
2427  * Returns: gphoto2 error code
2428  *
2429  */
2430 int
canon_usb_get_dirents(Camera * camera,unsigned char ** dirent_data,unsigned int * dirents_length,const char * path,GPContext * context)2431 canon_usb_get_dirents (Camera *camera, unsigned char **dirent_data,
2432                        unsigned int *dirents_length, const char *path, GPContext *context)
2433 {
2434         unsigned char payload[100];
2435         unsigned int payload_length;
2436         int res;
2437 
2438         *dirent_data = NULL;
2439 
2440         /* build payload :
2441          *
2442          * 0x00 dirname 0x00 0x00 0x00
2443          *
2444          * the 0x00 before dirname means 'no recursion'
2445          * NOTE: the first 0x00 after dirname is the NULL byte terminating
2446          * the string, so payload_length is strlen(dirname) + 4
2447          */
2448         if (strlen (path) + 4 > sizeof (payload)) {
2449                 GP_DEBUG ("canon_usb_get_dirents: "
2450                           "Path '%s' too long (%li), won't fit in payload buffer.", path,
2451                           (long)strlen (path));
2452                 gp_context_error (context,
2453                                   _("canon_usb_get_dirents: "
2454 				    "Couldn't fit payload into buffer, "
2455 				    "'%.96s' (truncated) too long."), path);
2456                 return GP_ERROR_BAD_PARAMETERS;
2457         }
2458         memset (payload, 0x00, sizeof (payload));
2459         memcpy (payload + 1, path, strlen (path));
2460         payload_length = strlen (path) + 4;
2461 
2462         /* 1024 * 1024 is max realistic data size, out of the blue.
2463          * 0 is to not show progress status
2464          */
2465         res = canon_usb_long_dialogue (camera, CANON_USB_FUNCTION_GET_DIRENT, dirent_data,
2466                                        dirents_length, 1024 * 1024, payload, payload_length, 0,
2467                                        context);
2468         if (res != GP_OK) {
2469                 gp_context_error (context,
2470                                   _("canon_usb_get_dirents: "
2471 				    "canon_usb_long_dialogue failed to fetch direntries, "
2472 				    "returned %i"), res);
2473                 return res;
2474 
2475         }
2476 
2477         return GP_OK;
2478 }
2479 
2480 /**
2481  * canon_usb_list_all_dirs:
2482  * @camera: camera to initialize
2483  * @dirent_data: to receive directory data
2484  * @dirents_length: to receive length of @dirent_data
2485  * @context: context for error reporting
2486  *
2487  * Lists all directories on camera. This can be executed before and
2488  *  after a "capture image" operation. By comparing the results, we can
2489  *  see where the new image went. Unfortunately, this seems to be the
2490  *  only way to find out, as Canon doesn't return that information from
2491  *  a capture command.
2492  *
2493  * Returns: gphoto2 error code
2494  *
2495  */
2496 int
canon_usb_list_all_dirs(Camera * camera,unsigned char ** dirent_data,unsigned int * dirents_length,GPContext * context)2497 canon_usb_list_all_dirs (Camera *camera, unsigned char **dirent_data,
2498 			 unsigned int *dirents_length, GPContext *context)
2499 {
2500         unsigned char payload[100];
2501         unsigned int payload_length;
2502         char *disk_name = canon_int_get_disk_name (camera, context);
2503         int res;
2504 
2505         *dirent_data = NULL;
2506 
2507 	if (!disk_name) /* should only happen on IO error */
2508 		return GP_ERROR_IO;
2509 
2510         /* build payload :
2511          *
2512          * 0x0f dirname 0x00 0x00 0x00
2513          *
2514          * the 0x0f before dirname means 'recurse to level 15', which
2515          * should get all the directories on the camera.
2516          * NOTE: the first 0x00 after dirname is the NULL byte terminating
2517          * the string, so payload_length is strlen(dirname) + 4
2518          */
2519         if (strlen (disk_name) + 4 > sizeof (payload)) {
2520                 GP_DEBUG ("canon_usb_list_all_dirs: "
2521                           "Path '%s' too long (%li), won't fit in payload buffer.",
2522                           disk_name, (long)strlen (disk_name));
2523                 gp_context_error (context,
2524                                   _("canon_usb_list_all_dirs: "
2525 				    "Couldn't fit payload into buffer, "
2526 				    "'%.96s' (truncated) too long."), disk_name);
2527                 return GP_ERROR_BAD_PARAMETERS;
2528         }
2529         memset (payload, 0x00, sizeof (payload));
2530         memcpy (payload + 1, disk_name, strlen (disk_name));
2531         payload[0] = 0x0f;                   /* Recursion depth */
2532         payload_length = strlen (disk_name) + 4;
2533         free ( disk_name );
2534 
2535         /* Give no max data size.
2536          * 0 is to not show progress status
2537          */
2538         res = canon_usb_long_dialogue (camera, CANON_USB_FUNCTION_GET_DIRENT, (unsigned char **)dirent_data,
2539                                        dirents_length, 0, payload, payload_length, 0,
2540                                        context);
2541         if (res != GP_OK) {
2542                 gp_context_error (context,
2543                                   _("canon_usb_list_all_dirs: "
2544 				    "canon_usb_long_dialogue failed to fetch direntries, "
2545 				    "returned %i"), res);
2546                 return res;
2547         }
2548 
2549         return GP_OK;
2550 }
2551 
2552 /**
2553  * canon_usb_ready:
2554  * @camera: camera to check
2555  *
2556  * Checks whether camera is available for communication.
2557  *
2558  * Returns: gphoto2 error code
2559  *          GP_OK if camera is ready
2560  *
2561  */
2562 int
canon_usb_ready(Camera * camera,GPContext __unused__ * context)2563 canon_usb_ready (Camera *camera, GPContext __unused__ *context)
2564 {
2565 	unsigned char *msg;
2566         unsigned int len;
2567 
2568         GP_DEBUG ("canon_usb_ready()");
2569 
2570         /* "Identify camera" seems to be a command compatible with all
2571 	 * cameras, and one that doesn't change the camera state. */
2572 	msg = canon_usb_dialogue (camera, CANON_USB_FUNCTION_IDENTIFY_CAMERA,
2573 				  &len, NULL, 0);
2574 	if ( msg == NULL )
2575 		return GP_ERROR_OS_FAILURE;
2576 
2577         return GP_OK;
2578 }
2579 
2580 
2581 /**
2582  * canon_usb_identify:
2583  * @camera: camera to identify
2584  * @context: context for error reporting
2585  *  GP_ERROR_MODEL_NOT_FOUND if not found in our list;
2586  *    this is a code inconsistency.
2587  *  GP_OK otherwise
2588  *
2589  * Identify a supported camera by looking through our list of models.
2590  *
2591  * Returns: gphoto2 error code
2592  *
2593  */
2594 static int
canon_usb_identify(Camera * camera,GPContext * context)2595 canon_usb_identify (Camera *camera, GPContext *context)
2596 {
2597         CameraAbilities a;
2598         int i, res;
2599 
2600         res = gp_camera_get_abilities (camera, &a);
2601         if (res != GP_OK) {
2602                 GP_DEBUG ("canon_usb_identify: Could not get camera abilities: %s",
2603                           gp_result_as_string (res));
2604                 return res;
2605         }
2606 
2607         /* ahem. isn't this a tautology? */
2608 
2609         /* Formerly, we matched strings here.
2610          * Now we just match USB Vendor/Product IDs to work around
2611          * the colon/space problem. (FIXME)
2612          */
2613         for (i = 0; models[i].id_str != NULL; i++) {
2614                 if (models[i].usb_vendor
2615                     && models[i].usb_product
2616                     && (a.usb_vendor  == models[i].usb_vendor)
2617                     && (a.usb_product == models[i].usb_product)) {
2618                         GP_DEBUG ("canon_usb_identify: USB ID match 0x%04x:0x%04x (model name \"%s\")",
2619                                   models[i].usb_vendor, models[i].usb_product, models[i].id_str);
2620                         gp_context_status (context, _("Detected a '%s'."), models[i].id_str);
2621                         camera->pl->md = (struct canonCamModelData *) &models[i];
2622                         return GP_OK;
2623                 }
2624         }
2625 
2626         gp_context_error (context, _("Name \"%s\" from camera does not match any known camera"), a.model);
2627 
2628         return GP_ERROR_MODEL_NOT_FOUND;
2629 }
2630 
2631 
2632 /*
2633  * Local Variables:
2634  * c-file-style:"linux"
2635  * indent-tabs-mode:t
2636  * End:
2637  */
2638