1 /****************************************************************************
2 *
3 * File: serial.c
4 *
5 * Serial communication layer.
6 *
7 ****************************************************************************/
8
9 /****************************************************************************
10 *
11 * include files
12 *
13 ****************************************************************************/
14
15 #define _DEFAULT_SOURCE
16
17 #include "config.h"
18
19 #include <stdio.h>
20 #include <fcntl.h>
21 #include <string.h>
22 #include <sys/time.h>
23 #include <errno.h>
24 #include <stdlib.h>
25 #include <ctype.h>
26
27 #include <gphoto2/gphoto2.h>
28
29 #ifdef ENABLE_NLS
30 # include <libintl.h>
31 # undef _
32 # define _(String) dgettext (GETTEXT_PACKAGE, String)
33 # ifdef gettext_noop
34 # define N_(String) gettext_noop (String)
35 # else
36 # define N_(String) (String)
37 # endif
38 #else
39 # define textdomain(String) (String)
40 # define gettext(String) (String)
41 # define dgettext(Domain,Message) (Message)
42 # define dcgettext(Domain,Message,Type) (Message)
43 # define bindtextdomain(Domain,Directory) (Domain)
44 # define _(String) (String)
45 # define N_(String) (String)
46 #endif
47
48 #include "library.h"
49 #include "canon.h"
50 #include "serial.h"
51 #include "util.h"
52 #include "crc.h"
53
54 #ifndef MAX
55 # define MAX(a, b) ((a) > (b) ? (a) : (b))
56 #endif
57 #ifndef MIN
58 # define MIN(a, b) ((a) < (b) ? (a) : (b))
59 #endif
60
61
62 #ifdef __GNUC__
63 # define __unused__ __attribute__((unused))
64 #else
65 # define __unused__
66 #endif
67
68
69 /**
70 * serial_flush_input
71 * @gdev: serial port to use
72 *
73 * Dummy function.
74 *
75 */
76 static void
serial_flush_input(GPPort __unused__ * gdev)77 serial_flush_input (GPPort __unused__ *gdev)
78 {
79 }
80
81 /**
82 * serial_flush_output
83 * @gdev: serial port to use
84 *
85 * Dummy function.
86 *
87 */
88 static void
serial_flush_output(GPPort __unused__ * gdev)89 serial_flush_output (GPPort __unused__ *gdev)
90 {
91 }
92
93 /**
94 * canon_serial_change_speed
95 * @gdev: serial port to use
96 * @speed: the new speed
97 *
98 * Changes the speed of the communication.
99 *
100 * Returns: 1 on success.
101 * 0 on any error.
102 *
103 */
104
105 static int
canon_serial_change_speed(GPPort * gdev,int speed)106 canon_serial_change_speed (GPPort *gdev, int speed)
107 {
108 gp_port_settings settings;
109
110 /* set speed */
111 gp_port_get_settings (gdev, &settings);
112 settings.serial.speed = speed;
113 gp_port_set_settings (gdev, settings);
114
115 usleep (70000);
116
117 return 1;
118 }
119
120
121 /**
122 * canon_serial_get_cts
123 * @gdev: serial port to use
124 *
125 * Gets the status of the CTS (Clear To Send) line on the serial port.
126 *
127 * CTS is "1" when the camera is ON, and "0" when it is OFF.
128 *
129 * Returns: 1 on CTS high.
130 * 0 on CTS low.
131 *
132 */
133 #if 0
134 static int
135 canon_serial_get_cts (GPPort *gdev)
136 {
137 GPLevel level;
138
139 gp_port_get_pin (gdev, PIN_CTS, &level);
140 return (level);
141 }
142 #endif
143
144 /**
145 * canon_serial_init
146 * @camera: Camera object to initialize
147 *
148 * Initializes the given serial device by setting speed, parity, etc.
149 *
150 * Returns: %GP_OK
151 *
152 */
153
154 int
canon_serial_init(Camera * camera)155 canon_serial_init (Camera *camera)
156 {
157 GPPortSettings settings;
158
159 GP_DEBUG ("Initializing the (serial) camera.");
160
161 /* Get the current settings */
162 gp_port_get_settings (camera->port, &settings);
163
164 /* Adjust the current settings */
165 settings.serial.speed = 9600;
166 settings.serial.bits = 8;
167 settings.serial.parity = 0;
168 settings.serial.stopbits = 1;
169
170 /* Set the new settings */
171 gp_port_set_settings (camera->port, settings);
172
173 return GP_OK;
174 }
175
176 /**
177 * canon_serial_send
178 * @camera: Camera object to work with
179 * @buf: the raw data buffer to send
180 * @len: the length of the buffer
181 * @sleep: time in usec to wait between characters
182 *
183 * Send the given buffer with given length over the serial line.
184 *
185 * Returns: 0 on success, -1 on error.
186 *
187 */
188 static int
canon_serial_send(Camera * camera,const unsigned char * buf,int len,int sleep)189 canon_serial_send (Camera *camera, const unsigned char *buf, int len, int sleep)
190 {
191 int i;
192
193 /* the A50 does not like to get too much data in a row at 115200
194 * The S10 and S20 do not have this problem */
195 if (sleep > 0 && camera->pl->slow_send == 1) {
196 for (i = 0; i < len; i++) {
197 gp_port_write (camera->port, (char *) buf, 1);
198 buf++;
199 usleep (sleep);
200 }
201 } else {
202 gp_port_write (camera->port, (char *) buf, len);
203 }
204
205 return 0;
206 }
207
208
209 /**
210 * serial_set_timeout
211 * @gdev: serial port to use
212 * @to: timeout in milliseconds
213 *
214 * Sets the timeout, in miliseconds.
215 *
216 */
217 static void
serial_set_timeout(GPPort * gdev,int to)218 serial_set_timeout (GPPort *gdev, int to)
219 {
220 gp_port_set_timeout (gdev, to);
221 }
222
223 /**
224 * canon_serial_get_byte
225 * @gdev: serial port to use
226 *
227 * Gets the next byte from the serial line.
228 * Actually the function reads chunks of data and keeps them in a cache.
229 * Only one byte per call will be returned.
230 *
231 * Returns: the byte on success, -1 on error.
232 *
233 */
234 static int
canon_serial_get_byte(GPPort * gdev)235 canon_serial_get_byte (GPPort *gdev)
236 {
237 static unsigned char cache[512];
238 static unsigned char *cachep = cache;
239 static unsigned char *cachee = cache;
240 int recv;
241
242 /* if still data in cache, get it */
243 if (cachep < cachee) {
244 return (int) *cachep++;
245 }
246
247 recv = gp_port_read (gdev, (char *)cache, 1);
248 if (recv < 0) /* An error occurred */
249 return -1;
250
251 cachep = cache;
252 cachee = cache + recv;
253
254 if (recv) {
255 return (int) *cachep++;
256 }
257
258 return -1;
259 }
260
261 /* ------------------------- Frame-level processing ------------------------- */
262
263 /**
264 * canon_serial_send_frame
265 * @camera: Camera object to work with
266 * @pkt: Data to send to camera
267 * @len: Length of packet
268 *
269 * Sends a frame of data to camera
270 *
271 * Returns: 1 if canon_serial_send() succeeds, 0 if it fails
272 *
273 */
274 static int
canon_serial_send_frame(Camera * camera,const unsigned char * pkt,int len)275 canon_serial_send_frame (Camera *camera, const unsigned char *pkt, int len)
276 {
277 static unsigned char buffer[2100];
278
279 /* worst case: two maximum-sized packets (~1020 bytes, full of data
280 that needs to be escaped */
281 unsigned char *p;
282
283 p = buffer;
284 *p++ = CANON_FBEG;
285 while (len--) {
286 if (p < buffer ||
287 (unsigned int)(p - buffer) >= sizeof (buffer) - 1) {
288 GP_DEBUG ("FATAL ERROR: send buffer overflow");
289 return -1;
290 }
291 if (*pkt != CANON_FBEG && *pkt != CANON_FEND && *pkt != CANON_ESC)
292 *p++ = *pkt++;
293 else {
294 *p++ = CANON_ESC;
295 *p++ = *pkt++ ^ CANON_XOR;
296 }
297 }
298 *p++ = CANON_FEND;
299
300 return !canon_serial_send (camera, buffer, p - buffer, USLEEP2);
301 }
302
303 /**
304 * canon_serial_recv_frame
305 * @camera: Camera object to work with
306 * @len: to receive the length of the buffer
307 *
308 * Receive a frame from the camera
309 *
310 * Returns: a buffer containing a frame from the camera, or NULL on error.
311 * On success, @len will contain the length of the buffer.
312 *
313 */
314 static unsigned char *
canon_serial_recv_frame(Camera * camera,int * len)315 canon_serial_recv_frame (Camera *camera, int *len)
316 {
317 static unsigned char buffer[5000];
318
319 /* more than enough :-) (allow for a few run-together packets) */
320 unsigned char *p = buffer;
321 int c;
322
323 while ((c = canon_serial_get_byte (camera->port)) != CANON_FBEG) {
324 if (c == -1)
325 return NULL;
326 }
327 while ((c = canon_serial_get_byte (camera->port)) != CANON_FEND) {
328 if (c < 0)
329 return NULL;
330 if (c == CANON_ESC)
331 c = canon_serial_get_byte (camera->port) ^ CANON_XOR;
332 if (p < buffer ||
333 (unsigned int)(p - buffer) >= sizeof (buffer)) {
334 GP_DEBUG ("FATAL ERROR: receive buffer overflow");
335 return NULL;
336 }
337 *p++ = c;
338 }
339
340 GP_LOG_DATA ((char *)buffer, p - buffer, "RECV (without CANON_FBEG and CANON_FEND bytes)");
341
342 if (len)
343 *len = p - buffer;
344 return buffer;
345 }
346
347 /* ------------------------ Packet-level processing ------------------------- */
348
349 /**
350 * canon_serial_send_packet
351 * @camera: Camera object to work with
352 * @type:
353 * @seq:
354 * @pkt: data to send to camera
355 * @len: length of data
356 *
357 * frames a packet (generates CRC, packs with sequence number and
358 * length) and sends it to the camera through the serial port using
359 * canon_serial_send_frame().
360 *
361 * Returns: status from canon_serial_send_frame()
362 *
363 */
364 static int
canon_serial_send_packet(Camera * camera,unsigned char type,unsigned char seq,unsigned char * pkt,int len)365 canon_serial_send_packet (Camera *camera, unsigned char type, unsigned char seq,
366 unsigned char *pkt, int len)
367 {
368 unsigned char *hdr = pkt - PKT_HDR_LEN;
369 int crc;
370
371 hdr[PKT_TYPE] = type;
372 hdr[PKT_SEQ] = seq;
373 hdr[PKT_LEN_LSB] = len & 0xff;
374 hdr[PKT_LEN_MSB] = len >> 8;
375
376 if (type == PKT_NACK) {
377 hdr[PKT_TYPE] = PKT_ACK;
378 hdr[PKT_TYPE + 1] = '\xff'; /* PKTACK_NACK; */
379 }
380
381 if (type == PKT_UPLOAD_EOT) {
382 hdr[PKT_TYPE] = PKT_EOT;
383 hdr[PKT_TYPE + 1] = 0x3;
384 len = 2;
385 }
386
387 if (type == PKT_EOT || type == PKT_ACK || type == PKT_NACK)
388 len = 2; /* @@@ hack */
389 crc = canon_psa50_gen_crc (hdr, len + PKT_HDR_LEN);
390 if (crc == -1)
391 return GP_ERROR;
392 pkt[len] = crc & 0xff;
393 pkt[len + 1] = crc >> 8;
394
395 return canon_serial_send_frame (camera, hdr, len + PKT_HDR_LEN + 2);
396 }
397
398 /**
399 * canon_serial_recv_packet
400 * @camera: Camera object to work with
401 * @type: Type of packet
402 * @seq: Sequence number of packet
403 * @len: length of data received
404 *
405 * Receives a packet from the serial port using
406 * canon_serial_send_frame(), decodes frame information (type,
407 * sequence number, and length), and returns it stripped of frame
408 * information.
409 *
410 * Returns: packet data (or NULL if failure). Type in @type, sequence
411 * number in @seq, and length in @len.
412 *
413 */
414 static unsigned char *
canon_serial_recv_packet(Camera * camera,unsigned char * type,unsigned char * seq,int * len)415 canon_serial_recv_packet (Camera *camera, unsigned char *type, unsigned char *seq, int *len)
416 {
417 unsigned char *pkt;
418 unsigned short crc;
419 int raw_length, length = 0;
420
421 pkt = canon_serial_recv_frame (camera, &raw_length);
422 if (!pkt)
423 return NULL;
424 if (raw_length < PKT_HDR_LEN) {
425 GP_DEBUG ("ERROR: packet truncated");
426 return NULL;
427 }
428 if (pkt[PKT_TYPE] == PKT_MSG) {
429 length = pkt[PKT_LEN_LSB] | (pkt[PKT_LEN_MSB] << 8);
430 if (length + PKT_HDR_LEN > raw_length - 2) {
431 GP_DEBUG ("ERROR: invalid length");
432 /*fprintf(stderr,"Sending NACK");
433 canon_serial_send_packet(PKT_NACK,camera->pl->seq_rx++,camera->pl->psa50_eot+PKT_HDR_LEN,0); */
434 camera->pl->receive_error = ERROR_RECEIVED;
435 return NULL;
436 }
437 }
438 crc = pkt[raw_length - 2] | (pkt[raw_length - 1] << 8);
439 if (!canon_psa50_chk_crc (pkt, raw_length - 2, crc)) {
440 GP_DEBUG ("ERROR: CRC error");
441 return NULL;
442 }
443 *type = pkt[PKT_TYPE];
444 if (seq)
445 *seq = pkt[PKT_SEQ];
446 if (len)
447 *len = length;
448 if (*type == PKT_ACK || *type == PKT_EOT)
449 return pkt;
450 return pkt + PKT_HDR_LEN;
451 }
452
453 /* ----------------------- Message-level processing ------------------------ */
454
455
456 /**
457 * canon_serial_wait_for_ack
458 * @camera: Camera object to work with
459 *
460 * Waits for an "ACK" from the camera.
461 *
462 * Returns:
463 * 1 : ACK received
464 * 0 : communication error (no reply received for example)
465 * -1 : NACK received.
466 */
467 static int
canon_serial_wait_for_ack(Camera * camera)468 canon_serial_wait_for_ack (Camera *camera)
469 {
470 unsigned char *pkt;
471 unsigned char type, seq, old_seq;
472 int len;
473
474 while (1) {
475 pkt = canon_serial_recv_packet (camera, &type, &seq, &len);
476 if (!pkt)
477 return 0;
478 if (seq == camera->pl->seq_tx && type == PKT_ACK) {
479 if (pkt[2] == PKTACK_NACK) {
480 GP_DEBUG ("ERROR: NACK received");
481 return -1;
482 }
483 camera->pl->seq_tx++;
484 return 1;
485 }
486 old_seq = '\0';
487 if (type == PKT_EOT) {
488 old_seq = pkt[0];
489 if (camera->pl->receive_error == NOERROR) {
490 GP_DEBUG ("Old EOT received, sending corresponding ACK");
491 if (!canon_serial_send_packet
492 (camera, PKT_ACK, old_seq,
493 camera->pl->psa50_eot + PKT_HDR_LEN, 0))
494 return 0;
495 pkt = canon_serial_recv_packet (camera, &type, &seq, &len);
496 if (!pkt)
497 return 0;
498 if (seq == old_seq && type == PKT_ACK) {
499 if (pkt[2] == PKTACK_NACK) {
500 GP_DEBUG ("Old EOT acknowledged");
501 return -1;
502 }
503 return 1;
504 }
505 }
506 }
507 /* error already aknowledged, we skip the following ones */
508 if (camera->pl->receive_error == ERROR_RECEIVED) {
509 if (!canon_serial_send_packet
510 (camera, PKT_NACK, old_seq, camera->pl->psa50_eot + PKT_HDR_LEN,
511 0))
512 return 0;
513 return 1;
514 }
515
516 GP_DEBUG ("ERROR: ACK format or sequence error, retrying");
517 GP_DEBUG ("Sending NACK");
518 canon_serial_send_packet (camera, PKT_NACK, camera->pl->seq_rx++,
519 camera->pl->psa50_eot + PKT_HDR_LEN, 0);
520 camera->pl->receive_error = ERROR_RECEIVED;
521
522 /*
523 * just keep on trying. protocol seems to retransmit EOTs, so we may get
524 * some old EOTs when we're actually expecting ACKs.
525 */
526 }
527 }
528
529 /**
530 * canon_serial_send_msg
531 * @camera: Camera object to work with
532 * @mtype: message type.
533 * @dir: direction.
534 * @ap: message payload (list of arguments, see 'man va_start'
535 *
536 * Sends a message to the camera.
537 *
538 * Returns:
539 * -1 on error
540 * 0 if canon_serial_send_packet() fails
541 * 1 on good ACK received
542 */
543 static int
canon_serial_send_msg(Camera * camera,unsigned char mtype,unsigned char dir,va_list * ap)544 canon_serial_send_msg (Camera *camera, unsigned char mtype, unsigned char dir, va_list * ap)
545 {
546 unsigned char buffer[MAX_PKT_PAYLOAD + 2]; /* allow space for CRC */
547 unsigned char upload_buffer[MAX_PKT_PAYLOAD + 2];
548 unsigned char *pkt, *pkt2, *pos;
549 int total, good_ack, try;
550
551 memset (buffer, 0, PKT_HDR_LEN + MSG_HDR_LEN);
552
553 pkt = buffer + PKT_HDR_LEN;
554 pkt[MSG_02] = 2;
555 pkt[MSG_MTYPE] = mtype;
556 pkt[MSG_DIR] = dir;
557
558 pos = pkt + MSG_HDR_LEN;
559 total = 0;
560
561 while (1) {
562 const unsigned char *str;
563 int len;
564
565 str = va_arg (*ap, unsigned char *);
566
567 if (!str)
568 break;
569 len = va_arg (*ap, int);
570
571 if (pos + len - pkt > MAX_MSG_SIZE && camera->pl->uploading != 1) {
572 GP_DEBUG ("FATAL ERROR: message too big (%i)", (int)(pos + len - pkt));
573 return -1;
574 }
575 memcpy (pos, str, len);
576 pos += len;
577 }
578
579 total = pos - pkt;
580
581 pkt[MSG_LEN_LSB] = total & 0xff;
582 pkt[MSG_LEN_MSB] = total >> 8;
583
584 if (camera->pl->uploading == 1) {
585 memset (upload_buffer, 0, PKT_HDR_LEN + MSG_HDR_LEN);
586 pkt2 = upload_buffer;
587 memcpy (pkt2, pkt + UPLOAD_DATA_BLOCK, total - UPLOAD_DATA_BLOCK);
588 for (try = 0; try < MAX_TRIES; try++) {
589 canon_serial_send_packet (camera, PKT_MSG, 0, pkt, UPLOAD_DATA_BLOCK);
590 canon_serial_send_packet (camera, PKT_MSG, 0x1, pkt2,
591 total - UPLOAD_DATA_BLOCK);
592 if (!canon_serial_send_packet
593 (camera, PKT_UPLOAD_EOT, camera->pl->seq_tx,
594 camera->pl->psa50_eot + PKT_HDR_LEN, 1))
595 return 0;
596 if (!canon_serial_send_packet
597 (camera, PKT_UPLOAD_EOT, camera->pl->seq_tx,
598 camera->pl->psa50_eot + PKT_HDR_LEN, 1))
599 return 0;
600
601 good_ack = canon_serial_wait_for_ack (camera);
602 if (good_ack == 1)
603 return good_ack;
604 }
605 return -1;
606 } else {
607 pkt[MSG_LEN_LSB] = total & 0xff;
608 pkt[MSG_LEN_MSB] = total >> 8;
609 for (try = 1; try < MAX_TRIES; try++) {
610 if (!canon_serial_send_packet (camera, PKT_MSG, 0, pkt, total))
611 return 0;
612 if (!canon_serial_send_packet
613 (camera, PKT_EOT, camera->pl->seq_tx,
614 camera->pl->psa50_eot + PKT_HDR_LEN, 1))
615 return 0;
616 good_ack = canon_serial_wait_for_ack (camera);
617 if (good_ack == -1) {
618 GP_DEBUG ("NACK received, retrying command");
619 } else if (good_ack == 1) {
620 return good_ack;
621 } else {
622 GP_DEBUG ("No ACK received, retrying command");
623 if (try == 2) {
624 /* is the camera still there? */
625 if (!canon_serial_send_packet
626 (camera, PKT_EOT, camera->pl->seq_tx,
627 camera->pl->psa50_eot + PKT_HDR_LEN, 0))
628 return 0;
629 good_ack = canon_serial_wait_for_ack (camera);
630 if (good_ack == 0) {
631 camera->pl->receive_error = FATAL_ERROR;
632 GP_DEBUG ("ERROR: FATAL ERROR");
633 clear_readiness (camera);
634 return -1;
635 }
636 }
637 }
638 }
639 return -1;
640 }
641 }
642
643 /**
644 * canon_serial_recv_msg
645 * @camera: Camera object to work with
646 * @mtype: message type.
647 * @dir: direction.
648 * @total: payload length (set by this function).
649 * @context: context for error reporting
650 *
651 * Receives a message from the camera.
652 *
653 * See the "Protocol" file for an explanation of the various
654 * elements needed to handle a message.
655 *
656 * Returns:
657 * char* pointer to the message payload; NULL on failure.
658 *
659 */
660 static unsigned char *
canon_serial_recv_msg(Camera * camera,unsigned char mtype,unsigned char dir,unsigned int * total,GPContext * context)661 canon_serial_recv_msg (Camera *camera, unsigned char mtype, unsigned char dir, unsigned int *total,
662 GPContext *context)
663 {
664 static unsigned char *msg = NULL;
665 static int msg_size = 512; /* initial allocation/2 */
666 unsigned char *frag;
667 unsigned char type, seq;
668 int len, length = 0, msg_pos = 0;
669
670 while (1) {
671 frag = canon_serial_recv_packet (camera, &type, NULL, &len);
672 if (!frag)
673 return NULL;
674 if (type == PKT_MSG)
675 break;
676 /* uploading is special */
677 /* if (type == PKT_ACK && mtype == 0x3 && dir == 0x21) break; */
678 if (type == PKT_EOT) {
679 GP_DEBUG ("Old EOT received sending corresponding ACK");
680 canon_serial_send_packet (camera, PKT_ACK, frag[0],
681 camera->pl->psa50_eot + PKT_HDR_LEN, 0);
682 }
683 GP_DEBUG ("ERROR: protocol error, retrying");
684 }
685 /* we keep the fragment only if there was no error */
686 if (camera->pl->receive_error == NOERROR) {
687 length = frag[MSG_LEN_LSB] | (frag[MSG_LEN_MSB] << 8);
688 /* while uploading we expect 2 ACKs and a message 0x3 0x21
689 * not always in the same order */
690 /*
691 if (type == PKT_ACK && mtype == 0x3 && dir == 0x21) {
692 GP_DEBUG("ignoring ACK received while waiting for MSG");
693 return frag;
694 }
695 */
696 if (len < MSG_HDR_LEN || frag[MSG_02] != 2) {
697 GP_DEBUG ("ERROR: message format error");
698 return NULL;
699 }
700
701 if (frag[MSG_MTYPE] != mtype || frag[MSG_DIR] != dir) {
702 if (frag[MSG_MTYPE] == '\x01' && frag[MSG_DIR] == '\x00'
703 && memcmp (frag + 12, "\x30\x00\x00\x30", 4)) {
704 gp_context_error (context,
705 _("Battery exhausted, camera off."));
706 camera->pl->receive_error = ERROR_LOWBATT;
707 } else {
708 gp_context_error (context, _("ERROR: unexpected message"));
709 }
710 return NULL;
711 }
712 frag += MSG_HDR_LEN;
713 len -= MSG_HDR_LEN;
714 }
715 while (1) {
716 if (camera->pl->receive_error == NOERROR) {
717 if (msg_pos + len > length) {
718 gp_context_error (context, _("ERROR: message overrun"));
719 return NULL;
720 }
721 if (msg_pos + len > msg_size || !msg) {
722 msg_size *= 2;
723 msg = realloc (msg, msg_size);
724 if (!msg)
725 return NULL;
726 }
727 memcpy (msg + msg_pos, frag, len);
728 msg_pos += len;
729 }
730 frag = canon_serial_recv_packet (camera, &type, &seq, &len);
731 if (!frag)
732 return NULL;
733 if (type == PKT_EOT) {
734 /* in case of error we don't want to stop as the camera will send
735 the 1st packet of the sequence again */
736 if (camera->pl->receive_error == ERROR_RECEIVED) {
737 camera->pl->seq_rx = seq;
738 canon_serial_send_packet (camera, PKT_NACK, camera->pl->seq_rx,
739 camera->pl->psa50_eot + PKT_HDR_LEN,
740 0);
741 camera->pl->receive_error = ERROR_ADDRESSED;
742 } else {
743 if (seq == camera->pl->seq_rx)
744 break;
745 gp_context_error (context, _("ERROR: out of sequence."));
746 return NULL;
747 }
748 }
749 if (type != PKT_MSG && camera->pl->receive_error == NOERROR) {
750 gp_context_error (context, _("ERROR: unexpected packet type."));
751 return NULL;
752 }
753 if (type == PKT_EOT && camera->pl->receive_error == ERROR_RECEIVED) {
754 camera->pl->receive_error = ERROR_ADDRESSED;
755 }
756 if (type == PKT_MSG && camera->pl->receive_error == ERROR_ADDRESSED) {
757 msg_pos = 0;
758 length = frag[MSG_LEN_LSB] | (frag[MSG_LEN_MSB] << 8);
759 if (len < MSG_HDR_LEN || frag[MSG_02] != 2) {
760 gp_context_error (context, _("ERROR: message format error."));
761 return NULL;
762 }
763
764 if (frag[MSG_MTYPE] != mtype || frag[MSG_DIR] != dir) {
765 if (frag[MSG_MTYPE] == '\x01' && frag[MSG_DIR] == '\x00'
766 && memcmp (frag + 12, "\x30\x00\x00\x30", 4)) {
767 gp_context_error (context,
768 _("Battery exhausted, camera off."));
769 camera->pl->receive_error = ERROR_LOWBATT;
770 } else {
771 gp_context_error (context,
772 _("ERROR: unexpected message2."));
773 }
774 return NULL;
775 }
776 frag += MSG_HDR_LEN;
777 len -= MSG_HDR_LEN;
778 camera->pl->receive_error = NOERROR;
779 }
780 }
781 if (camera->pl->receive_error == ERROR_ADDRESSED) {
782 camera->pl->receive_error = NOERROR;
783 }
784 if (camera->pl->receive_error == NOERROR) {
785 /*we want to be sure the camera U N D E R S T A N D S our packets */
786 if (camera->pl->uploading == 1 && camera->pl->md->model == CANON_CLASS_1)
787 camera->pl->slow_send = 1;
788 if (!canon_serial_send_packet
789 (camera, PKT_ACK, camera->pl->seq_rx++,
790 camera->pl->psa50_eot + PKT_HDR_LEN, 0)) {
791 if (camera->pl->uploading == 1
792 && camera->pl->md->model == CANON_CLASS_1)
793 camera->pl->slow_send = 0;
794 return NULL;
795 }
796 if (camera->pl->uploading == 1 && camera->pl->md->model == CANON_CLASS_1)
797 camera->pl->slow_send = 0;
798 if (total)
799 *total = msg_pos;
800 return msg;
801 }
802
803 return NULL;
804 }
805
806 /**
807 * canon_serial_dialogue:
808 * @camera: camera with which to communicate
809 * @context: context for error reporting
810 * @mtype : type
811 * @dir : direction
812 * @len : length of the received payload
813 * @Varargs: The rest of the arguments will be put together to
814 * fill up the payload of the request message.
815 *
816 * Higher level function: sends a message and waits for a
817 * reply from the camera.
818 *
819 * Payload: each argument after "len" goes by 2: the variable itself,
820 * and the next argument has to be its length. You also have to finish
821 * the list by a "NULL".
822 *
823 * Example: To send a string called "name" :
824 * canon_serial_dialogue(0x05,0x12,&len,name,strlen(name)+1,NULL);
825 *
826 * Returns: buffer received from canon_serial_recv_msg(), NULL if failure
827 *
828 */
829 unsigned char *
canon_serial_dialogue(Camera * camera,GPContext * context,unsigned char mtype,unsigned char dir,unsigned int * len,...)830 canon_serial_dialogue (Camera *camera, GPContext *context, unsigned char mtype,
831 unsigned char dir, unsigned int *len, ...)
832 {
833 va_list ap;
834 int okay, try;
835 unsigned char *good_ack;
836
837 for (try = 1; try < MAX_TRIES; try++) {
838 va_start (ap, len);
839 okay = canon_serial_send_msg (camera, mtype, dir, &ap);
840 va_end (ap);
841 if (!okay)
842 return NULL;
843 /* while uploading we receive 2 ACKs and 1 confirmation message
844 * The first ACK has already been received if we are here */
845 if (camera->pl->uploading == 1) {
846 camera->pl->seq_tx--;
847 good_ack =
848 canon_serial_recv_msg (camera, mtype, dir ^ DIR_REVERSE, len,
849 context);
850 if (!good_ack)
851 return NULL;
852 if (good_ack[0] == camera->pl->seq_tx && good_ack[1] == 0x5) {
853 GP_DEBUG ("ACK received waiting for the confirmation message");
854 good_ack =
855 canon_serial_recv_msg (camera, mtype,
856 dir ^ DIR_REVERSE, len,
857 context);
858 } else {
859 okay = canon_serial_wait_for_ack (camera);
860 if (okay == 1)
861 return good_ack;
862 }
863 } else
864 good_ack =
865 canon_serial_recv_msg (camera, mtype, dir ^ DIR_REVERSE, len,
866 context);
867
868 if (good_ack)
869 return good_ack;
870 if (camera->pl->receive_error == NOERROR) {
871 GP_DEBUG ("Resending message...");
872 camera->pl->seq_tx--;
873 }
874 if (camera->pl->receive_error == FATAL_ERROR)
875 break;
876 }
877 return NULL;
878 }
879
880 /* ----------------------- Command-level processing ------------------------ */
881
882
883 /**
884 * canon_serial_end:
885 * @camera: the camera to switch off
886 *
887 * Switches the @camera off
888 *
889 * Returns: %GP_OK
890 *
891 */
892 #if 0
893 static int
894 canon_serial_end (Camera *camera)
895 {
896 canon_serial_send (camera, (unsigned char *)"\xC0\x00\x02\x55\x2C\xC1", 6, USLEEP2);
897 canon_serial_send (camera, (unsigned char *)"\xC0\x00\x04\x01\x00\x00\x00\x24\xC6\xC1", 8, USLEEP2);
898 return GP_OK;
899 }
900 #endif
901
902 /**
903 * canon_serial_off:
904 * @camera: the camera to switch off
905 *
906 * Switches the #camera off, and resets the serial driver to 9600 bauds,
907 * in order to be ready to switch the camera back on again if wanted.
908 * Should better be named psa50_serial_off
909 *
910 * Returns: %GP_OK
911 *
912 */
913 int
canon_serial_off(Camera * camera)914 canon_serial_off (Camera *camera)
915 {
916 canon_serial_send (camera, (unsigned char *)"\xC0\x00\x02\x55\x2C\xC1", 6, USLEEP2);
917 canon_serial_send (camera, (unsigned char *)"\xC0\x00\x04\x01\x00\x00\x00\x24\xC6\xC1", 8, USLEEP2);
918 canon_serial_change_speed (camera->port, 9600);
919 return GP_OK;
920 }
921
922
923
924 /**
925 * canon_serial_error_type
926 * @camera: Camera object to work with
927 *
928 * logs a debug message corresponding
929 * to the error encountered
930 *
931 */
932 void
canon_serial_error_type(Camera * camera)933 canon_serial_error_type (Camera *camera)
934 {
935 switch (camera->pl->receive_error) {
936 case ERROR_LOWBATT:
937 GP_DEBUG ("ERROR: no battery left, Bailing out!");
938 break;
939 case FATAL_ERROR:
940 GP_DEBUG ("ERROR: camera connection lost!");
941 break;
942 default:
943 GP_DEBUG ("ERROR: malformed message");
944 break;
945 }
946 }
947
948 /**
949 * canon_serial_put_file
950 * @camera: Camera object to work with
951 * @file: CameraFile object to upload
952 * @destname: name file should have on camera
953 * @destpath: pathname for directory to put file
954 * @context: context for error reporting
955 *
956 * Uploads file to @camera via serial port
957 *
958 * Returns: gphoto2 error code
959 *
960 */
961 int
canon_serial_put_file(Camera * camera,CameraFile * file,const char * name,const char * destname,const char * destpath,GPContext * context)962 canon_serial_put_file (Camera *camera, CameraFile *file, const char *name, const char *destname, const char *destpath,
963 GPContext *context)
964 {
965 unsigned char *msg;
966 char buf[4096];
967 int offset = 0;
968 char offset2[4];
969 int block_len;
970 char block_len2[4];
971 unsigned int sent = 0;
972 int i, j = 0;
973 unsigned int len;
974 unsigned long int size;
975 const char *data;
976 unsigned int id;
977
978 camera->pl->uploading = 1;
979
980 gp_file_get_data_and_size (file, &data, &size);
981
982 id = gp_context_progress_start (context, size, _("Uploading file..."));
983 while (sent < size) {
984
985 if (size < DATA_BLOCK)
986 block_len = size;
987 else if ((size - sent < DATA_BLOCK))
988 block_len = size - sent;
989 else
990 block_len = DATA_BLOCK;
991
992 offset = sent;
993
994 for (i = 0; i < 4; i++) {
995 offset2[i] = (offset >> (8 * i)) & 0xff;
996 block_len2[i] = (block_len >> (8 * i)) & 0xff;
997 }
998
999 for (i = 0; i < DATA_BLOCK; i++) {
1000 buf[i] = data[j];
1001 j++;
1002 }
1003
1004 msg = canon_serial_dialogue (camera, context, 0x3, 0x11, &len,
1005 "\x02\x00\x00\x00", 4, offset2, 4, block_len2, 4,
1006 destpath, strlen (destpath), destname,
1007 strlen (destname) + 1, buf, block_len, NULL);
1008 if (!msg) {
1009 camera->pl->uploading = 0;
1010 return GP_ERROR;
1011 }
1012 sent += block_len;
1013 gp_context_progress_update (context, id, sent);
1014 }
1015 gp_context_progress_stop (context, id);
1016 camera->pl->uploading = 0;
1017 return GP_OK;
1018 }
1019
1020 /**
1021 * canon_serial_get_file:
1022 * @camera: camera to lock keys on
1023 * @name: name of file to fetch
1024 * @length: to receive length of image data
1025 * @context: context for error reporting
1026 *
1027 * Get a file from a USB_connected Canon camera.
1028 *
1029 * Returns: buffer containing file data (or NULL on failure); length
1030 * in @length.
1031 *
1032 */
1033 unsigned char *
canon_serial_get_file(Camera * camera,const char * name,unsigned int * length,GPContext * context)1034 canon_serial_get_file (Camera *camera, const char *name, unsigned int *length, GPContext *context)
1035 {
1036 unsigned char *file = NULL;
1037 unsigned char *msg;
1038 unsigned char name_len;
1039 unsigned int total = 0, expect = 0, size, id;
1040 unsigned int len;
1041
1042 if (camera->pl->receive_error == FATAL_ERROR) {
1043 GP_DEBUG ("ERROR: can't continue a fatal error condition detected");
1044 return NULL;
1045 }
1046 name_len = strlen (name) + 1;
1047 msg = canon_serial_dialogue (camera, context, 0x1, 0x11, &len, "\x00\x00\x00\x00", 5,
1048 &name_len, 1, "\x00", 2, name, strlen (name) + 1, NULL);
1049 if (!msg) {
1050 canon_serial_error_type (camera);
1051 return NULL;
1052 }
1053 id = gp_context_progress_start (context, le32atoh (msg + 4), _("Getting file..."));
1054 while (msg) {
1055 if (len < 20 || le32atoh (msg)) {
1056 break;
1057 }
1058 if (!file) {
1059 total = le32atoh (msg + 4);
1060
1061 if (total > camera->pl->md->max_picture_size) {
1062 GP_DEBUG ("ERROR: %d is too big", total);
1063 break;
1064 }
1065 file = malloc (total);
1066 if (!file) {
1067 perror ("malloc");
1068 break;
1069 }
1070 if (length)
1071 *length = total;
1072 }
1073 size = le32atoh (msg + 12);
1074 if (le32atoh (msg + 8) != expect || expect + size > total || size > len - 20) {
1075 GP_DEBUG ("ERROR: doesn't fit");
1076 break;
1077 }
1078 memcpy (file + expect, msg + 20, size);
1079 expect += size;
1080 gp_context_progress_update (context, id, expect);
1081 if ((expect == total) != le32atoh (msg + 16)) {
1082 GP_DEBUG ("ERROR: end mark != end of data");
1083 break;
1084 }
1085 if (expect == total) {
1086 gp_context_progress_stop (context, id);
1087 return file;
1088 }
1089 msg = canon_serial_recv_msg (camera, 0x1, 0x21, &len, context);
1090 }
1091 free (file);
1092 file = NULL;
1093 return NULL;
1094 }
1095
1096 /**
1097 * canon_serial_get_dirents:
1098 * @camera: camera to initialize
1099 * @dirent_data: to receive directory data
1100 * @dirents_length: to receive length of @dirent_data
1101 * @path: pathname of directory to list
1102 * @context: context for error reporting
1103 *
1104 * Lists a directory.
1105 *
1106 * Returns: gphoto2 error code
1107 *
1108 */
1109 int
canon_serial_get_dirents(Camera * camera,unsigned char ** dirent_data,unsigned int * dirents_length,const char * path,GPContext * context)1110 canon_serial_get_dirents (Camera *camera, unsigned char **dirent_data,
1111 unsigned int *dirents_length, const char *path, GPContext *context)
1112 {
1113 unsigned char *p, *temp_ch, *data = NULL;
1114 unsigned int mallocd_bytes, total_size;
1115
1116 *dirent_data = NULL;
1117
1118 /* fetch all directory entries, the first one is a little special */
1119 p = canon_serial_dialogue (camera, context, 0xb, 0x11, dirents_length, "", 1, path,
1120 strlen (path) + 1, "\x00", 2, NULL);
1121 if (p == NULL) {
1122 gp_context_error (context,
1123 _("canon_serial_get_dirents: "
1124 "canon_serial_dialogue failed to fetch directory entries"));
1125 return GP_ERROR;
1126 }
1127
1128 /* In the RS232 implementation, we should never get less than 5 bytes */
1129 if (*dirents_length < 5) {
1130 gp_context_error (context,
1131 _("canon_serial_get_dirents: "
1132 "Initial dirent packet too short (only %i bytes)"),
1133 *dirents_length);
1134 return GP_ERROR;
1135 }
1136
1137 GP_LOG_DATA ((char *)p, *dirents_length,
1138 "canon_serial_get_dirents: "
1139 "dirent packet received from canon_serial_dialogue:");
1140
1141 /* the first five bytes is only for the RS232 implementation
1142 * of this command, we do not need to copy them so therefore
1143 * we don't need to malloc() them either
1144 */
1145 mallocd_bytes = MAX (1024, *dirents_length - 5);
1146 data = malloc (mallocd_bytes);
1147 if (!data) {
1148 gp_context_error (context,
1149 _("canon_serial_get_dirents: "
1150 "Could not allocate %i bytes of memory"), mallocd_bytes);
1151 return GP_ERROR_NO_MEMORY;
1152 }
1153
1154 /* the first five bytes is only for the RS232 implementation
1155 * of this command, do not copy them
1156 */
1157 memcpy (data, p + 5, (*dirents_length - 5));
1158 total_size = *dirents_length;
1159
1160 /* p[4] indicates this is not the last packet,
1161 * read additional packets until there are no more
1162 * directory entries to read
1163 */
1164 while (!p[4]) {
1165 GP_DEBUG ("p[4] is %i", (int) p[4]);
1166 p = canon_serial_recv_msg (camera, 0xb, 0x21, dirents_length, context);
1167 if (p == NULL) {
1168 gp_context_error (context,
1169 _("canon_serial_get_dirents: "
1170 "Failed to read another directory entry"));
1171 free (data);
1172 data = NULL;
1173 return GP_ERROR;
1174 }
1175
1176 GP_LOG_DATA ((char *)p, *dirents_length,
1177 "canon_serial_get_dirents: "
1178 "dirent packet received from canon_serial_recv_msg:");
1179
1180 /* the first five bytes is only for the RS232 implementation,
1181 * don't count them when checking dirent size
1182 */
1183 if (*dirents_length - 5 < CANON_MINIMUM_DIRENT_SIZE) {
1184 gp_context_error (context,
1185 _("canon_serial_get_dirents: "
1186 "Truncated directory entry received"));
1187 free (data);
1188 data = NULL;
1189 return GP_ERROR;
1190 }
1191
1192 /* check if we need to allocate some more memory,
1193 * the first five bytes is only for the RS232
1194 * implementation of this command, don't need to
1195 * malloc for them. note that we ensured earlier in this
1196 * function that *dirents_length >= 5.
1197 */
1198 if (total_size + (unsigned int)(*dirents_length - 5) > mallocd_bytes) {
1199 /* we allocate 1024 bytes chunks instead
1200 * of the exact number of bytes needed.
1201 * this is OK since we will free this
1202 * before returning from canon_int_list_directory
1203 * (our caller).
1204 */
1205 mallocd_bytes += MAX (1024, *dirents_length);
1206
1207 /* check if we are reading unrealistic ammounts
1208 * of directory entries so that we don't loop
1209 * forever. 1024 * 1024 is picked out of the blue.
1210 */
1211 if (mallocd_bytes > 1024 * 1024) {
1212 gp_context_error (context,
1213 _("canon_serial_get_dirents: "
1214 "Too many dirents, we must be looping."));
1215 free (data);
1216 data = NULL;
1217 return GP_ERROR;
1218 }
1219
1220 temp_ch = realloc (data, mallocd_bytes);
1221 if (!temp_ch) {
1222 gp_context_error (context,
1223 _("canon_serial_get_dirents: "
1224 "Could not resize dirent buffer "
1225 "to %i bytes"), mallocd_bytes);
1226 free (data);
1227 data = NULL;
1228 return GP_ERROR;
1229 }
1230 data = temp_ch;
1231 }
1232
1233 /* the first five bytes is only for the RS232
1234 * implementation of this command, don't copy them.
1235 */
1236 memcpy (data + total_size, p + 5, (*dirents_length - 5));
1237 total_size += (*dirents_length - 5);
1238 }
1239 GP_DEBUG ("OK - this was last dirent");
1240
1241 *dirent_data = data;
1242 return GP_OK;
1243 }
1244
1245 /**
1246 * canon_serial_ready:
1247 * @camera: camera to get ready
1248 * @context: context for error reporting
1249 *
1250 * serial part of canon_int_ready
1251 *
1252 * Returns: gphoto2 error code
1253 *
1254 */
1255 int
canon_serial_ready(Camera * camera,GPContext * context)1256 canon_serial_ready (Camera *camera, GPContext *context)
1257 {
1258 unsigned char type, seq;
1259 int good_ack, speed, try, len, i;
1260 unsigned char *pkt;
1261 int res;
1262 char cam_id_str[2000];
1263 unsigned int id;
1264
1265 GP_DEBUG ("canon_int_ready()");
1266
1267 serial_set_timeout (camera->port, 900); /* 1 second is the delay for awakening the camera */
1268 serial_flush_input (camera->port);
1269 serial_flush_output (camera->port);
1270
1271 camera->pl->receive_error = NOERROR;
1272
1273 /* First of all, we must check if the camera is already on */
1274 /* cts=canon_serial_get_cts();
1275 GP_DEBUG("cts : %i",cts);
1276 if (cts==32) { CTS == 32 when the camera is connected. */
1277 if (camera->pl->first_init == 0 && camera->pl->cached_ready == 1) {
1278 /* First case, the serial speed of the camera is the same as
1279 * ours, so let's try to send a ping packet : */
1280 if (!canon_serial_send_packet
1281 (camera, PKT_EOT, camera->pl->seq_tx, camera->pl->psa50_eot + PKT_HDR_LEN,
1282 0))
1283 return GP_ERROR;
1284 good_ack = canon_serial_wait_for_ack (camera);
1285 GP_DEBUG ("good_ack = %i", good_ack);
1286 if (good_ack == 0) {
1287 /* no answer from the camera, let's try
1288 * at the speed saved in the settings... */
1289 speed = camera->pl->speed;
1290 if (speed != 9600) {
1291 if (!canon_serial_change_speed (camera->port, speed)) {
1292 gp_context_error (context, _("Error changing speed."));
1293 }
1294 }
1295 if (!canon_serial_send_packet
1296 (camera, PKT_EOT, camera->pl->seq_tx,
1297 camera->pl->psa50_eot + PKT_HDR_LEN, 0))
1298 return GP_ERROR;
1299 good_ack = canon_serial_wait_for_ack (camera);
1300 if (good_ack == 0) {
1301 gp_context_status (context, _("Resetting protocol..."));
1302 canon_serial_off (camera);
1303 sleep (3); /* The camera takes a while to switch off */
1304 return canon_int_ready (camera, context);
1305 }
1306 if (good_ack == -1) {
1307 GP_DEBUG ("Received a NACK!");
1308 return GP_ERROR;
1309 }
1310 gp_context_status (context, _("Camera OK."));
1311 return 1;
1312 }
1313 if (good_ack == -1) {
1314 GP_DEBUG ("Received a NACK !\n");
1315 return GP_ERROR;
1316 }
1317 GP_DEBUG ("Camera replied to ping, proceed.\n");
1318 return GP_OK;
1319 }
1320
1321 /* Camera was off... */
1322
1323 gp_context_status (context, _("Looking for camera ..."));
1324 if (camera->pl->receive_error == FATAL_ERROR) {
1325 /* we try to recover from an error
1326 we go back to 9600bps */
1327 if (!canon_serial_change_speed (camera->port, 9600)) {
1328 GP_DEBUG ("ERROR: Error changing speed");
1329 return GP_ERROR;
1330 }
1331 camera->pl->receive_error = NOERROR;
1332 }
1333 id = gp_context_progress_start (context, MAX_TRIES, _("Trying to contact camera..."));
1334 for (try = 0; try < MAX_TRIES; try++) {
1335 if (canon_serial_send (camera, (unsigned char *)"\x55\x55\x55\x55\x55\x55\x55\x55", 8, USLEEP1)
1336 < 0) {
1337 gp_context_error (context, _("Communication error 1"));
1338 return GP_ERROR;
1339 }
1340 pkt = canon_serial_recv_frame (camera, &len);
1341 gp_context_progress_update (context, id, try + 1);
1342 if (pkt)
1343 break;
1344 }
1345 gp_context_progress_stop (context, id);
1346 if (try == MAX_TRIES) {
1347 gp_context_error (context, _("No response from camera"));
1348 return GP_ERROR;
1349 }
1350 if (!pkt) {
1351 gp_context_error (context, _("No response from camera"));
1352 return GP_ERROR;
1353 }
1354 if (len < 40 && strncmp ((char *)pkt + 26, "Canon", 5)) {
1355 gp_context_error (context, _("Unrecognized response"));
1356 return GP_ERROR;
1357 }
1358 strncpy (cam_id_str, (char *)pkt + 26, sizeof (cam_id_str) - 1);
1359
1360 GP_DEBUG ("cam_id_str : '%s'", cam_id_str);
1361
1362 camera->pl->first_init = 0;
1363
1364 /* Compare what the camera identified itself as with our list
1365 * of known models
1366 *
1367 * We iterate over the model list testing id_str, even if we
1368 * don't actually use id_str, but serial_id_string.
1369 */
1370 for (i = 0; models[i].id_str != NULL; i++) {
1371 if ((models[i].serial_id_string != NULL) &&
1372 !strcmp (models[i].serial_id_string, cam_id_str)) {
1373 GP_DEBUG ("canon_serial_ready: Serial ID string matches '%s'",
1374 models[i].serial_id_string);
1375 gp_context_status (context, _("Detected a \"%s\" aka \"%s\""),
1376 models[i].id_str, models[i].serial_id_string);
1377 camera->pl->md = (struct canonCamModelData *) &models[i];
1378 break;
1379 }
1380 }
1381
1382 if (models[i].id_str == NULL) {
1383 gp_context_error (context, _("Unknown model \"%s\""), cam_id_str);
1384 return GP_ERROR_MODEL_NOT_FOUND;
1385 }
1386
1387 /* take care of some model specific things */
1388 switch (camera->pl->md->model) {
1389 case CANON_CLASS_3:
1390 case CANON_CLASS_1:
1391 if (camera->pl->speed > 57600)
1392 camera->pl->slow_send = 1;
1393 break;
1394 default:
1395 break;
1396 }
1397
1398 /* 5 seconds delay should be enough for big flash cards. By
1399 * experience, one or two seconds is too little, as a large flash
1400 * card needs more access time. */
1401 serial_set_timeout (camera->port, 5000);
1402 (void) canon_serial_recv_packet (camera, &type, &seq, NULL);
1403 if (type != PKT_EOT || seq) {
1404 gp_context_error (context, _("Bad EOT"));
1405 return GP_ERROR;
1406 }
1407 camera->pl->seq_tx = 0;
1408 camera->pl->seq_rx = 1;
1409 if (!canon_serial_send_frame (camera, (unsigned char *)"\x00\x05\x00\x00\x00\x00\xdb\xd1", 8)) {
1410 gp_context_error (context, _("Communication error 2"));
1411 return GP_ERROR;
1412 }
1413 res = 0;
1414 switch (camera->pl->speed) {
1415 case 9600:
1416 res = canon_serial_send_frame (camera, SPEED_9600, 12);
1417 break;
1418 case 19200:
1419 res = canon_serial_send_frame (camera, SPEED_19200, 12);
1420 break;
1421 case 38400:
1422 res = canon_serial_send_frame (camera, SPEED_38400, 12);
1423 break;
1424 case 57600:
1425 res = canon_serial_send_frame (camera, SPEED_57600, 12);
1426 break;
1427 case 115200:
1428 res = canon_serial_send_frame (camera, SPEED_115200, 12);
1429 break;
1430 }
1431
1432 if (!res || !canon_serial_send_frame (camera, (unsigned char *)"\x00\x04\x01\x00\x00\x00\x24\xc6", 8)) {
1433 gp_context_error (context, _("Communication error 3"));
1434 return GP_ERROR;
1435 }
1436 speed = camera->pl->speed;
1437 gp_context_status (context, _("Changing speed... wait..."));
1438 if (!canon_serial_wait_for_ack (camera))
1439 return GP_ERROR;
1440 if (speed != 9600) {
1441 if (!canon_serial_change_speed (camera->port, speed)) {
1442 gp_context_status (context, _("Error changing speed"));
1443 } else {
1444 GP_DEBUG ("speed changed");
1445 }
1446
1447 }
1448 for (try = 1; try < MAX_TRIES; try++) {
1449 canon_serial_send_packet (camera, PKT_EOT, camera->pl->seq_tx,
1450 camera->pl->psa50_eot + PKT_HDR_LEN, 0);
1451 if (!canon_serial_wait_for_ack (camera)) {
1452 gp_context_status (context,
1453 _("Error waiting for ACK during initialization, retrying"));
1454 } else
1455 break;
1456 }
1457
1458 if (try == MAX_TRIES) {
1459 gp_context_error (context, _("Error waiting ACK during initialization"));
1460 return GP_ERROR;
1461 }
1462
1463 gp_context_status (context, _("Connected to camera"));
1464 /* Now is a good time to ask the camera for its owner
1465 * name (and Model String as well) */
1466 canon_int_identify_camera (camera, context);
1467 canon_int_get_time (camera, NULL, context);
1468
1469 return GP_OK;
1470 }
1471
1472 /**
1473 * canon_serial_get_thumbnail:
1474 * @camera: camera to work on
1475 * @name: file name (complete canon path) of file to get thumbnail for
1476 * @data: pointer to data pointer
1477 * @length: pointer to data length
1478 * @context: context for error reporting
1479 *
1480 * This is just the serial specific part extracted from the older
1481 * canon_get_thumbnail() routine.
1482 *
1483 * Returns: gphoto2 error code
1484 *
1485 */
1486 int
canon_serial_get_thumbnail(Camera * camera,const char * name,unsigned char ** data,unsigned int * length,GPContext * context)1487 canon_serial_get_thumbnail (Camera *camera, const char *name, unsigned char **data,
1488 unsigned int *length, GPContext *context)
1489 {
1490 unsigned int expect = 0, size, payload_length, total_file_size;
1491 unsigned int total = 0, id;
1492 unsigned char *msg;
1493
1494 CON_CHECK_PARAM_NULL (length);
1495 CON_CHECK_PARAM_NULL (data);
1496 *length = 0;
1497 *data = NULL;
1498
1499 if (camera->pl->receive_error == FATAL_ERROR) {
1500 gp_context_error (context,
1501 _("ERROR: a fatal error condition was detected, can't continue "));
1502 return GP_ERROR;
1503 }
1504
1505 payload_length = strlen (name) + 1;
1506 msg = canon_serial_dialogue (camera, context, 0x1, 0x11, &total_file_size,
1507 "\x01\x00\x00\x00\x00", 5, &payload_length, 1, "\x00", 2,
1508 name, strlen (name) + 1, NULL);
1509 if (!msg) {
1510 canon_serial_error_type (camera);
1511 return GP_ERROR;
1512 }
1513
1514
1515 total = le32atoh (msg + 4);
1516 if (total > 2000000) { /* 2 MB thumbnails ? unlikely ... */
1517 gp_context_error (context, _("ERROR: %d is too big"), total);
1518 return GP_ERROR;
1519 }
1520 *data = malloc (total);
1521 if (!*data) {
1522 perror ("malloc");
1523 return GP_ERROR;
1524 }
1525 *length = total;
1526
1527 id = gp_context_progress_start (context, total, _("Getting thumbnail..."));
1528 while (msg) {
1529 if (total_file_size < 20 || le32atoh (msg)) {
1530 return GP_ERROR;
1531 }
1532 size = le32atoh (msg + 12);
1533 if (le32atoh (msg + 8) != expect || expect + size > total
1534 || size > total_file_size - 20) {
1535 GP_DEBUG ("ERROR: doesn't fit");
1536 return GP_ERROR;
1537 }
1538 memcpy (*data + expect, msg + 20, size);
1539 expect += size;
1540 gp_context_progress_update (context, id, expect);
1541 if ((expect == total) != le32atoh (msg + 16)) {
1542 GP_DEBUG ("ERROR: end mark != end of data");
1543 return GP_ERROR;
1544 }
1545 if (expect == total) {
1546 /* We finished receiving the file. Parse the header and
1547 return just the thumbnail */
1548 break;
1549 }
1550 msg = canon_serial_recv_msg (camera, 0x1, 0x21, &total_file_size, context);
1551 }
1552 gp_context_progress_stop (context, id);
1553 return GP_OK;
1554 }
1555
1556 /****************************************************************************
1557 *
1558 * End of file: serial.c
1559 *
1560 ****************************************************************************/
1561
1562 /*
1563 * Local Variables:
1564 * c-file-style:"linux"
1565 * indent-tabs-mode:t
1566 * End:
1567 */
1568