3 * Copyright © 2003 Marcus Meissner <marcus@jet.franken.de>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
28 #include <gphoto2/gphoto2-library.h>
29 #include <gphoto2/gphoto2-result.h>
30 #include <gphoto2/gphoto2-port-log.h>
35 # define _(String) dgettext (GETTEXT_PACKAGE, String)
37 # define N_(String) gettext_noop (String)
39 # define N_(String) (String)
42 # define _(String) (String)
43 # define N_(String) (String)
48 * channel host/client length data checksum padding
49 * 01 01 00 00 07 00 00 00 <7 byte> <1 byte> <fill to next 4>
54 g3_channel_read(GPPort *port, int *channel, char **buffer, int *len)
56 unsigned char xbuf[0x800];
57 int tocopy, ret, curlen;
59 ret = gp_port_read(port, xbuf, 0x800);
61 gp_log(GP_LOG_ERROR, "g3", "read error in g3_channel_read\n");
65 if ((xbuf[2] != 0xff) && (xbuf[3] != 0xff)) {
66 gp_log(GP_LOG_ERROR, "g3" ,"first bytes do not match.\n");
71 *len = xbuf[4] + (xbuf[5]<<8) + (xbuf[6]<<16) + (xbuf[7]<<24);
72 /* Safety buffer of 0x800 ... we can only read in 0x800 chunks,
73 * otherwise the communication gets hickups. However *len might be
77 *buffer = malloc(*len + 1 + 0x800);
79 *buffer = realloc(*buffer, *len + 1 + 0x800);
81 if (tocopy > 0x800-8) tocopy = 0x800-8;
82 memcpy(*buffer, xbuf+8, tocopy);
84 while (curlen < *len) {
85 ret = gp_port_read(port, *buffer + curlen, 0x800);
87 gp_log(GP_LOG_ERROR, "g3", "read error in g3_channel_read\n");
92 (*buffer)[*len] = 0x00;
97 g3_channel_read_bytes(
98 GPPort *port, int *channel, char **buffer, int expected, GPContext *context,
102 int id, ret, len, xlen = 0;
105 *buffer = malloc (expected);
107 *buffer = realloc (*buffer, expected);
108 xbuf = malloc(65536 + 12);
110 id = gp_context_progress_start (context, expected, "%s", msg);
112 /* The camera lets us read in packets of at least max 64kb size. */
113 while (expected > 0) {
115 if (rest > 65536) rest = 65536;
117 rest = (rest + 9 + 3) & ~3;
118 if (rest < 0x800) rest = 0x800;
120 ret = gp_port_read(port, xbuf, rest);
122 gp_log(GP_LOG_ERROR, "g3", "read error in g3_channel_read\n");
126 gp_log(GP_LOG_ERROR, "g3", "read error in g3_channel_read\n");
130 if ((xbuf[2] != 0xff) || (xbuf[3] != 0xff)) {
131 gp_log(GP_LOG_ERROR, "g3", "first bytes do not match.\n");
135 len = xbuf[4] + (xbuf[5]<<8) + (xbuf[6]<<16) + (xbuf[7]<<24);
138 gp_log(GP_LOG_ERROR,"g3","len %d is > rest expected %d\n", len, expected);
139 memcpy(*buffer+xlen, xbuf+8, len);
142 gp_context_progress_update (context, id, xlen);
144 gp_context_progress_stop (context, id);
150 g3_channel_write(GPPort *port, int channel, char *buffer, int len)
153 int ret = GP_OK, nlen, curlen = 0;
158 if (sendlen>65536) sendlen = 65536;
159 nlen = (4 + 4 + sendlen + 1 + 3) & ~3;
160 xbuf = calloc(nlen,1);
166 xbuf[4] = sendlen & 0xff;
167 xbuf[5] = (sendlen>>8) & 0xff;
168 xbuf[6] = (sendlen>>16) & 0xff;
169 xbuf[7] = (sendlen>>24) & 0xff;
170 memcpy(xbuf+8, buffer + curlen, sendlen);
172 xbuf[8+sendlen] = 0x03;
173 ret = gp_port_write( port, (char*)xbuf, nlen);
175 if (ret < GP_OK) break;
182 g3_ftp_command_and_reply(GPPort *port, char *cmd, char **reply) {
183 int ret, channel, len;
186 realcmd = malloc(strlen(cmd)+2+1);strcpy(realcmd, cmd);strcat(realcmd, "\r\n");
188 gp_log(GP_LOG_DEBUG, "g3" , "sending %s", cmd);
189 ret = g3_channel_write(port, 1, realcmd, strlen(realcmd));
192 gp_log (GP_LOG_ERROR, "g3", "ftp command write failed? %d\n", ret);
195 ret = g3_channel_read(port, &channel, reply, &len);
197 gp_log (GP_LOG_ERROR, "g3", "ftp reply read failed? %d\n", ret);
200 s = strchr(*reply, '\r');
203 gp_log(GP_LOG_DEBUG, "g3" , "reply %s", *reply);
208 camera_id (CameraText *id)
210 strcpy(id->text, "ricoh_g3");
215 camera_abilities (CameraAbilitiesList *list)
219 memset(&a, 0, sizeof(a));
220 strcpy(a.model, "Ricoh:Caplio G3");
221 a.status = GP_DRIVER_STATUS_PRODUCTION;
222 a.port = GP_PORT_USB;
223 a.usb_vendor = 0x5ca;
224 a.usb_product = 0x2204;
226 a.operations = GP_OPERATION_NONE;
227 a.file_operations = GP_FILE_OPERATION_DELETE | GP_FILE_OPERATION_EXIF;
228 a.folder_operations = GP_FOLDER_OPERATION_MAKE_DIR |
229 GP_FOLDER_OPERATION_REMOVE_DIR ;
231 gp_abilities_list_append(list, a);
233 strcpy(a.model, "Ricoh:Caplio RR30");
234 a.usb_vendor = 0x5ca;
235 a.usb_product = 0x2202;
236 gp_abilities_list_append(list, a);
238 strcpy(a.model, "Ricoh:Caplio 300G");
239 a.usb_vendor = 0x5ca;
240 a.usb_product = 0x2203;
241 gp_abilities_list_append(list, a);
243 strcpy(a.model, "Medion:MD 6126");
244 a.usb_vendor = 0x5ca;
245 a.usb_product = 0x2205;
246 gp_abilities_list_append(list, a);
248 strcpy(a.model, "Ricoh:Caplio G4");
249 a.usb_vendor = 0x5ca;
250 a.usb_product = 0x2208;
251 gp_abilities_list_append(list, a);
253 strcpy(a.model, "Ricoh:Capilo RX");
254 a.usb_vendor = 0x5ca;
255 a.usb_product = 0x220b;
256 gp_abilities_list_append(list, a);
258 strcpy(a.model, "Ricoh:Caplio GX");
259 a.usb_vendor = 0x5ca;
260 a.usb_product = 0x220c;
261 gp_abilities_list_append(list, a);
263 strcpy(a.model, "Ricoh:Caplio R1");
264 a.usb_vendor = 0x5ca;
265 a.usb_product = 0x220d;
266 gp_abilities_list_append(list, a);
268 /* same id as above */
269 strcpy(a.model, "Ricoh:Caplio RZ1");
270 a.usb_vendor = 0x5ca;
271 a.usb_product = 0x220d;
272 gp_abilities_list_append(list, a);
274 strcpy(a.model, "Sea & Sea:5000G");
275 a.usb_vendor = 0x5ca;
276 a.usb_product = 0x220e;
277 gp_abilities_list_append(list, a);
279 strcpy(a.model, "Rollei:dr5");
280 a.usb_vendor = 0x5ca;
281 a.usb_product = 0x220f;
282 gp_abilities_list_append(list, a);
284 strcpy(a.model, "Ricoh:Caplio R1v");
285 a.usb_vendor = 0x5ca;
286 a.usb_product = 0x2212;
287 gp_abilities_list_append(list, a);
289 strcpy(a.model, "Ricoh:Caplio R2");
290 a.usb_vendor = 0x5ca;
291 a.usb_product = 0x2213;
292 gp_abilities_list_append(list, a);
294 strcpy(a.model, "Ricoh:Caplio GX 8");
295 a.usb_vendor = 0x5ca;
296 a.usb_product = 0x2214;
297 gp_abilities_list_append(list, a);
299 strcpy(a.model, "Ricoh:Caplio R3");
300 a.usb_vendor = 0x5ca;
301 a.usb_product = 0x2216;
302 gp_abilities_list_append(list, a);
304 strcpy(a.model, "Ricoh:Caplio R4");
305 a.usb_vendor = 0x5ca;
306 a.usb_product = 0x2217;
307 gp_abilities_list_append(list, a);
309 strcpy(a.model, "Ricoh:Caplio R5");
310 a.usb_vendor = 0x5ca;
311 a.usb_product = 0x221a;
312 gp_abilities_list_append(list, a);
318 g3_cwd_command( GPPort *port, const char *folder) {
319 char *cmd, *reply = NULL;
322 cmd = malloc(strlen("CWD ") + strlen(folder) + 2 + 1);
323 sprintf(cmd,"CWD %s", folder);
324 ret = g3_ftp_command_and_reply(port, cmd, &reply);
327 if (reply) free(reply);
330 if (reply[0]=='5') /* Failed, most likely no such directory */
331 ret = GP_ERROR_DIRECTORY_NOT_FOUND;
337 get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
338 CameraFileType type, CameraFile *file, void *data,
341 Camera *camera = data;
342 char *buf = NULL, *reply = NULL, *cmd =NULL, *msg = NULL;
343 int ret, channel, bytes, seek, len;
345 ret = g3_cwd_command (camera->port, folder);
346 if (ret < GP_OK) goto out;
349 case GP_FILE_TYPE_NORMAL:
350 msg = _("Downloading...");
351 if (strstr(filename,"AVI") || strstr(filename,"avi"))
352 msg = _("Downloading movie...");
353 if (strstr(filename,"jpg") || strstr(filename,"JPG") ||
354 strstr(filename,"tif") || strstr(filename,"TIF")
356 msg = _("Downloading image...");
357 if (strstr(filename,"wav") || strstr(filename,"WAV"))
358 msg = _("Downloading audio...");
359 cmd = malloc(strlen("RETR ") + strlen(filename) + 2 + 1);
360 sprintf(cmd,"RETR %s", filename);
361 ret = g3_ftp_command_and_reply(camera->port, cmd, &buf);
363 if (ret < GP_OK) goto out;
364 if (buf[0] != '1') { /* error, most likely file not found */
365 ret = GP_ERROR_FILE_NOT_FOUND;
370 sscanf(buf, "150 data connection for RETR.(%d)", &bytes);
372 case GP_FILE_TYPE_EXIF:
373 msg = _("Downloading EXIF data...");
374 if (!strstr(filename,".JPG") && !strstr(filename,".jpg")) {
375 gp_context_error (context,_("No EXIF data available for %s."),
377 ret = GP_ERROR_FILE_NOT_FOUND;
380 cmd = malloc(strlen("-SRET ") + strlen(filename) + 2 + 1);
381 sprintf(cmd,"-SRET %s", filename);
382 ret = g3_ftp_command_and_reply(camera->port, cmd, &buf);
384 if (ret < GP_OK) goto out;
385 if (buf[0] != '1') { /* error, most likely file not found */
386 ret = GP_ERROR_FILE_NOT_FOUND;
390 sscanf(buf, "150 %d byte Seek=%d", &bytes, &seek);
392 /* FIXME: pretty bad, the camera has some time out problems
394 gp_context_error (context,_("No EXIF data available for %s."),
396 ret = GP_ERROR_FILE_NOT_FOUND;
397 g3_channel_read(camera->port, &channel, &reply, &len); /* reply */
403 return GP_ERROR_NOT_SUPPORTED;
406 ret = g3_channel_read_bytes(camera->port, &channel, &buf, bytes, context, msg);
407 if (ret < GP_OK) goto out;
408 ret = g3_channel_read(camera->port, &channel, &reply, &len); /* reply */
409 if (ret < GP_OK) goto out;
410 gp_log(GP_LOG_DEBUG, "g3" , "reply %s", reply);
411 gp_file_set_data_and_size (file, buf, bytes);
412 buf = NULL; /* now owned by libgphoto2 filesystem */
416 if (reply) free(reply);
421 /* Works to some degree, but the firmware on the camera is not really happy
422 * with it and sometimes refuses to send data the correct way
425 put_file_func (CameraFilesystem *fs, const char *folder, CameraFile *file,
426 void *data, GPContext *context)
428 Camera *camera = data;
429 char *buf = NULL, *reply = NULL, *cmd =NULL;
430 const char *fn = NULL, *imgdata = NULL;
431 int ret, channel, len;
434 ret = g3_cwd_command (camera->port, folder);
435 if (ret < GP_OK) goto out;
437 ret = gp_file_get_name (file, &fn);
438 if (ret < GP_OK) goto out;
439 ret = gp_file_get_data_and_size (file, &imgdata, &size);
440 if (ret < GP_OK) goto out;
442 cmd = malloc(strlen("-STOR ") + 20 + strlen(fn) + 2 + 1);
443 sprintf(cmd,"-STOR %ld %s", size, fn);
444 ret = g3_ftp_command_and_reply(camera->port, cmd, &buf);
446 if (ret < GP_OK) goto out;
447 if (buf[0] != '1') { /* error, most likely file not found */
451 ret = g3_channel_write(camera->port, 2, (char*)imgdata, size); /* data */
452 if (ret < GP_OK) goto out;
453 ret = g3_channel_read(camera->port, &channel, &reply, &len); /* reply */
454 if (ret < GP_OK) goto out;
457 if (reply) free(reply);
463 delete_file_func (CameraFilesystem *fs, const char *folder,
464 const char *filename, void *data, GPContext *context)
466 Camera *camera = data;
467 char *reply = NULL, *cmd = NULL;
470 ret = g3_cwd_command (camera->port, folder);
474 cmd = malloc(strlen("DELE ")+strlen(filename)+1);
475 if (!cmd) return GP_ERROR_NO_MEMORY;
476 sprintf(cmd,"DELE %s",filename);
477 ret = g3_ftp_command_and_reply(camera->port, cmd, &reply);
480 if (reply[0] == '5') {
481 gp_context_error (context, _("Could not delete file."));
486 if (reply) free(reply);
491 rmdir_func (CameraFilesystem *fs, const char *folder,
492 const char *name, void *data, GPContext *context)
494 Camera *camera = data;
495 char *reply = NULL, *cmd = NULL;
498 ret = g3_cwd_command (camera->port, folder);
502 cmd = realloc(cmd,strlen("RMD ")+strlen(name)+1);
503 if (!cmd) return GP_ERROR_NO_MEMORY;
504 sprintf(cmd,"RMD %s",name);
505 ret = g3_ftp_command_and_reply(camera->port, cmd, &reply);
508 if (reply[0] == '5') {
509 gp_context_error (context, _("Could not remove directory."));
514 if (reply) free(reply);
519 mkdir_func (CameraFilesystem *fs, const char *folder,
520 const char *name, void *data, GPContext *context)
522 Camera *camera = data;
523 char *reply = NULL, *cmd = NULL;
526 ret = g3_cwd_command (camera->port, folder);
530 cmd = realloc(cmd,strlen("MKD ")+strlen(name)+1);
531 if (!cmd) return GP_ERROR_NO_MEMORY;
532 sprintf(cmd,"MKD %s",name);
533 ret = g3_ftp_command_and_reply(camera->port, cmd, &reply);
536 if (reply[0] == '5') {
537 gp_context_error (context, _("Could not create directory."));
542 if (reply) free(reply);
547 camera_summary (Camera *camera, CameraText *summary, GPContext *context)
549 char *t = summary->text;
554 ret = g3_ftp_command_and_reply (camera->port, "-VER", &buf);
556 sprintf(t+strlen(t), _("Version: %s\n"), buf+4); /* skip "200 " */
557 ret = g3_ftp_command_and_reply(camera->port, "-RTST", &buf); /* RTC test */
560 if (sscanf(buf, "200 RTC status=%d", &rtcstat))
561 sprintf(t+strlen(t), _("RTC Status: %d\n"), rtcstat);
563 ret = g3_ftp_command_and_reply(camera->port, "-TIME", &buf);
565 char day[20], time[20];
566 if (sscanf(buf, "200 %s %s for -TIME", day, time))
567 sprintf(t+strlen(t), _("Camera time: %s %s\n"), day, time);
569 ret = g3_ftp_command_and_reply(camera->port, "-GCID", &buf);
572 if (sscanf(buf, "200 CameraID=%s for -GCID", camid))
573 sprintf(t+strlen(t), _("Camera ID: %s\n"), camid);
575 ret = g3_ftp_command_and_reply(camera->port, "-GSID", &buf);
578 if (strstr(buf, "200 SD ID= for -GSID")) {
579 sprintf(t+strlen(t), _("No SD Card inserted.\n"));
581 if (sscanf(buf, "200 SD ID=%s for -GSID", cardid)) {
582 sprintf(t+strlen(t), _("SD Card ID: %s\n"), cardid);
586 ret = g3_ftp_command_and_reply(camera->port, "-GTPN", &buf);
589 if (sscanf (buf, "200 TotalPhotoNo=%d for -GTPN", &total))
590 sprintf(t+strlen(t), _("Photos on camera: %d\n"), total);
592 ret = g3_ftp_command_and_reply(camera->port, "-DCAP /EXT0", &buf);
595 if (sscanf (buf, "200 /EXT0 capacity %d byte,free %d byte.", &space, &sfree)) {
596 sprintf(t+strlen(t), _("SD memory: %d MB total, %d MB free.\n"), space/1024/1024, sfree/1024/1024);
599 ret = g3_ftp_command_and_reply(camera->port, "-DCAP /IROM", &buf);
602 if (sscanf (buf, "200 /IROM capacity %d byte,free %d byte.", &space, &sfree)) {
603 sprintf(t+strlen(t), _("Internal memory: %d MB total, %d MB free.\n"), space/1024/1024, sfree/1024/1024);
611 camera_about (Camera *camera, CameraText *about, GPContext *context)
613 strcpy (about->text, _("Ricoh Caplio G3.\n"
614 "Marcus Meissner <marcus@jet.franken.de>\n"
615 "Reverse engineered using USB Snoopy, looking\n"
616 "at the firmware update image and wild guessing.\n"
623 get_info_func (CameraFilesystem *fs, const char *folder, const char *filename,
624 CameraFileInfo *info, void *data, GPContext *context)
626 Camera *camera = data;
627 int ret, bytes, width, height, k;
629 char *cmd = NULL, *reply = NULL;
631 info->file.fields = GP_FILE_INFO_TYPE | GP_FILE_INFO_NAME |
632 GP_FILE_INFO_SIZE | GP_FILE_INFO_TYPE;
633 strcpy(info->file.type,GP_MIME_UNKNOWN);
634 strcpy(info->file.name, filename);
636 if (!strcmp(filename+9,"JPG") || !strcmp(filename+9,"jpg"))
637 strcpy(info->file.type,GP_MIME_JPEG);
639 if (!strcmp(filename+9,"AVI") || !strcmp(filename+9,"avi"))
640 strcpy(info->file.type,GP_MIME_AVI);
642 if (!strcmp(filename+9,"WAV") || !strcmp(filename+9,"wav"))
643 strcpy(info->file.type,GP_MIME_WAV);
645 if (!strcmp(filename+9,"MTA") || !strcmp(filename+9,"mta"))
646 strcpy(info->file.type,"text/plain");
648 cmd = malloc(strlen("-FDAT ")+strlen(folder)+1+strlen(filename)+1);
649 sprintf(cmd, "-FDAT %s/%s", folder,filename);
650 ret = g3_ftp_command_and_reply(camera->port, cmd, &reply);
651 if (ret < GP_OK) goto out;
652 if (sscanf(reply, "200 date=%d:%d:%d %d:%d:%d",
660 xtm.tm_mon--; /* range 0 - 11 */
661 xtm.tm_year -= 1900; /* number of years since 1900 */
662 info->file.mtime = mktime(&xtm);
663 info->file.fields |= GP_FILE_INFO_MTIME;
666 /* -INFO command only sometimes work on non jpeg/avi files */
667 if ( !strcmp(info->file.type,GP_MIME_JPEG) ||
668 !strcmp(info->file.type,GP_MIME_AVI)
670 sprintf(cmd, "-INFO %s/%s", folder,filename);
671 ret = g3_ftp_command_and_reply(camera->port, cmd, &reply);
672 if (ret < GP_OK) goto out;
674 /* 200 1330313 byte W=2048 H=1536 K=0 for -INFO */
675 if (sscanf(reply, "200 %d byte W=%d H=%d K=%d for -INFO", &bytes, &width, &height , &k)) {
676 if (width != 0 && height != 0) {
677 info->file.fields |= GP_FILE_INFO_WIDTH | GP_FILE_INFO_HEIGHT;
678 info->file.height = height;
679 info->file.width = width;
681 info->file.fields |= GP_FILE_INFO_SIZE;
682 info->file.size = bytes;
684 gp_log(GP_LOG_ERROR, "g3", "k is %d for %s/%s\n", k, folder,filename);
688 if (reply) free(reply);
697 folder_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,
698 void *data, GPContext *context)
700 Camera *camera = data;
701 char *buf = NULL, *reply = NULL;
703 int ret = GP_OK, channel, len, rlen;
705 if (!strcmp("/",folder)) {
706 /* Lets hope they dont invent other names. */
708 /* We check the folder we get, since we should
709 * not add EXT0 without SD card.
711 ret = g3_ftp_command_and_reply(camera->port, "-NLST /", &buf);
712 if (ret < GP_OK) goto out;
714 /* seen with R3: 450 Open Error... likely OK. */
721 ret = g3_channel_read(camera->port, &channel, &buf, &len); /* data. */
722 if (ret < GP_OK) goto out;
723 ret = g3_channel_read(camera->port, &channel, &reply, &rlen); /* next reply */
724 if (ret < GP_OK) goto out;
725 gp_log(GP_LOG_DEBUG, "g3" , "reply %s", reply);
727 if (!strcmp("/EXT0",buf))
728 gp_list_append (list, "EXT0", NULL);
730 /* always add internal memory */
731 gp_list_append (list, "IROM", NULL);
735 cmd = malloc(6 + strlen(folder) + 1);
736 strcpy(cmd, "-NLST ");
739 ret = g3_ftp_command_and_reply(camera->port, cmd, &buf);
740 free(cmd);cmd = NULL;
741 if (ret < GP_OK) goto out;
742 if (buf[0] == '1') { /* 1xx means another reply follows */
745 ret = g3_channel_read(camera->port, &channel, &buf, &len); /* data. */
746 if (ret < GP_OK) goto out;
747 g3_channel_read(camera->port, &channel, &reply, &rlen); /* next reply */
748 if (ret < GP_OK) goto out;
749 gp_log(GP_LOG_DEBUG, "g3" , "reply %s", reply);
751 for (n=0;n<len/32;n++) {
752 if (buf[n*32+11] == 0x10) {
753 if (buf[n*32] == '.') /* skip . and .. entries */
755 ret = gp_list_append (list, buf+n*32, NULL);
756 if (ret != GP_OK) goto out;
767 if (reply) free(reply);
771 /* for DOS FAT -> UNIX time conversion */
772 static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 };
775 file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,
776 void *data, GPContext *context)
778 Camera *camera = data;
779 char *buf = NULL, *reply = NULL, *cmd;
783 cmd = malloc(6 + strlen(folder) + 1);
784 strcpy(cmd, "-NLST ");
786 ret = g3_ftp_command_and_reply(camera->port, cmd, (char**)&buf);
787 free(cmd); cmd = NULL;
788 if (ret < GP_OK) goto out;
789 if (buf[0] == '1') { /* 1xx means another reply follows */
790 int n = 0, channel, len, rlen;
791 ret = g3_channel_read(camera->port, &channel, &buf, &len); /* data. */
792 if (ret < GP_OK) goto out;
793 g3_channel_read(camera->port, &channel, &reply, &rlen); /* next reply */
794 if (ret < GP_OK) goto out;
795 gp_log(GP_LOG_DEBUG, "g3" , "reply %s", reply);
797 ubuf = (unsigned char*)buf;
798 for (n=0;n < len/32;n++) {
799 if (buf[n*32+11] == 0x20) {
802 int date, time, month, year;
804 strncpy (xfn, buf+n*32, 8);
806 strncpy (xfn+9, buf+n*32+8, 3);
809 ret = gp_filesystem_append (fs, folder, xfn, context);
810 if (ret < GP_OK) goto out;
812 /* we also get parts of fs info for free, so just set it */
817 info.file.size =(ubuf[n*32+28]<<24)|
821 strcpy(info.file.name,xfn);
822 if (!strcmp(xfn+9,"JPG") || !strcmp(xfn+9,"jpg")) {
823 strcpy(info.file.type,GP_MIME_JPEG);
824 info.file.fields |= GP_FILE_INFO_TYPE;
827 if (!strcmp(xfn+9,"AVI") || !strcmp(xfn+9,"avi")) {
828 strcpy(info.file.type,GP_MIME_AVI);
829 info.file.fields |= GP_FILE_INFO_TYPE;
832 if (!strcmp(xfn+9,"WAV") || !strcmp(xfn+9,"wav")) {
833 strcpy(info.file.type,GP_MIME_WAV);
834 info.file.fields |= GP_FILE_INFO_TYPE;
837 if (!strcmp(xfn+9,"MTA") || !strcmp(xfn+9,"mta")) {
838 strcpy(info.file.type,"text/plain");
839 info.file.fields |= GP_FILE_INFO_TYPE;
841 info.preview.fields = 0;
842 date = (ubuf[n*32+16]) | (ubuf[n*32+17]<<8);
843 time = (ubuf[n*32+14]) | (ubuf[n*32+15]<<8);
845 /* from kernel fs/fat/, time_dos2unix. */
846 month = ((date >> 5) - 1) & 15;
849 (time & 31)*2+60*((time >> 5) & 63)+
850 (time >> 11)*3600+86400*((date & 31)-1+
851 day_n[month]+(year/4)+year*365-
852 ((year & 3) == 0 && month < 2 ? 1 : 0)+
855 ret = gp_filesystem_set_info_noop(fs, folder, info, context);
860 if (buf[0] == '4') /* 450 Open Error ... like dir not there */
867 if (reply) free(reply);
871 static CameraFilesystemFuncs fsfuncs = {
872 .file_list_func = file_list_func,
873 .get_file_func = get_file_func,
874 .del_file_func = delete_file_func,
875 .get_info_func = get_info_func,
876 .folder_list_func = folder_list_func,
877 .make_dir_func = mkdir_func,
878 .remove_dir_func = rmdir_func,
882 camera_init (Camera *camera, GPContext *context)
885 GPPortSettings settings;
887 /* First, set up all the needed function pointers */
888 camera->functions->summary = camera_summary;
889 camera->functions->about = camera_about;
891 /* Now, tell the filesystem where to get lists, files and info */
892 gp_filesystem_set_funcs (camera->fs, &fsfuncs, camera);
894 gp_port_get_settings(camera->port, &settings);
895 settings.usb.inep = 0x81;
896 settings.usb.outep = 0x02;
897 settings.usb.intep = 0x83;
898 gp_port_set_settings(camera->port, settings);
900 * The port is already provided with camera->port (and
901 * already open). You just have to use functions like
902 * gp_port_timeout_set, gp_port_settings_get, gp_port_settings_set.
906 * Once you have configured the port, you should check if a
907 * connection to the camera can be established.
912 g3_ftp_command_and_reply(camera->port, "-PWOF STDBY", &buf);