1 /*
2  * multican 0.0.5, USB remote control tool for Canon cameras.
3  *
4  * Copyright (C) 2006 Jindrich Novy (jnovy@users.sourceforge.net)
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 
21 #define _GNU_SOURCE
22 
23 #include <stdio.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <sys/endian.h>
27 #include <time.h>
28 #include <sched.h>
29 #include <sys/time.h>
30 #include <sys/types.h>
31 #include <sys/wait.h>
32 #include <usb.h>
33 
34 #include "usbio.h"
35 #include "canonio.h"
36 
37 /*
38  * Purpose:
39  * - scan USB ports for attached Canon devices
40  *
41  * Returns:
42  * - number of successfully recognized Canon devices attached to USB ports
43  * - filled camera[6] field
44  */
canon_scan(camera ** c)45 int canon_scan( camera **c ) {
46 	struct usb_bus *busses;
47 	struct usb_bus *bus;
48 	struct usb_interface_descriptor *desc;
49 	int count = 0, n, ready = 0;
50 	camera *cam;
51 
52 	FUNCSTART
53 
54 	usb_init();
55 	usb_find_busses();
56 	usb_find_devices();
57 
58 	busses = usb_get_busses();
59 
60 	*c = calloc(USB_MAX_DEVICES, sizeof(camera));
61 	cam = *c;
62 
63 	for (bus = busses; bus; bus = bus->next) {
64                 struct usb_device *dev;
65 		int i;
66 
67 		for (dev = bus->devices; dev; dev = dev->next) {
68 			if (dev->descriptor.idVendor || dev->descriptor.idProduct) {
69 #ifdef DEBUG
70 				printf("Found: %04x:%04x\n", dev->descriptor.idVendor, dev->descriptor.idProduct);
71 #endif
72 				for ( i=0; camera_id[i].idVendor; i++ )
73 					if ( dev->descriptor.idVendor == camera_id[i].idVendor && dev->descriptor.idProduct == camera_id[i].idProduct ) {
74 #ifdef DEBUG
75 						printf(" -> %s.\n", camera_id[i].name);
76 #endif
77 						cam[count].dev = dev;
78 						cam[count].cam_id = i;
79 
80 						cam[count].h = usb_open(dev);
81 						if ( !cam[count].h ) {
82 							fprintf(stderr, "  usb_open(): Unable to open USB device.\n");
83 							count++;
84 							break;
85 						}
86 
87 						if ( usb_claim_interface(cam[count].h, 0) < 0 ) {
88 							fprintf(stderr, "  usb_claim_interface(): Cannot claim USB interface.\n");
89 							count++;
90 							break;
91 						}
92 
93 						if ( usb_reset(cam[count].h) ) {
94 							fprintf(stderr, "  usb_reset(): Unable to reset interface.\n");
95 							count++;
96 							break;
97 						}
98 
99 						cam[count].interface = cam[count].dev->config->interface;
100 						if (cam[count].interface->num_altsetting != 1) {
101 							fprintf(stderr,"  bad altsetting (%d).\n", cam[count].interface->num_altsetting);
102 							count++;
103 							break;
104 						}
105 
106 						cam[count].desc = &cam[count].interface->altsetting[0];
107 						desc = cam[count].desc;
108 
109 						for (n = 0; n<desc->bNumEndpoints; n++) {
110 							struct usb_endpoint_descriptor *endpoint = &desc->endpoint[n];
111 
112 							switch(endpoint->bmAttributes & USB_ENDPOINT_TYPE_MASK) {
113 								case USB_ENDPOINT_TYPE_BULK:
114 									if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN) {
115 										cam[count].bulk_in = endpoint->bEndpointAddress;
116 									} else {
117 										cam[count].bulk_out = endpoint->bEndpointAddress;
118 									}
119 								break;
120 								case USB_ENDPOINT_TYPE_INTERRUPT:
121 									if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN) {
122 										cam[count].bulk_int_in = endpoint->bEndpointAddress;
123 									}
124 								break;
125 							}
126         					}
127 #ifdef DEBUG
128 						fprintf(stderr, "  bulk_in=%d (0x%x), bulk_out=%d (0x%x), bulk_int_in=%d (0x%x)\n\n",
129 						cam[count].bulk_in, cam[count].bulk_in, cam[count].bulk_out, cam[count].bulk_out, cam[count].bulk_int_in, cam[count].bulk_int_in);
130 #endif
131 						if (cam[count].bulk_in == 0 || cam[count].bulk_out == 0 || cam[count].bulk_int_in == 0) {
132 							fprintf(stderr, "  bad endpoints.\n");
133 							count++;
134 							break;
135 						}
136 
137 						cam[count].ready = 1;
138 
139 						count++;
140 						ready++;
141 						if ( count>=7 ) {
142 							fprintf(stderr, "  maximal number of supported devices reached.\n");
143 							return ready;
144 						}
145 						break;
146 					}
147                         }
148                 }
149         }
150 
151 	if (!ready) {
152 		free(cam);
153 		*c = NULL;
154 		return 0;
155 	}
156 
157 	return ready;
158 }
159 
160 /*
161  * Purpose:
162  * - initialize detected camera for communication
163  *
164  * Returns:
165  * - 1 == ok
166  * - 0 == error
167  * - sets camera ready flag to 0 when initialization is unsuccessful
168  * - sets max_transfer
169  */
canon_init_camera(camera * c)170 int canon_init_camera( camera *c ) {
171 	char buf[0x58];
172 	char canon_state;
173 
174 	FUNCSTART
175 
176 	if ( !c->ready ) return 0;
177 #ifdef DEBUG
178 	fprintf(stderr, "Initializing %s...\n", camera_id[c->cam_id].name);
179 #endif
180 
181 	usb_read_byte(c->h, 0x55, &canon_state);
182 	c->canon_state = canon_state;
183 
184 	switch( canon_state ) {
185 		case 'A':
186 #ifdef DEBUG
187 			printf("Camera was already active.\n\n");
188 #endif
189 			usb_read_bytes(c->h, 1, buf, sizeof(buf));
190 			usb_read_bytes(c->h, 4, buf, 0x50); /* XXX: requesttype 0x4 instead of 0x40? */
191 
192 /*			if ( CANON_CLASS(c) >= 6 ) {
193 				char tmp[1024];
194 				usb_send_packet(c, 0x24, 0x12, 0x201, NULL, 0);
195 				usb_receive_packet(c, tmp, sizeof(tmp));
196 			}
197 */
198 			break;
199 		case 'C':
200 #ifdef DEBUG
201 			printf("Camera was woken up.\n\n");
202 #endif
203 			usb_read_bytes(c->h, 1, buf, sizeof(buf));
204 #ifdef DEBUG
205 			fprintf(stderr,"Max download transfer length: %u (0x%x).\n\n", get_le32(buf+0x4c), get_le32(buf+0x4c));
206 #endif
207 			c->max_transfer = get_le32(buf+0x4c);
208 			buf[0] = 0x10;
209 			memmove(&buf[0x40], &buf[sizeof(buf)-0x10], 0x10);
210 			usb_write_bytes(c->h, 0x11, buf, 0x50);
211 			if ( CANON_CLASS(c) < 6 ) {
212 				usb_bulk_read_bytes(c->h, c->bulk_in, buf, 0x40);
213 #ifdef DEBUG
214 				fprintf(stderr, "Length should be 4, length read from packet is: %u (0x%x).\n\n", get_le32(buf), get_le32(buf));
215 #endif
216 				usb_bulk_read_bytes(c->h, c->bulk_in, buf, 0x4);
217 				usb_bulk_read_bytes(c->h, c->bulk_int_in, buf, 0x10);
218 			} else {
219 				if ( CANON_CLASS(c) >= 6 && !IS_TYPE(c,"1D")) {
220 #ifdef DEBUG
221 					fprintf(stderr, "Class >= 6 camera reading all 0x44 bytes.\n\n");
222 #endif
223 					usb_bulk_read_bytes(c->h, c->bulk_in, buf, 0x44);
224 				} else {
225 					usb_bulk_read_bytes(c->h, c->bulk_in, buf, 0x40);
226 					usb_bulk_read_bytes(c->h, c->bulk_int_in, buf, 0x10);
227 				}
228 			}
229 			break;
230 		case 'I':
231 		case 'E':
232 #ifdef DEBUG
233 			fprintf(stderr, "Camera reports an error.\n");
234 #endif
235 			c->ready = 0;
236 			return 0;
237 			break;
238 		default:
239 			fprintf(stderr, "Camera returned unknown state '%c' (0x%02x).\n", canon_state, canon_state);
240 			c->ready = 0;
241 			return 0;
242 	}
243 
244 	return 1;
245 }
246 
247 /*
248  * Purpose:
249  * - initialize all detected cameras.
250  *
251  * Returns:
252  * - number of cameras successfuly initialized
253  */
canon_init_all(camera * c)254 int canon_init_all( camera *c ) {
255 	int i, ready = 0;
256 
257 	FUNCSTART
258 
259 	for ( i=0; i<USB_MAX_DEVICES; i++ )
260 		if ( c[i].ready ) {
261 			canon_init_camera( &c[i] );
262 			if ( c[i].ready ) ready++;
263 		}
264 
265 	return ready;
266 }
267 
canon_identify_camera(camera * c)268 void canon_identify_camera( camera *c ) {
269 	char buf[0x9c];
270 
271 	FUNCSTART
272 
273 	if ( !c->identified )
274 		c->identified = 1;
275 	else
276 		return;
277 
278 	usb_send_packet(c, 0x1, 0x12, 0x201, NULL, 0);
279 	usb_receive_packet(c, buf, sizeof(buf));
280 
281 	printf("Camera type:\t\t'%s'.\nOwner:\t\t\t'%s'.\nFirmware version:\t%c.%c.%c.%c.\n",
282 		buf+0x5c, buf+0x7c, buf[0x5b]+'0', buf[0x5a]+'0', buf[0x59]+'0', buf[0x58]+'0');
283 
284 	{
285 		char firmware[] = {"0.0.0.0"};
286 
287 		c->camera_type = strdup(buf+0x5c);
288 		c->owner = strdup(buf+0x7c);
289 
290 		firmware[0] = buf[0x5b]+'0';
291 		firmware[2] = buf[0x5a]+'0';
292 		firmware[4] = buf[0x59]+'0';
293 		firmware[6] = buf[0x58]+'0';
294 		c->firmware = strdup(firmware);
295 
296 		c->firmware1 = buf[0x5b];
297 		c->firmware2 = buf[0x5a];
298 		c->firmware3 = buf[0x59];
299 		c->firmware4 = buf[0x59];
300 	}
301 }
302 
canon_power_status(camera * c)303 void canon_power_status( camera *c ) {
304 	char buf[0x58];
305 
306 	FUNCSTART
307 
308 	if ( IS_TYPE(c,"10D") ) {
309 		c->power_status = strdup("unknown");
310 		c->power_type   = strdup("unknown");
311 		printf("Power status:\t\t%s.\nPower type:\t\t%s.\n",
312 			c->power_status, c->power_type);
313 		return;
314 	}
315 
316 	if ( IS_TYPE(c,"300D") || IS_TYPE(c,"10D") || IS_TYPE(c,"1D") ) {
317 		usb_send_packet(c, 0xa, 0x12, 0x201, NULL, 0);
318 	} else {
319 		usb_send_packet(c, 0x13, 0x12, 0x201, NULL, 0);
320 	}
321 	usb_receive_packet(c, buf, sizeof(buf));
322 
323 	c->power_status = strdup(buf[0x54]==6?"good":buf[0x54]==4?"bad":"unknown");
324 	c->power_type   = strdup(buf[0x57]&0x20?"battery":"AC adapter");
325 
326 	printf("Power status:\t\t%s.\nPower type:\t\t%s.\n",
327 		c->power_status, c->power_type);
328 
329 	if ( CANON_CLASS(c) == 6 )
330 		usb_bulk_read_bytes(c->h, c->bulk_int_in, buf, 0x10);
331 }
332 
canon_eos_id(camera * c)333 void canon_eos_id( camera *c ) {
334 	char buf[0x58];
335 
336 	FUNCSTART
337 
338 	if ( !c->got_body_id )
339 		c->got_body_id = 1;
340 	else
341 		return;
342 
343 	if ( !IS_EOS(c) ) {
344 #ifdef DEBUG
345 		fprintf(stderr, "Unable to get body ID on non-EOS cameras.\n");
346 #endif
347 		exit(1);
348 	}
349 
350 	if ( CANON_CLASS(c) >= 6 /*&& !IS_TYPE(c,"1D")*/ ) {
351 		usb_send_packet(c, 0x23, 0x12, 0x201, NULL, 0);
352 	} else {
353 		usb_send_packet(c, 0x1d, 0x12, 0x201, NULL, 0);
354 	}
355 	usb_receive_packet(c, buf, sizeof(buf));
356 
357 	c->body_id = get_le32(&buf[0x54]);
358 
359 	printf("Serial number:\t\t%010u.\n", c->body_id);
360 }
361 
canon_init_control(camera * c)362 void canon_init_control( camera *c ) {
363 	char buf[0x5c];
364 	char args[0x9];
365 
366 	FUNCSTART
367 
368 	if ( IS_TYPE(c,"300D") || IS_TYPE(c,"10D") || IS_TYPE(c,"1D") ) {
369 		memset(args, 0, 8);
370 		usb_send_packet( c, 0x13, 0x12, 0x201, args, 8 );
371 		usb_receive_packet(c, buf, sizeof(buf));
372 	} else {
373 		memset(args, 0, 9);
374 		usb_send_packet( c, 0x25, 0x12, 0x201, args, 9 );
375 		usb_receive_packet(c, buf, sizeof(buf));
376 	}
377 }
378 
379 /* Doesn't work with EOS 300D */
380 #define FLASH_OFF  0x00
381 #define FLASH_ON   0x01
382 #define FLASH_AUTO 0x02
canon_flash(camera * c,unsigned char flags)383 void canon_flash( camera *c, unsigned char flags ) {
384 	char buf[0x5c];
385 	char args[0x38];
386 
387 	FUNCSTART
388 
389 	printf("Flash is set:\t\t");
390 	switch( flags ) {
391 		case FLASH_OFF:
392 			printf("OFF\n");
393 		break;
394 		case FLASH_ON:
395 			printf("ON\n");
396 		break;
397 		case FLASH_AUTO:
398 			printf("AUTO\n");
399 		break;
400 		default:
401 			printf("to unknown state, THIS IS A BUG!\n");
402 			return;
403 		break;
404 	}
405 	memset(args, 0, sizeof(args));
406 	args[0]    = 7;
407 	args[0x12] = flags;
408 
409 	c->flash_state = flags;
410 
411 	usb_send_packet( c, 0x13, 0x12, 0x201, args, sizeof(args) );
412 	usb_receive_packet(c, buf, sizeof(buf));
413 }
414 
canon_transfer(camera * c,unsigned char flags)415 void canon_transfer( camera *c, unsigned char flags ) {
416 	char buf[0x5c];
417 	char args[0xc];
418 
419 	FUNCSTART
420 
421 	if ( flags&~15 ) {
422 		fprintf(stderr, "canon_transfer(): Flags not in range!\n");
423 	}
424 
425 	c->thumb_to_pc = flags&THUMB_TO_PC;
426 	c->full_to_pc = flags&FULL_TO_PC;
427 	c->thumb_to_drive = flags&THUMB_TO_DRIVE;
428 	c->full_to_drive = flags&FULL_TO_DRIVE;
429 
430 	printf("Transfer mode is:%s%s%s%s.\n",
431 		c->thumb_to_pc?"\tTHUMB_TO_PC":"",
432 		c->full_to_pc?"\tFULL_TO_PC":"",
433 		c->thumb_to_drive?"\tTHUMB_TO_DRIVE":"",
434 		c->full_to_drive?"\tFULL_TO_DRIVE":""
435 	      );
436 
437 	memset(args, 0, sizeof(args));
438 
439 	args[0] = 9;
440 	args[4] = 4;
441 	args[8] = flags;
442 
443 	if ( IS_TYPE(c,"300D") || IS_TYPE(c,"10D") )
444 		usb_send_packet( c, 0x13, 0x12, 0x201, args, sizeof(args) );
445 	else
446 		usb_send_packet( c, 0x25, 0x12, 0x201, args, sizeof(args) );
447 
448 	usb_receive_packet(c, buf, sizeof(buf));
449 }
450 
451 /* Doesn't work on EOS 300D */
canon_get_zoom(camera * c)452 void canon_get_zoom( camera *c ) {
453 	char buf[0x60];
454 	char args[0x8];
455 
456 	FUNCSTART
457 
458 	args[0] = 0xb;
459 	memset(args+1, 0, 7);
460 	usb_send_packet( c, 0x13, 0x12, 0x201, args, sizeof(args) );
461 	usb_receive_packet(c, buf, sizeof(buf));
462 
463 	printf("Zoom:\t\t%d\n", buf[0x5e]);
464 }
465 
canon_avail_shots(camera * c)466 void canon_avail_shots( camera *c ) {
467 	char buf[0x60];
468 	char args[0x8];
469 
470 	FUNCSTART
471 
472 	args[0] = 0xd;
473 	memset(args+1, 0, 7);
474 	usb_send_packet( c, 0x13, 0x12, 0x201, args, sizeof(args) );
475 	usb_receive_packet(c, buf, sizeof(buf));
476 
477 	c->avail_shots = get_le32(&buf[0x5c]);
478 	printf("Available shots:\t%u\n", c->avail_shots);
479 }
480 
canon_exit_control(camera * c)481 void canon_exit_control( camera *c ) {
482 	char buf[0x5c];
483 	char args[0x8];
484 
485 	FUNCSTART
486 
487 	args[0] = 1;
488 	memset(args+1, 0, 7);
489 
490 	if ( IS_TYPE(c,"300D")|| IS_TYPE(c,"10D") )
491 		usb_send_packet( c, 0x13, 0x12, 0x201, args, sizeof(args) );
492 	else
493 		usb_send_packet( c, 0x25, 0x12, 0x201, args, sizeof(args) );
494 
495 	usb_receive_packet(c, buf, sizeof(buf));
496 }
497 
canon_close(camera ** cptr)498 void canon_close( camera **cptr ) {
499 	int i;
500 
501 	FUNCSTART
502 
503 	if ( !*cptr ) return;
504 
505 	for ( i=0; i<USB_MAX_DEVICES; i++ ) {
506 		camera *c = &(*cptr)[i];
507 
508 		free(c->owner);
509 		free(c->camera_type);
510 		free(c->firmware);
511 		free(c->power_status);
512 		free(c->power_type);
513 
514 		if ( c->interface ) usb_release_interface(c->h, 0);
515 		if ( c->h ) usb_close(c->h);
516 	}
517 
518 	free( *cptr );
519 	*cptr = NULL;
520 }
521 
canon_set_owner(camera * c,char * name)522 void canon_set_owner( camera *c, char *name ) {
523 	usb_send_packet( c, 0x1, 0x12, 0x201, name, strlen(name)+1 );
524 }
525 
526 /*
527  * Has to be called before changing any of the release parameters.
528  */
canon_get_rel_params(camera * c)529 void canon_get_rel_params( camera *c ) {
530 	char buf[0x8c];
531 	char args[0x8];
532 
533 	FUNCSTART
534 
535 	memset(args, 0, sizeof(args));
536 	args[0]    = 0x0a;
537 
538 	if ( IS_TYPE(c,"300D") || IS_TYPE(c,"10D") )
539 		usb_send_packet( c, 0x13, 0x12, 0x201, args, sizeof(args) );
540 	else
541 		usb_send_packet( c, 0x25, 0x12, 0x201, args, sizeof(args) );
542 
543 	usb_receive_packet(c, buf, sizeof(buf));
544 
545 	memcpy(c->rel_params, &buf[0x5c], 0x30);
546 	c->rel_params_filled = 1;
547 	c->rel_params_updated = 0;
548 }
549 
canon_set_rel_params(camera * c)550 void canon_set_rel_params( camera *c ) {
551 	char buf2[0x5c];
552 	char args2[0x38];
553 
554 	FUNCSTART
555 
556 	if (!c->rel_params_filled) {
557 		fprintf(stderr, "warning: Release parameters not previously read.\n");
558 		return;
559 	}
560 
561 	memset(args2, 0, sizeof(args2));
562 	args2[0] = 7;
563 	args2[4] = 0x30;
564 	memcpy(&args2[8], c->rel_params, 0x30);
565 
566 	if ( IS_TYPE(c,"300D") || IS_TYPE(c,"10D") )
567 		usb_send_packet( c, 0x13, 0x12, 0x201, args2, sizeof(args2) );
568 	else
569 		usb_send_packet( c, 0x25, 0x12, 0x201, args2, sizeof(args2) );
570 
571 	usb_receive_packet(c, buf2, sizeof(buf2));
572 
573 	c->rel_params_updated = 0;
574 }
575 
canon_rel(camera * c,char * param,char * token)576 void canon_rel( camera *c, char *param, char *token ) {
577 	int par_no, i, j;
578 
579 	FUNCSTART
580 
581 	/* first, find the correct struct */
582 	for ( i=0; rel_param_entries[i].name; i++ ) {
583 		if ( !strcmp(rel_param_entries[i].name, param) ) {
584 #ifdef DEBUG
585 			fprintf(stderr, "canon_rel: updating parameter=%s.\n", rel_param_entries[i].name);
586 #endif
587 			par_no = i;
588 			break;
589 		}
590 	}
591 
592 	if ( !rel_param_entries[i].name ) {
593 		fprintf(stderr, "warning: rel parameter=%s -> no such parameter -> ignoring !!!\n", param);
594 		return;
595 	}
596 
597 	/* we have a valid parameter, maybe we need to load the parameter set from the camera first */
598 	if (!c->rel_params_filled)
599 		canon_get_rel_params(c);
600 
601 	/* lets see, what we should set the parameter to */
602 	for ( i=0; rel_param_entries[par_no].table[i].token; i++ ) {
603 		if ( !strcmp(rel_param_entries[par_no].table[i].token, token) ) {
604 #ifdef DEBUG
605 			fprintf(stderr, "canon_rel: setting %s=%s.\n", rel_param_entries[par_no].name, rel_param_entries[par_no].table[i].token);
606 #endif
607 			/* update entry/ies */
608 			for ( j=0; rel_param_entries[par_no].offset[j]; j++ ) {
609 				c->rel_params[(int)rel_param_entries[par_no].offset[j]] = rel_param_entries[par_no].table[i].code[j];
610 			}
611 			c->rel_params_updated = 1;
612 			break;
613 		}
614 	}
615 
616 	if ( !rel_param_entries[par_no].table[i].token )
617 		fprintf(stderr,"warning: %s=%s -> no such token -> ignoring !!!\n", rel_param_entries[par_no].name, token);
618 }
619 
canon_release_shutter(camera * c)620 void canon_release_shutter( camera *c ) {
621 	char buf[0x5c];
622 	char args[0x9];
623 
624 	FUNCSTART
625 
626 	if (c->rel_params_updated) {
627 		/* parameters have been changed, transmit them to camera before shooting */
628 		canon_set_rel_params(c);
629 	}
630 
631 	args[0] = 4;
632 	memset(args+1, 0, 8);
633 
634 	if ( IS_TYPE(c,"300D") || IS_TYPE(c,"10D") )
635 		usb_send_packet( c, 0x13, 0x12, 0x201, args, 8 );
636 	else
637 		usb_send_packet( c, 0x25, 0x12, 0x201, args, 9 );
638 
639 	usb_receive_packet(c, buf, sizeof(buf));
640 
641 /*	if ( CANON_CLASS(c) >= 6 && !IS_TYPE(c,"1D") ) {
642 		char buf2[0x54];
643 		char args2[4];
644 
645 		args2[0] = 0xf;
646 		memset(args2+1, 0, 3);
647 		usb_send_packet( c, 0x22, 0x12, 0x201, args2, 4 );
648 		usb_receive_packet(c, buf2, sizeof(buf2));
649 	}
650 */
651 	usb_bulk_read_bytes(c->h, c->bulk_int_in, buf, 0x10);
652 
653 	if ( c->thumb_to_pc ) {
654 		fprintf(stderr, "  THUMB_TO_PC not implemented!\n");
655 	}
656 
657 	if ( c->full_to_pc ) {
658 		unsigned idx, size;
659 
660 		if ( buf[0xc] != 0xc ) {
661 			fprintf(stderr,"Warning: FULL_TO_PC interrupt read error.\n");
662 		}
663 
664 		usb_bulk_read_bytes(c->h, c->bulk_int_in, buf, 0x17);
665 
666 		idx  = get_le32(buf+0xc);
667 		size = get_le32(buf+0x11);
668 		printf("  size = %u B\n", size);
669 
670 		if ( CANON_CLASS(c) != 6 ) /* 20D */
671 			usb_bulk_read_bytes(c->h, c->bulk_int_in, buf, 0x10);
672 
673 		{
674 			char recv[0x40];
675 			char args[0x10];
676 			char *img;
677 			unsigned read = 0, read_chunk, actually_read;
678 
679 			put_le32(args, 0);
680 /*			put_le32(&args[4], c->max_transfer); */
681 			put_le32(&args[4], 0x1400);
682 			put_le32(&args[8], 2); /* 1 - thumbnail, 2 - full image  */
683 			put_le32(&args[0xc], idx);
684 
685 			usb_send_packet( c, 0x17, 0x12, 0x202, args, sizeof(args) );
686 			usb_receive_packet(c, recv, sizeof(recv));
687 
688 			size = get_le32(&recv[6]);
689 			printf("  size = %u B\n", size);
690 
691 			img = calloc(size, 1);
692 /*			usb_bulk_read_bytes(c->h, c->bulk_in, img, 0x1400);
693 			usb_receive_packet(c, img, size);*/
694 
695 			do {
696 				if ( size - read > 0x1400 )
697 					read_chunk = 0x1400;
698 				else if ( size - read > 0x40 )
699 					read_chunk = (size - read) / 0x40 * 0x40;
700 				else
701 					read_chunk = size - read;
702 
703 				actually_read = usb_bulk_read(c->h, c->bulk_in, img + read, read_chunk, USB_TIMEOUT);
704 /*				usb_bulk_read_bytes(c->h, c->bulk_in, img + read, read_chunk);*/
705 
706 				if ( actually_read != read_chunk ) {
707 					fprintf(stderr, "Read error!\n");
708 					exit(1);
709 				}
710 
711 				read += read_chunk;
712 			} while ( read < size );
713 
714 			{
715 				FILE *f = fopen("img.jpg","wb");
716 				fwrite(img, size, 1, f);
717 				fclose(f);
718 			}
719 
720 			free(img);
721 		}
722 	}
723 
724 	if ( c->full_to_drive )	 {
725 		if ( buf[0xc] != 0x1c && (IS_TYPE(c,"300D") || IS_TYPE(c,"10D"))) {
726 			fprintf(stderr,"Warning: FULL_TO_DRIVE first interrupt read error.\n");
727 		}
728 
729 		if ( IS_TYPE(c,"300D") || IS_TYPE(c,"10D") ) {
730 			usb_bulk_read_bytes(c->h, c->bulk_int_in, buf, 0x10);
731 			if ( buf[0xc] != 0x1d ) {
732 				fprintf(stderr,"Warning: FULL_TO_DRIVE second interrupt read error.\n");
733 			}
734 		}
735 
736 		if ( IS_TYPE(c,"300D") ||  IS_TYPE(c,"10D") ) {
737 			usb_bulk_read_bytes(c->h, c->bulk_int_in, buf, 0x10);
738 			if ( buf[0x4] != 0xe ) {
739 				fprintf(stderr,"Warning: FULL_TO_DRIVE error saving image to CF.\n");
740 			}
741 		}
742 	}
743 
744 	if ( IS_EOS(c) && !(IS_TYPE(c,"300D") || IS_TYPE(c,"10D")) && !IS_TYPE(c,"350D") && !IS_TYPE(c,"5D") && !IS_TYPE(c,"20D"))
745 		usb_bulk_read_bytes(c->h, c->bulk_int_in, buf, 0x10);
746 
747 /*	if ( CANON_CLASS(c) >= 6 && !IS_TYPE(c,"1D") ) {
748 		char buf2[0x54];
749 		char args2[4];
750 
751 		args2[0] = 0xf;
752 		memset(args2+1, 0, 3);
753 		usb_send_packet( c, 0x21, 0x12, 0x201, args2, 4 );
754 		usb_receive_packet(c, buf2, sizeof(buf2));
755 	}
756 */
757 	c->rel_params_filled = 0;
758 }
759