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