1 /*
2         Copyright 2000 Mariusz Zynel <mariusz@mizar.org> (gPhoto port)
3         Copyright 2000 Fredrik Roubert <roubert@df.lth.se> (idea)
4         Copyright 1999 Galen Brooks <galen@nine.com> (DC1580 code)
5 
6         This file is part of the gPhoto project and may only be used,  modified,
7         and distributed under the terms of the gPhoto project license,  COPYING.
8         By continuing to use, modify, or distribute  this file you indicate that
9         you have read the license, understand and accept it fully.
10 
11         THIS  SOFTWARE IS PROVIDED AS IS AND COME WITH NO WARRANTY  OF ANY KIND,
12         EITHER  EXPRESSED OR IMPLIED.  IN NO EVENT WILL THE COPYRIGHT  HOLDER BE
13         LIABLE FOR ANY DAMAGES RESULTING FROM THE USE OF THIS SOFTWARE.
14 
15         Note:
16 
17         This is a Panasonic PV/NV-DC1580 camera gPhoto library source code.
18 
19         An algorithm  for  checksums  borrowed  from  Michael McCormack's  Nikon
20         CoolPix 600 library for gPhoto1.
21 */
22 
23 #include "config.h"
24 
25 #include <stdlib.h>
26 #include <stdarg.h>
27 #include <sys/stat.h>
28 #ifdef HAVE_MEMORY_H
29 #include <memory.h>
30 #endif
31 #include <string.h>
32 
33 #ifdef ENABLE_NLS
34 #  include <libintl.h>
35 #  undef _
36 #  define _(String) dgettext (GETTEXT_PACKAGE, String)
37 #  ifdef gettext_noop
38 #    define N_(String) gettext_noop (String)
39 #  else
40 #    define N_(String) (String)
41 #  endif
42 #else
43 #  define _(String) (String)
44 #  define N_(String) (String)
45 #endif
46 
47 #include "dc.h"
48 #include "dc1580.h"
49 
50 #ifndef __FILE__
51 #  define __FILE__ "dc1580.c"
52 #endif
53 
54 #define GP_MODULE "dc1580"
55 
56 /******************************************************************************/
57 
58 /* Internal utility functions */
59 
60 /* dsc2_checksum - establish checksum for size bytes in buffer */
61 
dsc2_checksum(char * buffer,int size)62 static uint8_t dsc2_checksum(char *buffer, int size) {
63 
64         int     checksum = 0;
65         int     i;
66 
67         for (i = 1; i < size - 2; i++) {
68                 checksum += buffer[i];
69                 checksum %= 0x100;
70         }
71 
72         return checksum;
73 }
74 
75 /* dsc2_sendcmd - send command with data to DSC */
76 
dsc2_sendcmd(Camera * camera,uint8_t cmd,long int data,uint8_t sequence)77 static int dsc2_sendcmd(Camera *camera, uint8_t cmd, long int data, uint8_t sequence) {
78 
79         unsigned int     i;
80 
81         DEBUG_PRINT_MEDIUM(("Sending command: 0x%02x, data: %i, sequence: %i.", cmd, data, sequence));
82 
83         memset(camera->pl->buf, 0, 16);
84 
85         camera->pl->buf[0] = 0x08;
86         camera->pl->buf[1] = sequence;
87         camera->pl->buf[2] = 0xff - sequence;
88         camera->pl->buf[3] = cmd;
89 
90         for (i = 0; i < sizeof(data); i++)
91                 camera->pl->buf[4 + i] = (uint8_t)(data >> 8*i);
92 
93         camera->pl->buf[14] = dsc2_checksum(camera->pl->buf, 16);
94 
95         return gp_port_write(camera->port, camera->pl->buf, 16);
96 }
97 
98 /* dsc2_retrcmd - retrieve command and its data from DSC */
99 
dsc2_retrcmd(Camera * camera)100 static int dsc2_retrcmd(Camera *camera) {
101 
102         int     result = GP_ERROR;
103         int     s;
104 
105         if ((s = gp_port_read(camera->port, camera->pl->buf, 16)) == GP_ERROR)
106                 return GP_ERROR;
107 
108 /*      Make sense in debug only. Done on gp_port level.
109         if (0 < s)
110                 dsc_dumpmem(camera->pl->buf, s);
111 
112 */
113         if (s != 16 ||  camera->pl->buf[DSC2_BUF_BASE] != 0x08 ||
114                         camera->pl->buf[DSC2_BUF_SEQ] != 0xff - (uint8_t)camera->pl->buf[DSC2_BUF_SEQC]) {
115                 RETURN_ERROR(EDSCBADRSP);
116                 /* bad response */
117         }
118         else
119                 result = camera->pl->buf[DSC2_BUF_CMD];
120 
121         DEBUG_PRINT_MEDIUM(("Retrieved command: %i.", result));
122 
123         return result;
124 }
125 
126 /* dsc2_connect - try hand shake with camera and establish connection */
127 
dsc2_connect(Camera * camera,int speed)128 static int dsc2_connect(Camera *camera, int speed) {
129 
130         DEBUG_PRINT_MEDIUM(("Connecting camera with speed: %i.", speed));
131 
132         if (dsc1_setbaudrate(camera, speed) != GP_OK)
133                 return GP_ERROR;
134 
135         if (dsc1_getmodel(camera) != DSC2)
136                 RETURN_ERROR(EDSCBADDSC);
137                 /* bad camera model */
138 
139         if (dsc2_sendcmd(camera, DSC2_CMD_CONNECT, 0, 0) != GP_OK)
140                 return GP_ERROR;
141 
142         if (dsc2_retrcmd(camera) != DSC2_RSP_OK)
143                 RETURN_ERROR(EDSCBADRSP);
144                 /* bad response */
145 
146         DEBUG_PRINT_MEDIUM(("Camera connected successfully."));
147 
148         return GP_OK;
149 }
150 
151 /* dsc2_disconnect - reset camera, free buffers and close files */
152 
dsc2_disconnect(Camera * camera)153 static int dsc2_disconnect(Camera *camera) {
154 
155         DEBUG_PRINT_MEDIUM(("Disconnecting the camera."));
156 
157         if (dsc2_sendcmd(camera, DSC2_CMD_RESET, 0, 0) != GP_OK)
158                 return GP_ERROR;
159 
160         if (dsc2_retrcmd(camera) != DSC2_RSP_OK)
161                 RETURN_ERROR(EDSCBADRSP)
162                 /* bad response */
163         else
164                 sleep(DSC_PAUSE); /* let camera to redraw its screen */
165 
166         DEBUG_PRINT_MEDIUM(("Camera disconnected."));
167 
168         return GP_OK;
169 }
170 
171 /* dsc2_getindex - retrieve the number of images stored in camera memory */
172 
dsc2_getindex(Camera * camera)173 static int dsc2_getindex(Camera *camera) {
174 
175         int     result = GP_ERROR;
176 
177         DEBUG_PRINT_MEDIUM(("Retrieving the number of images."));
178 
179         if (dsc2_sendcmd(camera, DSC2_CMD_GET_INDEX, 0, 0) != GP_OK)
180                 return GP_ERROR;
181 
182         if (dsc2_retrcmd(camera) == DSC2_RSP_INDEX)
183                 result =
184                         ((uint32_t)camera->pl->buf[DSC2_BUF_DATA]) |
185                         ((uint8_t)camera->pl->buf[DSC2_BUF_DATA + 1] << 8) |
186                         ((uint8_t)camera->pl->buf[DSC2_BUF_DATA + 2] << 16) |
187                         ((uint8_t)camera->pl->buf[DSC2_BUF_DATA + 3] << 24);
188         else
189                 RETURN_ERROR(EDSCBADRSP);
190                 /* bad response */
191 
192         DEBUG_PRINT_MEDIUM(("Number of images: %i", result));
193 
194         return result;
195 }
196 
197 /* dsc2_delete - delete image #index from camera memory */
198 
dsc2_delete(Camera * camera,int index)199 static int dsc2_delete(Camera *camera, int index) {
200 
201         DEBUG_PRINT_MEDIUM(("Deleting image: %i.", index));
202 
203         if (index < 1)
204                 RETURN_ERROR(EDSCBADNUM);
205                 /* bad image number */
206 
207         if (dsc2_sendcmd(camera, DSC2_CMD_DELETE, index, 0) != GP_OK)
208                 return GP_ERROR;
209 
210         if (dsc2_retrcmd(camera) != DSC2_RSP_OK)
211                 RETURN_ERROR(EDSCBADRSP);
212                 /* bad response */
213 
214         DEBUG_PRINT_MEDIUM(("Image: %i deleted.", index));
215         return GP_OK;
216 }
217 
218 /* dsc2_selectimage - select image to download, return its size */
219 
dsc2_selectimage(Camera * camera,int index,int thumbnail)220 static int dsc2_selectimage(Camera *camera, int index, int thumbnail) {
221 
222         int     size = 0;
223 
224         DEBUG_PRINT_MEDIUM(("Selecting image: %i, thumbnail: %i.", index, thumbnail));
225 
226         if (index < 1)
227                 RETURN_ERROR(EDSCBADNUM);
228                 /* bad image number */
229 
230         if (thumbnail == DSC_THUMBNAIL) {
231                 if (dsc2_sendcmd(camera, DSC2_CMD_THUMB, index, 0) != GP_OK)
232                         return GP_ERROR;
233         } else {
234                 if (dsc2_sendcmd(camera, DSC2_CMD_SELECT, index, 0) != GP_OK)
235                         return GP_ERROR;
236         }
237 
238         if (dsc2_retrcmd(camera) != DSC2_RSP_IMGSIZE)
239                 RETURN_ERROR(EDSCBADRSP);
240                 /* bad response */
241 
242         size =  ((uint32_t)camera->pl->buf[DSC2_BUF_DATA]) |
243                 ((uint8_t)camera->pl->buf[DSC2_BUF_DATA + 1] << 8) |
244                 ((uint8_t)camera->pl->buf[DSC2_BUF_DATA + 2] << 16) |
245                 ((uint8_t)camera->pl->buf[DSC2_BUF_DATA + 3] << 24);
246 
247         DEBUG_PRINT_MEDIUM(("Selected image: %i, thumbnail: %i, size: %i.", index, thumbnail, size));
248 
249         return size;
250 }
251 
252 /* gp_port_readimageblock - read #block block (1024 bytes) of an image into buf */
253 
dsc2_readimageblock(Camera * camera,int block,char * buffer)254 static int dsc2_readimageblock(Camera *camera, int block, char *buffer) {
255 
256         DEBUG_PRINT_MEDIUM(("Reading image block: %i.", block));
257 
258         if (dsc2_sendcmd(camera, DSC2_CMD_GET_DATA, block, block) != GP_OK)
259                 return GP_ERROR;
260 
261         if (gp_port_read(camera->port, camera->pl->buf, DSC_BUFSIZE) != DSC_BUFSIZE)
262                 RETURN_ERROR(EDSCBADRSP);
263                 /* bad response */
264 
265         if ((uint8_t)camera->pl->buf[0] != 1 ||
266                         (uint8_t)camera->pl->buf[1] != block ||
267                         (uint8_t)camera->pl->buf[2] != 0xff - block ||
268                         (uint8_t)camera->pl->buf[3] != DSC2_RSP_DATA ||
269                         (uint8_t)camera->pl->buf[DSC_BUFSIZE - 2] != dsc2_checksum(camera->pl->buf, DSC_BUFSIZE))
270                 RETURN_ERROR(EDSCBADRSP);
271                 /* bad response */
272 
273         if (buffer)
274                 memcpy(buffer, &camera->pl->buf[4], DSC_BLOCKSIZE);
275 
276         DEBUG_PRINT_MEDIUM(("Block: %i read in.", block));
277 
278         return DSC_BLOCKSIZE;
279 }
280 
281 /* dsc2_readimage - read #index image or thumbnail and return its contents */
282 
283 #if 0
284 static char *dsc2_readimage(Camera *camera, int index, int thumbnail, int *size) {
285 
286         char    kind[16];
287         int     blocks, i;
288         char    *buffer = NULL;
289 
290         DEBUG_PRINT_MEDIUM(("Reading image: %i, thumbnail: %i.", index, thumbnail));
291 
292         if ((*size = dsc2_selectimage(camera, index, thumbnail)) < 0)
293                 return NULL;
294 
295         if (thumbnail == DSC_THUMBNAIL)
296                 strcpy(kind, "thumbnail");
297         else
298                 strcpy(kind, "image");
299 
300         if (!(buffer = (char*)malloc(*size))) {
301                 DEBUG_PRINT_MEDIUM(("Failed to allocate memory for %s data.", kind));
302                 return NULL;
303         }
304 
305         blocks = (*size - 1)/DSC_BLOCKSIZE + 1;
306 
307         for (i = 0; i < blocks; i++) {
308                 if (dsc2_readimageblock(camera, i, &buffer[i*DSC_BLOCKSIZE]) == GP_ERROR) {
309                         DEBUG_PRINT_MEDIUM(("Error during %s transfer.", kind));
310                         free(buffer);
311                         return NULL;
312                 }
313         }
314 
315         DEBUG_PRINT_MEDIUM(("Image: %i read in.", index));
316 
317         return buffer;
318 }
319 #endif
320 
321 /* dsc2_setimagesize - set size of an image to upload to camera */
322 
dsc2_setimagesize(Camera * camera,int size)323 static int dsc2_setimagesize(Camera *camera, int size) {
324 
325         DEBUG_PRINT_MEDIUM(("Setting image size to: %i.", size));
326 
327         if (dsc2_sendcmd(camera, DSC2_CMD_SET_SIZE, size, 0) != GP_OK)
328                 return GP_ERROR;
329 
330         if (dsc2_retrcmd(camera) != DSC2_RSP_OK)
331                 RETURN_ERROR(EDSCBADRSP);
332                 /* bad response */
333 
334         DEBUG_PRINT_MEDIUM(("Image size set to: %i.", size));
335 
336         return GP_OK;
337 }
338 
339 /* gp_port_writeimageblock - write size bytes from buffer rounded to 1024 bytes to camera */
340 
dsc2_writeimageblock(Camera * camera,int block,char * buffer,int size)341 static int dsc2_writeimageblock(Camera *camera, int block, char *buffer, int size) {
342 
343         DEBUG_PRINT_MEDIUM(("Writing image block: %i.", block));
344 
345         memset(camera->pl->buf, 0, DSC_BUFSIZE);
346 
347         camera->pl->buf[0] = 0x01;
348         camera->pl->buf[1] = block;
349         camera->pl->buf[2] = 0xff - block;
350         camera->pl->buf[3] = DSC2_CMD_SEND_DATA;
351 
352         if (DSC_BLOCKSIZE < size)
353                 size = DSC_BLOCKSIZE;
354 
355         memcpy(&camera->pl->buf[4], buffer, size);
356 
357         camera->pl->buf[DSC_BUFSIZE - 2] = dsc2_checksum(camera->pl->buf, DSC_BUFSIZE);
358 
359         if (gp_port_write(camera->port, camera->pl->buf, DSC_BUFSIZE) != GP_OK)
360                 return GP_ERROR;
361 
362         if (dsc2_retrcmd(camera) != DSC2_RSP_OK)
363                 RETURN_ERROR(EDSCBADRSP);
364                 /* bad response */
365 
366         DEBUG_PRINT_MEDIUM(("Block: %i of size: %i written.", block, size));
367 
368         return GP_OK;
369 }
370 
371 /* dsc2_writeimage - write an image to camera memory, size bytes at buffer */
372 
373 #if 0
374 static int dsc2_writeimage(Camera *camera, char *buffer, int size) {
375 
376         int     blocks, blocksize, i;
377 
378         DEBUG_PRINT_MEDIUM(("Writing an image of size: %i.", size));
379 
380         if ((dsc2_setimagesize(camera, size)) != GP_OK)
381                 return GP_ERROR;
382 
383         blocks = (size - 1)/DSC_BLOCKSIZE + 1;
384 
385         for (i = 0; i < blocks; i++) {
386                 blocksize = size - i*DSC_BLOCKSIZE;
387                 if (DSC_BLOCKSIZE < blocksize)
388                         blocksize = DSC_BLOCKSIZE;
389                 if (dsc2_writeimageblock(camera, i, &buffer[i*DSC_BLOCKSIZE], blocksize) != GP_OK) {
390                         DEBUG_PRINT_MEDIUM(("Error during image transfer."));
391                         return GP_ERROR;
392                 }
393         }
394 
395         DEBUG_PRINT_MEDIUM(("Image written successfully."));
396 
397         return GP_OK;
398 }
399 #endif
400 
401 /* dsc2_preview - show selected image on camera's LCD  */
402 
403 #if 0
404 static int dsc2_preview(Camera *camera, int index) {
405 
406         if (index < 1)
407                 RETURN_ERROR(EDSCBADNUM);
408                 /* bad image number */
409 
410         if (dsc2_sendcmd(camera, DSC2_CMD_PREVIEW, index, 0) != GP_OK)
411                 return GP_ERROR;
412 
413         if (dsc2_retrcmd(camera) != DSC2_RSP_OK)
414                 RETURN_ERROR(EDSCBADRSP);
415                 /* bad response */
416 
417         return GP_OK;
418 }
419 #endif
420 
421 /******************************************************************************/
422 
423 /* Library interface functions */
424 
camera_id(CameraText * id)425 int camera_id (CameraText *id) {
426 
427         strcpy(id->text, "panasonic-dc1580");
428 
429         return (GP_OK);
430 }
431 
camera_abilities(CameraAbilitiesList * list)432 int camera_abilities (CameraAbilitiesList *list) {
433 
434         CameraAbilities a;
435         char    *models[] = {
436                         "Panasonic:DC1580",
437                         "Nikon:CoolPix 600",
438                         NULL };
439         int     i = 0, result;
440 
441         while (models[i]) {
442 		memset(&a, 0, sizeof(a));
443 		a.status = GP_DRIVER_STATUS_PRODUCTION;
444                 strcpy(a.model, models[i]);
445                 a.port         = GP_PORT_SERIAL;
446                 a.speed[0]     = 9600;
447                 a.speed[1]     = 19200;
448                 a.speed[2]     = 38400;
449                 a.speed[3]     = 57600;
450                 a.speed[4]     = 115200;
451                 a.speed[5]     = 0;
452                 a.operations        = 	GP_OPERATION_NONE;
453                 a.file_operations   = 	GP_FILE_OPERATION_DELETE |
454 					GP_FILE_OPERATION_PREVIEW;
455                 a.folder_operations = 	GP_FOLDER_OPERATION_PUT_FILE;
456 
457                 CHECK (gp_abilities_list_append(list, a));
458                 i++;
459         }
460 
461         return GP_OK;
462 }
463 
camera_exit(Camera * camera,GPContext * context)464 static int camera_exit (Camera *camera, GPContext *context) {
465         gp_context_status(context, _("Disconnecting camera."));
466         dsc2_disconnect(camera);
467 	if (camera->pl->buf) {
468 		free (camera->pl->buf);
469 		camera->pl->buf = NULL;
470 	}
471 	free (camera->pl);
472 	camera->pl = NULL;
473         return (GP_OK);
474 }
475 
file_list_func(CameraFilesystem * fs,const char * folder,CameraList * list,void * data,GPContext * context)476 static int file_list_func (CameraFilesystem *fs, const char *folder,
477 			   CameraList *list, void *data, GPContext *context) {
478 
479         Camera  *camera = data;
480         int     count, result;
481 
482 	CHECK (count = dsc2_getindex(camera));
483 
484         CHECK (gp_list_populate(list, DSC_FILENAMEFMT, count));
485 
486         return GP_OK;
487 }
488 
get_info_func(CameraFilesystem * fs,const char * folder,const char * filename,CameraFileInfo * info,void * data,GPContext * context)489 static int get_info_func (CameraFilesystem *fs, const char *folder,
490 			  const char *filename, CameraFileInfo *info,
491 			  void *data, GPContext *context) {
492 
493         Camera  *camera = data;
494 	int     index, result;
495 
496         /* index is the 0-based image number on the camera */
497         CHECK (index = gp_filesystem_number(camera->fs, folder, filename, context));
498         index++;
499 
500 	info->file.fields = GP_FILE_INFO_TYPE | GP_FILE_INFO_SIZE;
501 	strcpy(info->file.type, GP_MIME_JPEG);
502         info->file.size = dsc2_selectimage(camera, index, DSC_FULLIMAGE);
503 
504 	info->preview.fields = GP_FILE_INFO_TYPE | GP_FILE_INFO_SIZE;
505 	strcpy(info->preview.type, GP_MIME_JPEG);
506         info->preview.size = dsc2_selectimage(camera, index, DSC_THUMBNAIL);
507 
508         return GP_OK;
509 }
510 
get_file_func(CameraFilesystem * fs,const char * folder,const char * filename,CameraFileType type,CameraFile * file,void * data,GPContext * context)511 static int get_file_func (CameraFilesystem *fs, const char *folder,
512 			  const char *filename, CameraFileType type,
513 			  CameraFile *file, void *data, GPContext *context) {
514 
515 	Camera *camera = data;
516         int     index, i, size, blocks, result;
517 	unsigned int id;
518 
519         gp_context_status(context, _("Downloading %s."), filename);
520 
521         /* index is the 0-based image number on the camera */
522         CHECK (index = gp_filesystem_number(camera->fs, folder, filename, context));
523         index++;
524 
525 	switch (type) {
526 	case GP_FILE_TYPE_PREVIEW:
527 		size = dsc2_selectimage(camera, index, DSC_THUMBNAIL);
528 		break;
529 	case GP_FILE_TYPE_NORMAL:
530 		size = dsc2_selectimage(camera, index, DSC_FULLIMAGE);
531 		break;
532 	default:
533 		return (GP_ERROR_NOT_SUPPORTED);
534 	}
535 	if (size < 0)
536 		return (size);
537 
538 	CHECK (gp_file_set_mime_type(file, GP_MIME_JPEG));
539 
540         blocks = (size - 1)/DSC_BLOCKSIZE + 1;
541 
542 	id = gp_context_progress_start (context, blocks, _("Getting data..."));
543         for (i = 0; i < blocks; i++) {
544 		CHECK (dsc2_readimageblock(camera, i, NULL));
545                 CHECK (gp_file_append(file, &camera->pl->buf[4], DSC_BLOCKSIZE));
546 		gp_context_progress_update (context, id, i + 1);
547 		if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL)
548 			return (GP_ERROR_CANCEL);
549         }
550 	gp_context_progress_stop (context, id);
551 
552         return GP_OK;
553 }
554 
put_file_func(CameraFilesystem * fs,const char * folder,const char * name,CameraFileType type,CameraFile * file,void * user_data,GPContext * context)555 static int put_file_func (CameraFilesystem *fs, const char *folder, const char *name,
556 			  CameraFileType type, CameraFile *file, void *user_data,
557 			  GPContext *context) {
558 
559 	Camera *camera = user_data;
560         int             blocks, blocksize, i, result;
561 	const char      *data;
562 	long unsigned int size;
563 	unsigned int id;
564 
565         gp_context_status(context, _("Uploading image: %s."), name);
566 
567 /*      We can not figure out file type, at least by now. (? curious, mime type -Marcus)
568 
569         if (strcmp(file->type, "image/jpg") != 0) {
570                 dsc_print_message(camera, "JPEG image format allowed only.");
571                 return GP_ERROR;
572         }
573 */
574 	gp_file_get_data_and_size (file, &data, &size);
575         if (size > DSC_MAXIMAGESIZE) {
576                 gp_context_message (context, _("File size is %ld bytes. "
577 				   "The size of the largest file possible to "
578 				   "upload is: %i bytes."), size,
579 				   DSC_MAXIMAGESIZE);
580                 return GP_ERROR;
581         }
582 
583 	if ((result = dsc2_setimagesize(camera, size)) != GP_OK) return result;
584 
585         blocks = (size - 1)/DSC_BLOCKSIZE + 1;
586 
587 	id = gp_context_progress_start (context, blocks, _("Uploading..."));
588         for (i = 0; i < blocks; i++) {
589                 blocksize = size - i*DSC_BLOCKSIZE;
590                 if (DSC_BLOCKSIZE < blocksize)
591                         blocksize = DSC_BLOCKSIZE;
592 		result = dsc2_writeimageblock(camera, i,
593 					       (char*)&data[i*DSC_BLOCKSIZE],
594 					       blocksize);
595 		if (result != GP_OK)
596 			return result;
597 		gp_context_progress_update (context, id, i + 1);
598 		if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL)
599 			return (GP_ERROR_CANCEL);
600         }
601 	gp_context_progress_stop (context, id);
602 
603         return GP_OK;
604 }
605 
delete_file_func(CameraFilesystem * fs,const char * folder,const char * filename,void * data,GPContext * context)606 static int delete_file_func (CameraFilesystem *fs, const char *folder,
607 			     const char *filename, void *data,
608 			     GPContext *context) {
609 
610 	Camera *camera = data;
611         int     index, result;
612 
613         gp_context_status(context, _("Deleting image %s."), filename);
614 
615         /* index is the 0-based image number on the camera */
616 	CHECK (index = gp_filesystem_number (camera->fs, folder, filename, context));
617         index++;
618 
619         return dsc2_delete(camera, index);
620 }
621 
camera_about(Camera * camera,CameraText * about,GPContext * context)622 static int camera_about (Camera *camera, CameraText *about, GPContext *context)
623 {
624         strcpy(about->text,
625                         _("Panasonic DC1580 gPhoto2 library\n"
626                         "Mariusz Zynel <mariusz@mizar.org>\n\n"
627                         "Based on dc1000 program written by\n"
628                         "Fredrik Roubert <roubert@df.lth.se> and\n"
629                         "Galen Brooks <galen@nine.com>."));
630         return (GP_OK);
631 }
632 
633 static CameraFilesystemFuncs fsfuncs = {
634 	.file_list_func = file_list_func,
635 	.get_info_func = get_info_func,
636 	.get_file_func = get_file_func,
637 	.put_file_func = put_file_func,
638 	.del_file_func = delete_file_func,
639 };
640 
camera_init(Camera * camera,GPContext * context)641 int camera_init (Camera *camera, GPContext *context)
642 {
643         GPPortSettings settings;
644         int result, selected_speed;
645 
646         /* First, set up all the function pointers */
647         camera->functions->exit                 = camera_exit;
648         camera->functions->about                = camera_about;
649 
650 	camera->pl = malloc (sizeof (CameraPrivateLibrary));
651 	if (!camera->pl)
652 		return (GP_ERROR_NO_MEMORY);
653 	camera->pl->buf = malloc (sizeof (char) * DSC_BUFSIZE);
654 	if (!camera->pl->buf) {
655 		free (camera->pl);
656 		camera->pl = NULL;
657 		return (GP_ERROR_NO_MEMORY);
658 	}
659 
660 	CHECK (gp_port_set_timeout (camera->port, 5000));
661 
662 	/* Configure the port (and remember the speed) */
663 	CHECK (gp_port_get_settings (camera->port, &settings));
664 	selected_speed = settings.serial.speed;
665         settings.serial.speed      = 9600; /* hand shake speed */
666         settings.serial.bits       = 8;
667         settings.serial.parity     = 0;
668         settings.serial.stopbits   = 1;
669         CHECK (gp_port_set_settings (camera->port, settings));
670 
671       	CHECK (gp_filesystem_set_funcs (camera->fs, &fsfuncs, camera));
672 	/* Connect with the selected speed */
673         return dsc2_connect(camera, selected_speed);
674 }
675 
676 /* End of dc1580.c */
677