1 /* fuji.c:
2 *
3 * Fuji Camera library for the gphoto project.
4 *
5 * � 2001 Matthew G. Martin <matt.martin@ieee.org>
6 * 2002 Lutz Mueller <lutz@users.sourceforge.net>
7 *
8 * This routine works for Fuji DS-7 and DX-5,7,10 and
9 * MX-500,600,700,1200,1700,2700,2900, Apple QuickTake 200,
10 * Samsung Kenox SSC-350N,Leica Digilux Zoom cameras and possibly others.
11 *
12 * Preview and take_picture fixes and preview conversion integrated
13 * by Michael Smith <michael@csuite.ns.ca>.
14 *
15 * This driver was reworked from the "fujiplay" package:
16 * * A program to control Fujifilm digital cameras, like
17 * * the DS-7 and MX-700, and their clones.
18 * * Written by Thierry Bousch <bousch@topo.math.u-psud.fr>
19 * * and released in the public domain.
20 *
21 * Portions of this code were adapted from
22 * GDS7 v0.1 interactive digital image transfer software for DS-7 camera
23 * Copyright 1998 Matthew G. Martin
24
25 * Some of which was derived from get_ds7 , a Perl Language library
26 * Copyright 1997 Mamoru Ohno
27 *
28 * This program is free software; you can redistribute it and/or modify
29 * it under the terms of the GNU General Public License as published by
30 * the Free Software Foundation; either version 2 of the License, or
31 * (at your option) any later version.
32 *
33 * This program is distributed in the hope that it will be useful,
34 * but WITHOUT ANY WARRANTY; without even the implied warranty of
35 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 * GNU General Public License for more details.
37 *
38 * You should have received a copy of the GNU General Public License
39 * along with this program; if not, write to the
40 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
41 * Boston, MA 02110-1301 USA
42 */
43 #include "config.h"
44 #include "fuji.h"
45
46 #include <string.h>
47 #include <stdlib.h>
48 #include <stdio.h>
49
50 #include <gphoto2/gphoto2-port-log.h>
51
52 #ifdef ENABLE_NLS
53 # include <libintl.h>
54 # undef _
55 # define _(String) dgettext (GETTEXT_PACKAGE, String)
56 # ifdef gettext_noop
57 # define N_(String) gettext_noop (String)
58 # else
59 # define N_(String) (String)
60 # endif
61 #else
62 # define textdomain(String) (String)
63 # define gettext(String) (String)
64 # define dgettext(Domain,Message) (Message)
65 # define dcgettext(Domain,Message,Type) (Message)
66 # define bindtextdomain(Domain,Directory) (Domain)
67 # define _(String) (String)
68 # define N_(String) (String)
69 #endif
70
71 #ifndef MIN
72 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
73 #endif
74
75 #ifndef MAX
76 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
77 #endif
78
79 #define GP_MODULE "fuji"
80
81 #define CR(result) {int __r = (result); if (__r < 0) return (__r);}
82 #define CRF(result,d) {int __r = (result); if (__r < 0) {free (d); return (__r);}}
83 #define CLEN(buf_len,required) \
84 { \
85 if (buf_len < required) { \
86 gp_context_error (context, _("The camera sent " \
87 "only %i byte(s), but we need at " \
88 "least %i."), buf_len, required); \
89 return (GP_ERROR); \
90 } \
91 }
92
93
94 #define STX 0x02 /* Start of data */
95 #define ETX 0x03 /* End of data */
96 #define EOT 0x04 /* End of session */
97 #define ENQ 0x05 /* Enquiry */
98 #define ACK 0x06
99 #define ESC 0x10
100 #define ETB 0x17 /* End of transmission block */
101 #define NAK 0x15
102
103 #define FUJI_ACK 0x00
104 #define FUJI_NAK 0x01
105
106 static int fuji_reset (Camera *camera, GPContext *context);
107
108 int
fuji_ping(Camera * camera,GPContext * context)109 fuji_ping (Camera *camera, GPContext *context)
110 {
111 unsigned char b;
112 unsigned int i;
113 int r;
114
115 GP_DEBUG ("Pinging camera...");
116
117 /* Drain input */
118 while (gp_port_read (camera->port, (char *)&b, 1) >= 0);
119
120 i = 0;
121 while (1) {
122 b = ENQ;
123 CR (gp_port_write (camera->port, (char *)&b, 1));
124 r = gp_port_read (camera->port, (char *)&b, 1);
125 if ((r >= 0) && (b == ACK))
126 return (GP_OK);
127 i++;
128 if (i >= 3) {
129 gp_context_error (context, _("Could not contact "
130 "camera."));
131 return (GP_ERROR);
132 }
133 }
134 }
135
136 static int
fuji_send(Camera * camera,unsigned char * cmd,unsigned int cmd_len,unsigned char last,GPContext * context)137 fuji_send (Camera *camera, unsigned char *cmd, unsigned int cmd_len,
138 unsigned char last, GPContext *context)
139 {
140 unsigned char b[1024], check;
141 unsigned int i;
142
143 /* Send header */
144 b[0] = ESC;
145 b[1] = STX;
146 CR (gp_port_write (camera->port, (char *)b, 2));
147
148 /*
149 * Escape the data we are going to send.
150 * Calculate the checksum.
151 */
152 check = (last ? ETX : ETB);
153 memcpy (b, cmd, cmd_len);
154 for (i = 0; i < cmd_len; i++) {
155 check ^= b[i];
156 if (b[i] == ESC) {
157 memmove (b + i + 1, b + i, cmd_len - i);
158 b[i] = ESC;
159 i++;
160 cmd_len++;
161 }
162 }
163
164 /* Send data */
165 CR (gp_port_write (camera->port, (char *)b, cmd_len));
166
167 /* Send footer */
168 b[0] = ESC;
169 b[1] = (last ? ETX : ETB);
170 b[2] = check;
171 CR (gp_port_write (camera->port, (char *)b, 3));
172
173 return (GP_OK);
174 }
175
176 static int
fuji_recv(Camera * camera,unsigned char * buf,unsigned int * buf_len,unsigned char * last,GPContext * context)177 fuji_recv (Camera *camera, unsigned char *buf, unsigned int *buf_len,
178 unsigned char *last, GPContext *context)
179 {
180 unsigned char b[1024], check = 0;
181 unsigned int i;
182
183 /*
184 * Read the header. The checksum covers all bytes between
185 * ESC STX and ESC ET[X,B].
186 */
187 CR (gp_port_read (camera->port, (char *)b, 6));
188
189 /* Verify the header */
190 if ((b[0] != ESC) || (b[1] != STX)) {
191 gp_context_error (context, _("Received unexpected data "
192 "(0x%02x, 0x%02x)."), b[0], b[1]);
193 return (GP_ERROR_CORRUPTED_DATA);
194 }
195
196 /*
197 * We don't know the meaning of b[2] and b[3].
198 * We have seen 0x00 0x4d and 0x00 0x06.
199 */
200 check ^= b[2];
201 check ^= b[3];
202
203 /* Determine the length of the packet. */
204 *buf_len = ((b[5] << 8) | b[4]);
205 check ^= b[4];
206 check ^= b[5];
207 GP_DEBUG ("We are expecting %i byte(s) data (excluding ESC quotes). "
208 "Let's read them...", *buf_len);
209
210 /* Read the data. Unescape it. Calculate the checksum. */
211 for (i = 0; i < *buf_len; i++) {
212 CR (gp_port_read (camera->port, (char *)buf + i, 1));
213 if (buf[i] == ESC) {
214 CR (gp_port_read (camera->port, (char *)buf + i, 1));
215 if (buf[i] != ESC) {
216 gp_context_error (context,
217 _("Wrong escape sequence: "
218 "expected 0x%02x, got 0x%02x."),
219 ESC, buf[i]);
220
221 /* Dump the remaining data */
222 while (gp_port_read (camera->port, (char *)b, 1) >= 0);
223
224 return (GP_ERROR_CORRUPTED_DATA);
225 }
226 }
227 check ^= buf[i];
228 }
229
230 /* Read the footer */
231 CR (gp_port_read (camera->port, (char *)b, 3));
232 if (b[0] != ESC) {
233 gp_context_error (context,
234 _("Bad data - got 0x%02x, expected 0x%02x."),
235 b[0], ESC);
236 return (GP_ERROR_CORRUPTED_DATA);
237 }
238 switch (b[1]) {
239 case ETX:
240 *last = 1;
241 break;
242 case ETB:
243 *last = 0;
244 break;
245 default:
246 gp_context_error (context,
247 _("Bad data - got 0x%02x, expected 0x%02x or "
248 "0x%02x."), b[1], ETX, ETB);
249 return (GP_ERROR_CORRUPTED_DATA);
250 }
251 check ^= b[1];
252 if (check != b[2]) {
253 gp_context_error (context,
254 _("Bad checksum - got 0x%02x, expected 0x%02x."),
255 b[2], check);
256 return (GP_ERROR_CORRUPTED_DATA);
257 }
258
259 return (GP_OK);
260 }
261
262 static int
fuji_transmit(Camera * camera,unsigned char * cmd,unsigned int cmd_len,unsigned char * buf,unsigned int * buf_len,GPContext * context)263 fuji_transmit (Camera *camera, unsigned char *cmd, unsigned int cmd_len,
264 unsigned char *buf, unsigned int *buf_len, GPContext *context)
265 {
266 unsigned char last = 0, c, p;
267 unsigned int b_len = 1024;
268 int r, retries = 0, id = 0;
269
270 /*
271 * Send the command. If we fail the first time, we only try once more.
272 * After the third time, the camera would reset itself automatically.
273 */
274 retries = 0;
275 while (1) {
276
277 /* Give the user the possibility to cancel. */
278 if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL)
279 return (GP_ERROR_CANCEL);
280
281 CR (fuji_send (camera, cmd, cmd_len, 1, context));
282
283 /* Receive ACK (hopefully) */
284 CR (gp_port_read (camera->port, (char *)&c, 1));
285 switch (c) {
286 case ACK:
287 break;
288 case NAK:
289
290 /* Camera didn't like the command */
291 if (++retries > 1) {
292 gp_context_error (context, _("Camera rejected "
293 "the command."));
294 return (GP_ERROR);
295 }
296 continue;
297
298 case EOT:
299
300 /* Camera got fed up and reset itself. */
301 gp_context_error (context, _("Camera reset itself."));
302 return (GP_ERROR);
303
304 default:
305 gp_context_error (context, _("Camera sent unexpected "
306 "byte 0x%02x."), c);
307 return (GP_ERROR_CORRUPTED_DATA);
308 }
309
310 break;
311 }
312
313 /*
314 * Read the response. If we expect more than 1024 bytes, show
315 * progress information.
316 */
317 p = ((*buf_len > 1024) ? 1 : 0);
318 if (p)
319 id = gp_context_progress_start (context, *buf_len,
320 _("Downloading..."));
321 *buf_len = 0;
322 retries = 0;
323 while (!last) {
324 r = fuji_recv (camera, buf + *buf_len, &b_len, &last, context);
325 if (r < 0) {
326 retries++;
327 while (gp_port_read (camera->port, (char *)&c, 1) >= 0);
328 if (++retries > 2)
329 return (r);
330 GP_DEBUG ("Retrying...");
331 c = NAK;
332 CR (gp_port_write (camera->port, (char *)&c, 1));
333 continue;
334 }
335
336 /* Give the user the possibility to cancel. */
337 if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) {
338 CR (fuji_reset (camera, context));
339 return (GP_ERROR_CANCEL);
340 }
341
342 /* Acknowledge this packet. */
343 c = ACK;
344 CR (gp_port_write (camera->port, (char *)&c, 1));
345 *buf_len += b_len;
346
347 if (p)
348 gp_context_progress_update (context, id, *buf_len);
349 }
350 if (p)
351 gp_context_progress_stop (context, id);
352
353 return (GP_OK);
354 }
355
356 int
fuji_get_cmds(Camera * camera,unsigned char * cmds,GPContext * context)357 fuji_get_cmds (Camera *camera, unsigned char *cmds, GPContext *context)
358 {
359 unsigned char cmd[4], buf[1024];
360 unsigned int i, buf_len = 0;
361
362 cmd[0] = 0;
363 cmd[1] = FUJI_CMD_CMDS_VALID;
364 cmd[2] = 0;
365 cmd[3] = 0;
366 CR (fuji_transmit (camera, cmd, 4, buf, &buf_len, context));
367
368 memset (cmds, 0, 0xff);
369 for (i = 0; i < buf_len; i++)
370 cmds[buf[i]] = 1;
371
372 return (GP_OK);
373 }
374
375 int
fuji_pic_count(Camera * camera,unsigned int * n,GPContext * context)376 fuji_pic_count (Camera *camera, unsigned int *n, GPContext *context)
377 {
378 unsigned char cmd[4], buf[1024];
379 unsigned int buf_len = 0;
380
381 cmd[0] = 0;
382 cmd[1] = FUJI_CMD_PIC_COUNT;
383 cmd[2] = 0;
384 cmd[3] = 0;
385 CR (fuji_transmit (camera, cmd, 4, buf, &buf_len, context));
386
387 CLEN (buf_len, 2);
388
389 *n = (buf[1] << 8) | buf[0];
390
391 return (GP_OK);
392 }
393
394 int
fuji_pic_name(Camera * camera,unsigned int i,const char ** name,GPContext * context)395 fuji_pic_name (Camera *camera, unsigned int i, const char **name,
396 GPContext *context)
397 {
398 static unsigned char buf[1025];
399 unsigned char cmd[6];
400 unsigned int buf_len = 0;
401
402 cmd[0] = 0;
403 cmd[1] = FUJI_CMD_PIC_NAME;
404 cmd[2] = 2;
405 cmd[3] = 0;
406 cmd[4] = i;
407 cmd[5] = (i >> 8);
408
409 memset (buf, 0, sizeof (buf));
410 CR (fuji_transmit (camera, cmd, 6, buf, &buf_len, context));
411 *name = (char *)buf;
412
413 return (GP_OK);
414 }
415
416 int
fuji_version(Camera * camera,const char ** version,GPContext * context)417 fuji_version (Camera *camera, const char **version, GPContext *context)
418 {
419 static unsigned char buf[1025];
420 unsigned char cmd[4];
421 unsigned int buf_len = 0;
422
423 cmd[0] = 0;
424 cmd[1] = FUJI_CMD_VERSION;
425 cmd[2] = 0;
426 cmd[3] = 0;
427
428 memset (buf, 0, sizeof (buf));
429 CR (fuji_transmit (camera, cmd, 4, buf, &buf_len, context));
430 *version = (char *)buf;
431
432 return (GP_OK);
433 }
434
435 int
fuji_model(Camera * camera,const char ** model,GPContext * context)436 fuji_model (Camera *camera, const char **model, GPContext *context)
437 {
438 static unsigned char buf[1025];
439 unsigned char cmd[4];
440 unsigned int buf_len = 0;
441
442 cmd[0] = 0;
443 cmd[1] = FUJI_CMD_MODEL;
444 cmd[2] = 0;
445 cmd[3] = 0;
446
447 memset (buf, 0, sizeof (buf));
448 CR (fuji_transmit (camera, cmd, 4, buf, &buf_len, context));
449 *model = (char *)buf;
450
451 return (GP_OK);
452 }
453
454 int
fuji_id_get(Camera * camera,const char ** id,GPContext * context)455 fuji_id_get (Camera *camera, const char **id, GPContext *context)
456 {
457 static unsigned char buf[1025];
458 unsigned char cmd[4];
459 unsigned int buf_len = 0;
460
461 cmd[0] = 0;
462 cmd[1] = FUJI_CMD_ID_GET;
463 cmd[2] = 0;
464 cmd[3] = 0;
465
466 memset (buf, 0, sizeof (buf));
467 CR (fuji_transmit (camera, cmd, 4, buf, &buf_len, context));
468 *id = (char *)buf;
469
470 return (GP_OK);
471 }
472
473 int
fuji_id_set(Camera * camera,const char * id,GPContext * context)474 fuji_id_set (Camera *camera, const char *id, GPContext *context)
475 {
476 unsigned char cmd[14], buf[1025];
477 unsigned int buf_len = 0;
478
479 /* It seems that the ID must be 10 chars or less */
480 cmd[0] = 0;
481 cmd[1] = FUJI_CMD_ID_SET;
482 cmd[2] = 0x0a;
483 cmd[3] = 0x00;
484 memcpy (cmd + 4, id, MIN (strlen (id) + 1, 10));
485
486 CR (fuji_transmit (camera, cmd, 14, buf, &buf_len, context));
487
488 return (GP_OK);
489 }
490
491 int
fuji_pic_del(Camera * camera,unsigned int i,GPContext * context)492 fuji_pic_del (Camera *camera, unsigned int i, GPContext *context)
493 {
494 unsigned char cmd[6], buf[1024];
495 unsigned int buf_len = 0;
496
497 cmd[0] = 0;
498 cmd[1] = FUJI_CMD_PIC_NAME;
499 cmd[2] = 2;
500 cmd[3] = 0;
501 cmd[4] = i;
502 cmd[5] = (i >> 8);
503
504 CR (fuji_transmit (camera, cmd, 6, buf, &buf_len, context));
505
506 return (GP_OK);
507 }
508
509 int
fuji_pic_size(Camera * camera,unsigned int i,unsigned int * size,GPContext * context)510 fuji_pic_size (Camera *camera, unsigned int i, unsigned int *size,
511 GPContext *context)
512 {
513 unsigned char cmd[6], buf[1024];
514 unsigned int buf_len = 0;
515
516 cmd[0] = 0;
517 cmd[1] = FUJI_CMD_PIC_SIZE;
518 cmd[2] = 2;
519 cmd[3] = 0;
520 cmd[4] = i;
521 cmd[5] = (i >> 8);
522
523 CR (fuji_transmit (camera, cmd, 6, buf, &buf_len, context));
524 CLEN (buf_len, 4);
525
526 *size = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
527
528 return (GP_OK);
529 }
530
531 int
fuji_pic_get_thumb(Camera * camera,unsigned int i,unsigned char ** data,unsigned int * size,GPContext * context)532 fuji_pic_get_thumb (Camera *camera, unsigned int i, unsigned char **data,
533 unsigned int *size, GPContext *context)
534 {
535 unsigned char cmd[6];
536
537 /* It seems that all thumbnails have the size of 60 x 175. */
538 *size = 60 * 175;
539 *data = malloc (sizeof (char) * *size);
540 if (!*data) {
541 gp_context_error (context, _("Could not allocate "
542 "%i byte(s) for downloading the thumbnail."), *size);
543 return (GP_ERROR_NO_MEMORY);
544 }
545
546 cmd[0] = 0;
547 cmd[1] = FUJI_CMD_PIC_GET_THUMB;
548 cmd[2] = 2;
549 cmd[3] = 0;
550 cmd[4] = i;
551 cmd[5] = (i >> 8);
552
553 CRF (fuji_transmit (camera, cmd, 6, *data, size, context), *data);
554 GP_DEBUG ("Download of thumbnail completed.");
555
556 return (GP_OK);
557 }
558
559 int
fuji_pic_get(Camera * camera,unsigned int i,unsigned char ** data,unsigned int * size,GPContext * context)560 fuji_pic_get (Camera *camera, unsigned int i, unsigned char **data,
561 unsigned int *size, GPContext *context)
562 {
563 unsigned char cmd[6];
564
565 /*
566 * First, get the size of the picture and allocate the necessary
567 * memory. Some cameras don't support the FUJI_CMD_PIC_SIZE command.
568 * We will then assume 66000 bytes.
569 */
570 if (fuji_pic_size (camera, i, size, context) < 0)
571 *size = 66000;
572
573 *data = malloc (sizeof (char) * *size);
574 if (!*data) {
575 gp_context_error (context, _("Could not allocate "
576 "%i byte(s) for downloading the picture."), *size);
577 return (GP_ERROR_NO_MEMORY);
578 }
579
580 cmd[0] = 0;
581 cmd[1] = FUJI_CMD_PIC_GET;
582 cmd[2] = 2;
583 cmd[3] = 0;
584 cmd[4] = i;
585 cmd[5] = (i >> 8);
586
587 CRF (fuji_transmit (camera, cmd, 6, *data, size, context), *data);
588 GP_DEBUG ("Download of picture completed (%i byte(s)).", *size);
589
590 return (GP_OK);
591 }
592
593 int
fuji_date_get(Camera * camera,FujiDate * date,GPContext * context)594 fuji_date_get (Camera *camera, FujiDate *date, GPContext *context)
595 {
596 unsigned char cmd[4], buf[1024];
597 unsigned int buf_len = 0;
598
599 cmd[0] = 0;
600 cmd[1] = FUJI_CMD_DATE_GET;
601 cmd[2] = 0;
602 cmd[3] = 0;
603
604 CR (fuji_transmit (camera, cmd, 4, buf, &buf_len, context));
605 CLEN (buf_len, 14);
606
607 date->year = buf[0] * 1000 + buf[1] * 100 + buf[ 2] * 10 + buf[ 3];
608 date->month = buf[ 4] * 10 + buf[ 5];
609 date->day = buf[ 6] * 10 + buf[ 7];
610 date->hour = buf[ 8] * 10 + buf[ 9];
611 date->min = buf[10] * 10 + buf[11];
612 date->sec = buf[12] * 10 + buf[13];
613
614 return (GP_OK);
615 }
616
617 int
fuji_avail_mem(Camera * camera,unsigned int * avail_mem,GPContext * context)618 fuji_avail_mem (Camera *camera, unsigned int *avail_mem, GPContext *context)
619 {
620 unsigned char cmd[4], buf[1024];
621 unsigned int buf_len = 0;
622
623 cmd[0] = 0;
624 cmd[1] = FUJI_CMD_AVAIL_MEM;
625 cmd[2] = 0;
626 cmd[3] = 0;
627
628 CR (fuji_transmit (camera, cmd, 4, buf, &buf_len, context));
629 CLEN (buf_len, 4);
630
631 *avail_mem = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
632
633 return (GP_OK);
634 }
635
636 int
fuji_date_set(Camera * camera,FujiDate date,GPContext * context)637 fuji_date_set (Camera *camera, FujiDate date, GPContext *context)
638 {
639 unsigned char cmd[1024], buf[1024];
640 unsigned int buf_len = 0;
641
642 cmd[0] = 0;
643 cmd[1] = FUJI_CMD_DATE_SET;
644 cmd[2] = 14;
645 cmd[3] = 0;
646 sprintf ((char*)cmd + 4, "%04d%02d%02d%02d%02d%02d", date.year, date.month,
647 date.day, date.hour, date.min, date.sec);
648
649 CR (fuji_transmit (camera, cmd, 4, buf, &buf_len, context));
650
651 return (GP_OK);
652 }
653
654 int
fuji_upload_init(Camera * camera,const char * name,GPContext * context)655 fuji_upload_init (Camera *camera, const char *name, GPContext *context)
656 {
657 unsigned char cmd[1024], buf[1024];
658 unsigned int buf_len = 0, cmd_len = 0;
659
660 cmd[0] = 0;
661 cmd[1] = FUJI_CMD_UPLOAD_INIT;
662 cmd[2] = strlen (name);
663 cmd[3] = 0;
664 memcpy (cmd + 4, name, strlen (name));
665 cmd_len = strlen (name) + 4;
666 CR (fuji_transmit (camera, cmd, cmd_len, buf, &buf_len, context));
667 CLEN (buf_len, 1);
668
669 /* Check the response */
670 switch (buf[0]) {
671 case FUJI_ACK:
672 break;
673 case FUJI_NAK:
674 gp_context_error (context, _("The camera does not "
675 "accept '%s' as filename."), name);
676 return (GP_ERROR);
677 default:
678 gp_context_error (context, _("Could not initialize upload "
679 "(camera responded with 0x%02x)."), buf[0]);
680 return (GP_ERROR);
681 }
682
683 return (GP_OK);
684 }
685
686 #define CHUNK_SIZE 512
687
688 int
fuji_upload(Camera * camera,const unsigned char * data,unsigned int size,GPContext * context)689 fuji_upload (Camera *camera, const unsigned char *data,
690 unsigned int size, GPContext *context)
691 {
692 unsigned char cmd[1024], c;
693 unsigned int cmd_len, chunk_size, retries, i;
694
695 /*
696 * The old driver did upload in chunks of 512 bytes. I don't know
697 * if this is optimal.
698 */
699 cmd[0] = 0;
700 cmd[1] = FUJI_CMD_UPLOAD;
701 for (i = 0; i < size; i+= CHUNK_SIZE) {
702 chunk_size = MIN (CHUNK_SIZE, size - i);
703 cmd[2] = chunk_size;
704 cmd[3] = (chunk_size >> 8);
705 memcpy (cmd + 4, data + i, chunk_size);
706 cmd_len = chunk_size + 4;
707
708 retries = 0;
709 while (1) {
710
711 /* Give the user the possibility to cancel. */
712 if (gp_context_cancel (context) ==
713 GP_CONTEXT_FEEDBACK_CANCEL) {
714 CR (fuji_reset (camera, context));
715 return (GP_ERROR_CANCEL);
716 }
717
718 CR (fuji_send (camera, cmd, cmd_len,
719 (i + CHUNK_SIZE < size) ? 0 : 1, context));
720
721 /* Receive ACK (hopefully) */
722 CR (gp_port_read (camera->port, (char *)&c, 1));
723 switch (c) {
724 case ACK:
725 break;
726 case NAK:
727
728 /* Camera didn't like the command */
729 if (++retries > 1) {
730 gp_context_error (context,
731 _("Camera rejected "
732 "the command."));
733 return (GP_ERROR);
734 }
735 continue;
736
737 case EOT:
738
739 /* Camera got fed up and reset itself. */
740 gp_context_error (context, _("Camera reset "
741 "itself."));
742 return (GP_ERROR);
743
744 default:
745 gp_context_error (context, _("Camera sent "
746 "unexpected byte 0x%02x."), c);
747 return (GP_ERROR_CORRUPTED_DATA);
748 }
749 break;
750 }
751 }
752
753 return (GP_OK);
754 }
755
756 int
fuji_set_speed(Camera * camera,FujiSpeed speed,GPContext * context)757 fuji_set_speed (Camera *camera, FujiSpeed speed, GPContext *context)
758 {
759 unsigned char cmd[5], buf[1024];
760 unsigned int buf_len = 0;
761
762 GP_DEBUG("Attempting to set speed to %i",speed);
763 cmd[0] = 1;
764 cmd[1] = FUJI_CMD_SPEED;
765 cmd[2] = 1;
766 cmd[3] = 0;
767 cmd[4] = speed;
768 CR (fuji_transmit (camera, cmd, 5, buf, &buf_len, context));
769 CLEN (buf_len, 1);
770
771 /* Check the response */
772 switch (buf[0]) {
773 case FUJI_ACK:
774 break;
775 case FUJI_NAK:
776 gp_context_error (context, _("The camera does not "
777 "support speed %i."), speed);
778 return (GP_ERROR_NOT_SUPPORTED);
779 default:
780 gp_context_error (context, _("Could not set speed to "
781 "%i (camera responded with %i)."), speed, buf[0]);
782 return (GP_ERROR);
783 }
784
785 GP_DEBUG("Success with speed %i.",speed);
786
787 /* Reset the connection */
788 CR (fuji_reset (camera, context));
789
790 return (GP_OK);
791 }
792
793 static int
fuji_reset(Camera * camera,GPContext * context)794 fuji_reset (Camera *camera, GPContext *context)
795 {
796 unsigned char c = EOT;
797
798 CR (gp_port_write (camera->port, (char *)&c, 1));
799
800 return (GP_OK);
801 }
802
803 #if 0
804
805 static int fuji_get_flash_mode (void)
806 {
807 cmd0 (0, 0x30);
808 return answer[4];
809 }
810
811 static int fuji_set_flash_mode (int mode)
812 {
813 cmd1 (0, 0x32, mode);
814 return answer[4];
815 }
816
817 static int fuji_picture_size (int i)
818 {
819 cmd2 (0, FUJI_SIZE, i);
820 return answer[4] + (answer[5] << 8) + (answer[6] << 16) + (answer[7] << 24);
821 }
822
823 static int charge_flash (void)
824 {
825 cmd2 (0, FUJI_CHARGE_FLASH, 200);
826 return answer[4];
827 }
828
829 static int take_picture (void)
830 {
831 cmd0 (0, FUJI_CMD_TAKE);
832 return answer[4] + (answer[5] << 8) + (answer[6] << 16) + (answer[7] << 24);
833 }
834
835 static int del_frame (int i)
836 {
837 cmd2 (0, FUJI_CMD_DELETE, i);
838 return answer[4];
839 }
840
841 int
842 fuji_get_cmds (Camera *camera, unsigned char *cmds, GPContext *context)
843 {
844 unsigned char answer[0xff];
845 unsigned int answer_len = 0xff;
846
847 memset (cmds, 0, 0xff);
848
849 CR (fuji_cmd0 (camera, 0, FUJI_CMD_CMDS_VALID, answer, &answer_len,
850 context));
851 int i;
852 DBG("Get command list");
853 memset(fjd->has_cmd, 0, 256);
854 if (cmd0 (0, FUJI_CMDS_VALID)) return ;
855 for (i = 4; i < answer_len; i++)
856 fjd->has_cmd[answer[i]] = 1;
857 }
858
859 static int get_picture_info(int num,char *name,CameraPrivateLibrary *camdata){
860
861 DBG("Getting name...");
862
863 strncpy(name,fuji_picture_name(num),100);
864
865 DBG2("%s\n",name);
866
867 /*
868 * To find the picture number, go to the first digit. According to
869 * recent Exif specs, n_off can be either 3 or 4.
870 */
871 if (camdata->has_cmd[FUJI_SIZE]) fuji_size=fuji_picture_size(num);
872 else {
873 fuji_size=70000; /* this is an overestimation for DS7 */
874 DBG2("Image size not obtained, guessing %d",fuji_size);
875 };
876 return (fuji_size);
877 };
878
879 static void get_picture_list (FujiData *fjd)
880 {
881 int i, n_off;
882 char *name;
883 struct stat st;
884
885 pictures = fuji_nb_pictures();
886 maxnum = 100;
887 free(pinfo);
888 pinfo = calloc(pictures+1, sizeof(struct pict_info));
889 if (pinfo==NULL) {
890 DBG("Allocation error");
891 };
892
893 for (i = 1; i <= pictures; i++) {
894 DBG("Getting name...");
895
896 name = strdup(fuji_picture_name(i));
897 pinfo[i].name = name;
898
899 DBG2("%s\n",name);
900
901 /*
902 * To find the picture number, go to the first digit. According to
903 * recent Exif specs, n_off can be either 3 or 4.
904 */
905 n_off = strcspn(name, "0123456789");
906 if ((pinfo[i].number = atoi(name+n_off)) > maxnum)
907 maxnum = pinfo[i].number;
908 if (fjd->has_cmd[FUJI_SIZE]) pinfo[i].size = fuji_picture_size(i);
909 else pinfo[i].size=65000;
910 pinfo[i].ondisk = !stat(name, &st);
911 }
912 }
913
914 static int download_picture(int n,int thumb,CameraFile *file,CameraPrivateLibrary *fjd)
915 {
916 clock_t t1, t2;
917 char name[100];
918 long int file_size;
919 char *data;
920
921 DBG3("download_picture: %d,%s",n,thumb?"thumb":"pic");
922
923 if (!thumb) {
924 fuji_size=get_picture_info(n,name,fjd);
925 DBG3("Info %3d %12s ", n, name);
926 }
927 else fuji_size=10500; /* Probly not same for all cams, better way ? */
928
929 DBG2("calling download for %d bytes",fuji_size);
930
931 t1 = times(0);
932 if (cmd2(0, (thumb?0:0x02), n)==-1) return(GP_ERROR);
933
934 DBG3("Download :%4d actual bytes vs expected %4d bytes\n",
935 fuji_count ,fuji_size);
936
937 /* file->bytes_read=fuji_count; */
938 /* add room for thumb-decode */
939 /* file->size=fuji_count+(thumb?128:0); */
940 file_size=fuji_count+(thumb?128:0);
941
942 data=malloc(file_size);
943
944 if (data==NULL) return(GP_ERROR);
945
946 memcpy(data,fuji_buffer,fuji_count);
947
948 gp_file_set_data_and_size(file,data,file_size);
949
950 t2 = times(0);
951
952 DBG2("%3d seconds, ", (int)(t2-t1) / CLK_TCK);
953 DBG2("%4d bytes/s\n",
954 fuji_count * CLK_TCK / (int)(t2-t1));
955
956 if (fjd->has_cmd[17]&&!thumb){
957 if (!thumb&&(fuji_count != fuji_size)){
958 /* gp_frontend_status(NULL,"Short picture file--disk full or quota exceeded\n"); */
959 return(GP_ERROR);
960 };
961 };
962 return(GP_OK);
963
964 }
965
966 static int fuji_free_memory (void)
967 {
968 cmd0 (0, FUJI_CMD_FREE_MEM);
969 return answer[5] + (answer[6]<<8) + (answer[7]<<16) + (answer[8]<<24);
970 }
971
972 static int upload_pic (const char *picname)
973 {
974 unsigned char buffer[516];
975 const char *p;
976 struct stat st;
977 FILE *fd;
978 int c, last, len, free_space;
979
980 fd = fopen(picname, "r");
981 if (fd == NULL) {
982 /* update_status("Cannot open file for upload"); */
983 return 0;
984 }
985 if (fstat(fileno(fd), &st) < 0) {
986 DBG("fstat");
987 return 0;
988 }
989 free_space = fuji_free_memory();
990 fprintf(stderr, "Uploading %s (size %d, available %d bytes)\n",
991 picname, (int) st.st_size, free_space);
992 if (st.st_size > free_space) {
993 fprintf(stderr, " not enough space\n");
994 return 0;
995 }
996 if ((p = strrchr(picname, '/')) != NULL)
997 picname = p+1;
998 if (strlen(picname) != 12 || memcmp(picname,"DSC",3) || memcmp(picname+8,".JPG",4)) {
999 picname = auto_rename();
1000 fprintf(stderr, " file renamed %s\n", picname);
1001 }
1002 buffer[0] = 0;
1003 buffer[1] = 0x0F;
1004 buffer[2] = 12;
1005 buffer[3] = 0;
1006 memcpy(buffer+4, picname, 12);
1007 cmd(16, buffer);
1008 if (answer[4] != 0) {
1009 fprintf(stderr, " rejected by the camera\n");
1010 return 0;
1011 }
1012 buffer[1] = 0x0E;
1013 while(1) {
1014 len = fread(buffer+4, 1, 512, fd);
1015 if (!len) break;
1016 buffer[2] = len;
1017 buffer[3] = (len>>8);
1018 last = 1;
1019 if ((c = getc(fd)) != EOF) {
1020 last = 0;
1021 ungetc(c, fd);
1022 }
1023 if (!last && interrupted) {
1024 fprintf(stderr, "Interrupted!\n");
1025 exit(1);
1026 }
1027 again:
1028 send_packet(4+len, buffer, last);
1029 /*wait_for_input(1);*/
1030 if (get_byte() == 0x15)
1031 goto again;
1032 }
1033 fclose(fd);
1034 fprintf(stderr, " looks ok\n");
1035 return 1;
1036 }
1037
1038 #endif
1039