"Fossies" - the Fresh Open Source Software Archive

Member "libgphoto2-2.5.27/camlibs/sierra/library.c" (31 Jan 2021, 41649 Bytes) of package /linux/privat/libgphoto2-2.5.27.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "library.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.5.26_vs_2.5.27.

    1 /* library.c
    2  *
    3  * Copyright 2001 Lutz Mueller <lutz@users.sf.net>
    4  *
    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.
    9  *
   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.
   14  *
   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., 51 Franklin Street, Fifth Floor,
   18  * Boston, MA  02110-1301  USA
   19  */
   20 #define _DARWIN_C_SOURCE
   21 #include "config.h"
   22 #include "library.h"
   23 
   24 #include <stdio.h>
   25 #include <stdlib.h>
   26 #include <ctype.h>
   27 #include <string.h>
   28 #include <time.h>
   29 
   30 #include <gphoto2/gphoto2-port-log.h>
   31 
   32 #include "sierra.h"
   33 #include "sierra-usbwrap.h"
   34 
   35 #define GP_MODULE "sierra"
   36 
   37 #ifdef ENABLE_NLS
   38 #  include <libintl.h>
   39 #  undef _
   40 #  define _(String) dgettext (GETTEXT_PACKAGE, String)
   41 #  ifdef gettext_noop
   42 #    define N_(String) gettext_noop (String)
   43 #  else
   44 #    define N_(String) (String)
   45 #  endif
   46 #else
   47 #  define textdomain(String) (String)
   48 #  define gettext(String) (String)
   49 #  define dgettext(Domain,Message) (Message)
   50 #  define dcgettext(Domain,Message,Type) (Message)
   51 #  define bindtextdomain(Domain,Directory) (Domain)
   52 #  define _(String) (String)
   53 #  define N_(String) (String)
   54 #endif
   55 
   56 enum _SierraPacket {
   57     NUL             = 0x00,
   58     SIERRA_PACKET_DATA      = 0x02,
   59     SIERRA_PACKET_DATA_END      = 0x03,
   60     SIERRA_PACKET_ENQ       = 0x05,
   61     ACK             = 0x06,
   62     SIERRA_PACKET_INVALID       = 0x11,
   63     SIERRA_PACKET_NAK       = 0x15,
   64     SIERRA_PACKET_COMMAND       = 0x1b,
   65     SIERRA_PACKET_WRONG_SPEED   = 0x8c,
   66     SIERRA_PACKET_SESSION_ERROR = 0xfc,
   67     SIERRA_PACKET_SESSION_END   = 0xff
   68 };
   69 typedef enum _SierraPacket SierraPacket;
   70 
   71 /* Size of requested packet */
   72 #define SIERRA_PACKET_SIZE      32774
   73 
   74 /* Sub-types */
   75 #define SUBSIERRA_PACKET_COMMAND_FIRST   0x53
   76 #define SUBSIERRA_PACKET_COMMAND         0x43
   77 
   78 /* Maximum length of the data field within a packet */
   79 #define MAX_DATA_FIELD_LENGTH   2048
   80 
   81 #define RETRIES                 10
   82 
   83 #define     QUICKSLEEP  5
   84 
   85 int sierra_change_folder (Camera *camera, const char *folder, GPContext *context)
   86 {
   87     int st = 0, i;
   88     char target[128];
   89 
   90     GP_DEBUG ("*** sierra_change_folder");
   91     GP_DEBUG ("*** folder: %s", folder);
   92 
   93     /*
   94      * Do not issue the command if the camera doesn't support folders
   95      * or if the folder is the current working folder
   96      */
   97     if (!camera->pl->folders || !strcmp (camera->pl->folder, folder))
   98         return GP_OK;
   99 
  100     /* We will later need a path ending with '/'. */
  101     memset (target, 0, sizeof (target));
  102     if (folder[0])
  103         strncpy (target, folder, sizeof (target) - 1);
  104     if (target[strlen (target) - 1] != '/')
  105         strcat (target, "/");
  106 
  107     /* If the given path is absolute, we need to start in '/'. */
  108     if (target[0] == '/') {
  109         CHECK (sierra_set_string_register (camera, 84, "\\", 1,
  110                            context));
  111         i = 1;
  112     } else
  113         i = 0;
  114 
  115     st = i;
  116     for (; target[i]; i++) {
  117         if (target[i] == '/') {
  118             target[i] = '\0';
  119             if (st == i - 1)
  120                 break;
  121             CHECK (sierra_set_string_register (camera, 84,
  122                                target + st, strlen (target + st), context));
  123 
  124             st = i + 1;
  125             target[i] = '/';
  126         }
  127     }
  128     strcpy (camera->pl->folder, folder);
  129 
  130     return GP_OK;
  131 }
  132 
  133 int sierra_list_files (Camera *camera, const char *folder, CameraList *list, GPContext *context)
  134 {
  135     int count, i, r;
  136     unsigned int len = 0;
  137     char filename[1024];
  138 
  139     GP_DEBUG ("Listing files in folder '%s'", folder);
  140 
  141     /*
  142      * This is a non-fatal check if a memory card is present. Some
  143      * cameras don't understand this command and error out here.
  144      * Since some cameras do not like it at all, do not send it for those.
  145      */
  146     if (!(camera->pl->flags & SIERRA_NO_51)) {
  147         r = sierra_get_int_register (camera, 51, &i, NULL);
  148         if ((r >= 0) && (i == 1)) {
  149             gp_context_error (context, _("No memory card present"));
  150             return GP_ERROR_NOT_SUPPORTED;
  151         }
  152     }
  153 
  154     /* We need to change to the folder first */
  155     CHECK (sierra_change_folder (camera, folder, context));
  156 
  157     /* Then, we count the files */
  158     GP_DEBUG ("Counting files in '%s'...", folder);
  159     CHECK (sierra_get_int_register (camera, 10, &count, context));
  160     GP_DEBUG ("... done. Found %i file(s).", count);
  161 
  162     /* No files? Then, we are done. */
  163     if (!count)
  164         return GP_OK;
  165 
  166     /*
  167      * Get the filename of the first picture. Note that some cameras
  168      * that don't support filenames return 8 blanks instead of
  169      * reporting an error. If this is indeed the case, just fill
  170      * the list with dummy entries and return.
  171      */
  172     GP_DEBUG ("Getting filename of first file");
  173     r = sierra_get_string_register (camera, 79, 1, NULL,
  174                     (unsigned char *)filename,
  175                     &len, context);
  176     if ((r < 0) || (len <= 0) || !strcmp (filename, "        ")) {
  177         CHECK (gp_list_populate (list, "P101%04i.JPG", count));
  178         return GP_OK;
  179     }
  180 
  181     /*
  182      * The camera supports filenames. Append the first one to the list
  183      * and get the remaining ones.
  184      */
  185     CHECK (gp_list_append (list, filename, NULL));
  186     for (i = 1; i < count; i++) {
  187         GP_DEBUG ("Getting filename of file %i...", i + 1);
  188         CHECK (sierra_get_string_register (camera, 79, i + 1, NULL,
  189                            (unsigned char *)filename,
  190                            &len, context));
  191         if ((len <= 0) || !strcmp (filename, "        "))
  192             snprintf (filename, sizeof (filename),
  193                   "P101%04i.JPG", i + 1);
  194         GP_DEBUG ("... done ('%s').", filename);
  195         CHECK (gp_list_append (list, filename, NULL));
  196     }
  197 
  198     return GP_OK;
  199 }
  200 
  201 int sierra_list_folders (Camera *camera, const char *folder, CameraList *list,
  202              GPContext *context)
  203 {
  204     int i, j, count;
  205     unsigned int bsize;
  206     char buf[1024];
  207 
  208     /* List the folders only if the camera supports them */
  209     if (!camera->pl->folders)
  210         return GP_OK;
  211 
  212     CHECK (sierra_change_folder (camera, folder, context));
  213     GP_DEBUG ("*** counting folders in '%s'...", folder);
  214     CHECK (sierra_get_int_register (camera, 83, &count, context));
  215     GP_DEBUG ("*** found %i folders", count);
  216     for (i = 0; i < count; i++) {
  217         CHECK (sierra_change_folder (camera, folder, context));
  218         CHECK (sierra_set_int_register (camera, 83, i + 1, context));
  219         bsize = 1024;
  220         GP_DEBUG ("*** getting name of folder %i", i + 1);
  221         CHECK (sierra_get_string_register (camera, 84, 0,
  222                            NULL, (unsigned char *)buf,
  223                            &bsize, context));
  224 
  225         /* Remove trailing spaces */
  226         for (j = strlen (buf) - 1; j >= 0 && buf[j] == ' '; j--)
  227             buf[j] = '\0';
  228         gp_list_append (list, buf, NULL);
  229     }
  230 
  231     return GP_OK;
  232 }
  233 
  234 /**
  235  * sierra_get_picture_folder:
  236  * @camera : camera data structure
  237  * @folder : folder name (to be freed by the caller)
  238  *
  239  * Return the name of the folder that stores pictures. It is assumed that
  240  * the camera conforms with the JEIDA standard. Thus, look for the picture
  241  * folder into the /DCIM directory.
  242  *
  243  * Returns: a gphoto2 error code
  244  */
  245 int sierra_get_picture_folder (Camera *camera, char **folder)
  246 {
  247     int i;
  248     CameraList *list;
  249     const char *name = NULL;
  250 
  251     GP_DEBUG ("* sierra_get_picture_folder");
  252 
  253     *folder = NULL;
  254 
  255     /* If the camera does not support folders, the picture
  256        folder is the root folder */
  257     if (!camera->pl->folders) {
  258         *folder = (char*) calloc(2, sizeof(char));
  259         strcpy(*folder, "/");
  260         return GP_OK;
  261     }
  262 
  263     CHECK (gp_list_new (&list));
  264 
  265     /* It is assumed that the camera conforms with the JEIDA standard .
  266        Thus, look for the picture folder into the /DCIM directory */
  267     CHECK (gp_filesystem_list_folders (camera->fs, "/DCIM", list, NULL) );
  268     for(i=0 ; i < gp_list_count (list) ; i++) {
  269         CHECK (gp_list_get_name (list, i, &name) );
  270         GP_DEBUG ("* check folder %s", name);
  271         if (isdigit(name[0]) && isdigit(name[1]) && isdigit(name[2]))
  272             break;
  273         name = NULL;
  274     }
  275 
  276     if (name) {
  277         *folder = (char*) calloc(strlen(name)+7, sizeof(char));
  278         strcpy(*folder, "/DCIM/");
  279         strcat(*folder, name);
  280         gp_list_free (list);
  281         return GP_OK;
  282     } else {
  283         gp_list_free (list);
  284         return GP_ERROR_DIRECTORY_NOT_FOUND;
  285     }
  286 }
  287 
  288 /**
  289  * sierra_check_battery_capacity:
  290  * @camera : camera data structure
  291  *
  292  * Check if the battery capacity is high enough.
  293  *
  294  * Returns: a gphoto2 error code
  295  */
  296 int sierra_check_battery_capacity (Camera *camera, GPContext *context)
  297 {
  298     int ret, capacity;
  299 
  300     GP_DEBUG ("* sierra_check_battery_capacity");
  301 
  302     if ((ret = sierra_get_int_register(camera, 16, &capacity, context)) != GP_OK) {
  303         gp_context_error (context,
  304                      _("Cannot retrieve the battery capacity"));
  305         return ret;
  306     }
  307     if (!capacity) /* 0% is unlikely */
  308         return GP_OK;
  309 
  310     if (capacity < 5) {
  311         gp_context_error (context,
  312                      _("The battery level of the camera is too low (%d%%). "
  313                        "The operation is aborted."), capacity);
  314         return GP_ERROR;
  315     }
  316 
  317     return GP_OK;
  318 }
  319 
  320 /**
  321  * sierra_get_memory_left:
  322  * @camera : camera data structure
  323  * @memory : memory left
  324  *
  325  * Provide the available memory left
  326  *
  327  * Returns: a gphoto2 error code
  328  */
  329 int
  330 sierra_get_memory_left (Camera *camera, int *memory, GPContext *context)
  331 {
  332     int ret;
  333 
  334     ret = sierra_get_int_register (camera, 28, memory, context);
  335     if (ret < 0) {
  336         gp_context_error (context, _("Cannot retrieve the available "
  337                          "memory left"));
  338         return ret;
  339     }
  340 
  341     return GP_OK;
  342 }
  343 
  344 static int
  345 sierra_check_connection (Camera *camera, GPContext *context)
  346 {
  347     int r = 0, ret, timeout;
  348     unsigned char c;
  349 
  350     /* Only serial cameras close the connection after some timeout. */
  351     if (camera->port->type != GP_PORT_SERIAL)
  352         return GP_OK;
  353 
  354     GP_DEBUG ("Checking if connection is still open");
  355     while (1) {
  356 
  357         /*
  358          * Do like the Windows driver - check for 20ms if something
  359          * has been sent by the camera.
  360          */
  361         CHECK (gp_port_get_timeout (camera->port, &timeout));
  362         CHECK (gp_port_set_timeout (camera->port, 20));
  363         ret = gp_port_read (camera->port, (char *)&c, 1);
  364         CHECK (gp_port_set_timeout (camera->port, timeout));
  365         switch (ret) {
  366         case GP_ERROR_TIMEOUT:
  367         case GP_ERROR_IO_READ:
  368 
  369             /*
  370              * If we got GP_ERROR_TIMEOUT or GP_ERROR_IO_READ,
  371              * everything's just fine.
  372              */
  373             return GP_OK;
  374 
  375         default:
  376 
  377             /*
  378              * If any error (except timeout) has occurred,
  379              * report it.
  380              */
  381             CHECK (ret);
  382         }
  383 
  384         /*
  385          * We have received something. This is not good. Check if
  386          * the camera has closed the connection and told us about
  387          * that by sending SIERRA_PACKET_SESSION_END.
  388          */
  389         if (c == SIERRA_PACKET_SESSION_END) {
  390             if (++r > 2) {
  391                 gp_context_error (context, _("Camera refused "
  392                     "3 times to keep a connection open."));
  393                 return GP_ERROR;
  394             }
  395             CHECK (sierra_init (camera, context));
  396             CHECK (sierra_set_speed (camera, SIERRA_SPEED_19200,
  397                          context));
  398             continue;
  399         }
  400 
  401         /*
  402          * The camera sends us unexpected data. Dump it and assume
  403          * that everything's just fine.
  404          */
  405         while (gp_port_read (camera->port, (char *)&c, 1) >= 0);
  406         return GP_OK;
  407     }
  408 }
  409 
  410 static int
  411 sierra_write_packet (Camera *camera, char *packet, GPContext *context)
  412 {
  413     int x, checksum=0, length;
  414 
  415     CHECK (sierra_check_connection (camera, context));
  416 
  417     /*
  418      * We need to check if this is the first packet. Note that USB
  419      * cameras don't care.
  420      */
  421     switch (packet[0]) {
  422     case SIERRA_PACKET_COMMAND:
  423         switch (camera->port->type) {
  424         case GP_PORT_SERIAL:
  425             packet[1] = (camera->pl->first_packet ?
  426                     SUBSIERRA_PACKET_COMMAND_FIRST :
  427                     SUBSIERRA_PACKET_COMMAND);
  428             camera->pl->first_packet = 0;
  429             break;
  430         default:
  431             packet[1] = SUBSIERRA_PACKET_COMMAND;
  432             break;
  433         }
  434         break;
  435     default:
  436         break;
  437     }
  438 
  439     /* Determining packet length */
  440     if ((packet[0] == SIERRA_PACKET_COMMAND) ||
  441         (packet[0] == SIERRA_PACKET_DATA) ||
  442         (packet[0] == SIERRA_PACKET_DATA_END)) {
  443         length = ((unsigned char)packet[2]) +
  444             ((unsigned char)packet[3]  * 256);
  445         length += 6;
  446     } else {
  447         length = 1;
  448     }
  449 
  450     /* Generate the checksum */
  451     if (length > 1) {
  452         for (x = 4; x < length - 2; x++)
  453             checksum += (unsigned char)packet[x];
  454         packet[length-2] = checksum & 0xff;
  455         packet[length-1] = (checksum >> 8) & 0xff;
  456     }
  457 
  458     if (camera->pl->flags & SIERRA_WRAP_USB_MASK) {
  459         CHECK (usb_wrap_write_packet (camera->port,
  460             (camera->pl->flags & SIERRA_WRAP_USB_MASK),
  461             packet, length));
  462     } else {
  463         CHECK (gp_port_write (camera->port, packet, length));
  464     }
  465 
  466     return GP_OK;
  467 }
  468 
  469 static int
  470 sierra_clear_usb_halt(Camera *camera)
  471 {
  472 
  473     if ( (camera->port->type == GP_PORT_USB) &&
  474          !(camera->pl->flags & SIERRA_WRAP_USB_MASK) &&
  475          !(camera->pl->flags & SIERRA_NO_USB_CLEAR) )
  476         gp_port_usb_clear_halt(camera->port, GP_PORT_USB_ENDPOINT_IN);
  477         return (GP_OK);
  478 }
  479 
  480 static int
  481 sierra_write_nak (Camera *camera, GPContext *context)
  482 {
  483         char buf[4096];
  484         int ret;
  485 
  486         GP_DEBUG ("* sierra_write_nack");
  487 
  488         buf[0] = SIERRA_PACKET_NAK;
  489         ret = sierra_write_packet (camera, buf, context);
  490     sierra_clear_usb_halt(camera);
  491         return (ret);
  492 }
  493 
  494 /**
  495  * sierra_read_packet:
  496  * @camera : camera data structure
  497  * @packet : to return the read packet
  498  *
  499  * Read a data packet from the camera.
  500  *
  501  * Method:
  502  *   Two kinds of packet may be received from the camera :
  503  *     - either single byte length packet,
  504  *     - or several byte length packet.
  505  *
  506  *   Structure of the several byte length packet is the following :
  507  *   Offset Length    Meaning
  508  *          0     1       Packet type
  509  *          1     1       Packet subtype/sequence
  510  *          2     2       Length of data
  511  *          4   variable  Data
  512  *         -2     2       Checksum
  513  *
  514  *   The operation is successful when the packet is recognised
  515  *   and is completely retrieved without IO errors.
  516  *
  517  * Returns: error code
  518  *     - GP_OK if the operation is successful (see description),
  519  *     - GP_ERROR_UNKNOWN_PORT if no port was specified within
  520  *       the camera data structure,
  521  *     - GP_ERROR_CORRUPTED_DATA if the received data are invalid,
  522  *     - GP_ERROR_IO_* on other IO error.
  523  */
  524 static int
  525 sierra_read_packet (Camera *camera, unsigned char *packet, GPContext *context)
  526 {
  527     int result;
  528     unsigned int i, c, r = 0, length, blocksize = 1, br;
  529 
  530     GP_DEBUG ("Reading packet...");
  531 
  532     switch (camera->port->type) {
  533     case GP_PORT_USB_SCSI:
  534     case GP_PORT_USB:
  535         blocksize = SIERRA_PACKET_SIZE;
  536         break;
  537     case GP_PORT_SERIAL:
  538         blocksize = 1;
  539         break;
  540     default:
  541         return (GP_ERROR_UNKNOWN_PORT);
  542     }
  543 
  544     /* Try several times before leaving on error... */
  545     while (1) {
  546 
  547         /* Clear the USB bus
  548            (what about the SERIAL bus : do we need to flush it?) */
  549         sierra_clear_usb_halt(camera);
  550 
  551         /*
  552          * Read data through the bus. If an error occurred,
  553          * try again.
  554          */
  555         if ((camera->port->type & (GP_PORT_USB_SCSI|GP_PORT_USB)) && (camera->pl->flags & SIERRA_WRAP_USB_MASK))
  556             result = usb_wrap_read_packet (camera->port,
  557                     (camera->pl->flags & SIERRA_WRAP_USB_MASK),
  558                     (char *)packet, blocksize);
  559         else
  560             result = gp_port_read (camera->port, (char *)packet, blocksize);
  561         if (result < 0) {
  562             GP_DEBUG ("Read failed (%i: '%s').", result,
  563                   gp_result_as_string (result));
  564             if (++r > 2) {
  565                 sierra_clear_usb_halt(camera);
  566                 GP_DEBUG ("Giving up...");
  567                 return (result);
  568             }
  569             GP_DEBUG ("Retrying...");
  570             continue;
  571         }
  572         if (result == 0) {
  573             GP_DEBUG ("Read got 0 bytes..");
  574             if (++r > 2) {
  575                 sierra_clear_usb_halt(camera);
  576                 GP_DEBUG ("Giving up...");
  577                 return GP_ERROR_IO_READ;
  578             }
  579             GP_DEBUG ("Retrying...");
  580             continue;
  581         }
  582         br = result;
  583 
  584         /*
  585          * If the first read byte is not known,
  586          * report an error and exit the processing.
  587          */
  588         switch (packet[0]) {
  589         case NUL:
  590         case SIERRA_PACKET_ENQ:
  591         case ACK:
  592         case SIERRA_PACKET_INVALID:
  593         case SIERRA_PACKET_NAK:
  594         case SIERRA_PACKET_SESSION_ERROR:
  595         case SIERRA_PACKET_SESSION_END:
  596         case SIERRA_PACKET_WRONG_SPEED:
  597 
  598             /* Those are all single byte packets. */
  599             sierra_clear_usb_halt(camera);
  600             GP_DEBUG ("Packet type 0x%02x read. Returning GP_OK.", packet[0]);
  601             return GP_OK;
  602 
  603         case SIERRA_PACKET_DATA:
  604         case SIERRA_PACKET_DATA_END:
  605         case SIERRA_PACKET_COMMAND:
  606 
  607             /* Those are packets with more than one byte. */
  608             break;
  609 
  610         default:
  611 
  612             /*
  613              * This byte is not valid. Dump everything that
  614              * coming in.
  615              */
  616             gp_context_error (context, _("The first byte "
  617                 "received (0x%x) is not valid."), packet[0]);
  618             while (gp_port_read (camera->port, (char *)packet, 1) > 0)
  619                 ;
  620             sierra_clear_usb_halt(camera);
  621             return (GP_ERROR_CORRUPTED_DATA);
  622         }
  623 
  624         /*
  625          * We've got a packet containing several bytes.
  626          * The data packet size is not known yet if the communication
  627          * is performed through the serial bus : read it then.
  628          */
  629         if (br < 4) {
  630             result = gp_port_read (camera->port,
  631                            (char *)packet + br, 4 - br);
  632             if (result < 0) {
  633                 sierra_clear_usb_halt(camera);
  634                 GP_DEBUG ("Could not read length of "
  635                     "packet (%i: '%s'). Giving up...",
  636                     result, gp_result_as_string (result));
  637                 return (result);
  638             }
  639             br += result;
  640         }
  641 
  642         /*
  643          * Determine the packet length: 2 for packet type and
  644          * subtype or sequence number, 2 for length, the actual
  645          * data, and 2 for the checksum.
  646          */
  647         length = packet[2] + (packet[3] * 256) + 6;
  648         if (length > SIERRA_PACKET_SIZE) {
  649             GP_DEBUG ("Packet too long (%d)!", length);
  650             return GP_ERROR_IO;
  651         }
  652 
  653         /*
  654          * Read until the end of the packet is reached
  655          * or an error occurred.
  656          */
  657         while (br < length) {
  658             result = gp_port_read (camera->port, (char *)packet + br,
  659                            length - br);
  660             if (result == GP_ERROR_TIMEOUT) {
  661 
  662                 /* We will retry later on. */
  663                 GP_DEBUG ("Timeout!");
  664                 break;
  665 
  666             } else if (result < 0) {
  667                 GP_DEBUG ("Could not read remainder of "
  668                     "packet (%i: '%s'). Giving up...",
  669                     result, gp_result_as_string (result));
  670                 return (result);
  671             } else
  672                 br += result;
  673         }
  674 
  675         /*
  676          * If we have, at this point, received the full packet,
  677          * check the checksum. If the checksum is correct, we are
  678          * done.
  679          */
  680         if (br == length) {
  681             for (c = 0, i = 4; i < br - 2; i++)
  682                 c += packet[i];
  683             c &= 0xffff;
  684             if (c == ((unsigned int)packet[br - 2] + ((unsigned int)packet[br - 1] * 256)))
  685                 break;
  686 
  687             /*
  688              * At least the Nikon CoolPix 880 sets the checksum
  689              * always to 0xffff. In that case, we can't check it
  690              * and return successfully.
  691              */
  692             if ((packet[br - 2] == 0xff) &&
  693                 (packet[br - 1] == 0xff))
  694                 break;
  695             /*
  696              * The checksum for the Toshiba PDR-M6X cameras is
  697              * almost always set to 0x00 0x00.
  698              */
  699             if ((packet[br - 2] == 0x00) &&
  700                 (packet[br - 1] == 0x00))
  701                 break;
  702 
  703 
  704             GP_DEBUG ("Checksum wrong (calculated 0x%x, "
  705                 "found 0x%x)!", c,
  706                 packet[br - 2] + (packet[br - 1] * 256));
  707         }
  708 
  709         /*
  710          * We will retry if we couldn't receive the full packet
  711          * (GP_ERROR_TIMEOUT) or if the checksum is wrong.
  712          */
  713         r++;
  714         if (r + 1 >= RETRIES) {
  715             sierra_clear_usb_halt(camera);
  716             GP_DEBUG ("Giving up...");
  717             return ((br == length) ? GP_ERROR_CORRUPTED_DATA :
  718                          GP_ERROR_TIMEOUT);
  719         }
  720         GP_DEBUG ("Retrying...");
  721         sierra_write_nak (camera, context);
  722         usleep (10 * 1000);
  723     }
  724 
  725     sierra_clear_usb_halt(camera);
  726 
  727     return GP_OK;
  728 }
  729 
  730 static int
  731 sierra_read_packet_wait (Camera *camera, char *buf, GPContext *context)
  732 {
  733     int result, r = 0;
  734 
  735     while (1) {
  736         if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL)
  737             return (GP_ERROR_CANCEL);
  738 
  739         result = sierra_read_packet (camera, (unsigned char *)buf, context);
  740         if (result == GP_ERROR_TIMEOUT) {
  741             if (++r > 2) {
  742                 gp_context_error (context, _("Transmission "
  743                     "of packet timed out even after "
  744                     "%i retries. Please contact "
  745                     "%s."), r, MAIL_GPHOTO_DEVEL);
  746                 return GP_ERROR;
  747             }
  748             GP_DEBUG ("Retrying...");
  749             usleep (QUICKSLEEP * 1000);
  750             continue;
  751         }
  752 
  753         CHECK (result);
  754 
  755         GP_DEBUG ("Packet successfully read.");
  756         return GP_OK;
  757     }
  758 }
  759 
  760 static int
  761 sierra_transmit_ack (Camera *camera, char *packet, GPContext *context)
  762 {
  763     int r = 0, result;
  764     unsigned char buf[SIERRA_PACKET_SIZE];
  765 
  766     while (1) {
  767         if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL)
  768             return (GP_ERROR_CANCEL);
  769 
  770         /* Write packet and read the answer */
  771         CHECK (sierra_write_packet (camera, packet, context));
  772         buf[0] = 0;
  773         result = sierra_read_packet_wait (camera, (char *)buf, context);
  774         switch (result) {
  775         case GP_ERROR_CORRUPTED_DATA:
  776             if (++r > 2) {
  777                 gp_context_error (context, _("Could not "
  778                     "transmit packet even after several "
  779                     "retries."));
  780                 return (result);
  781             }
  782             continue;
  783         default:
  784             CHECK (result);
  785         }
  786 
  787         switch (buf[0]) {
  788         case SIERRA_PACKET_ENQ:
  789         case ACK:
  790             GP_DEBUG ("Transmission successful.");
  791             return GP_OK;
  792         case SIERRA_PACKET_INVALID:
  793             gp_context_error (context, _("Packet was rejected "
  794                 "by camera. Please contact "
  795                 "%s."), MAIL_GPHOTO_DEVEL);
  796             return GP_ERROR;
  797 
  798         case SIERRA_PACKET_SESSION_END:
  799         case SIERRA_PACKET_SESSION_ERROR:
  800         case SIERRA_PACKET_WRONG_SPEED:
  801             if (++r > 2) {
  802                 gp_context_error (context, _("Could not "
  803                     "transmit packet even after several "
  804                     "retries."));
  805                 return GP_ERROR;
  806             }
  807 
  808             /*
  809                          * The camera has ended this session and
  810                          * reverted the speed back to 19200. Reinitialize
  811              * the connection.
  812                          */
  813             CHECK (sierra_init (camera, context));
  814             CHECK (sierra_set_speed (camera, SIERRA_SPEED_19200,
  815                          context));
  816             continue;
  817 
  818         default:
  819             if (++r > 2) {
  820                 gp_context_error (context, _("Could not "
  821                     "transmit packet (error code %i). "
  822                     "Please contact "
  823                     "%s."), buf[0], MAIL_GPHOTO_DEVEL);
  824                 return GP_ERROR;
  825             }
  826             GP_DEBUG ("Did not receive ACK. Retrying...");
  827             continue;
  828         }
  829     }
  830 }
  831 
  832 static int
  833 sierra_build_packet (Camera *camera, char type, char subtype,
  834              int data_length, char *packet)
  835 {
  836     packet[0] = type;
  837     switch (type) {
  838     case SIERRA_PACKET_COMMAND:
  839 
  840         /* sierra_write_packet will check for the first packet */
  841         packet[1] = SUBSIERRA_PACKET_COMMAND;
  842 
  843         break;
  844     case SIERRA_PACKET_DATA:
  845     case SIERRA_PACKET_DATA_END:
  846         packet[1] = subtype;
  847         break;
  848     default:
  849         GP_DEBUG ("* unknown packet type!");
  850     }
  851 
  852     packet[2] = data_length &  0xff;
  853     packet[3] = (data_length >> 8) & 0xff;
  854 
  855     return GP_OK;
  856 }
  857 
  858 static int
  859 sierra_write_ack (Camera *camera, GPContext *context)
  860 {
  861     char buf[4096];
  862     int ret;
  863 
  864     GP_DEBUG ("Writing acknowledgement...");
  865 
  866     buf[0] = ACK;
  867     ret = sierra_write_packet (camera, buf, context);
  868     sierra_clear_usb_halt(camera);
  869     CHECK (ret);
  870 
  871     GP_DEBUG ("Successfully wrote acknowledgement.");
  872     return GP_OK;
  873 }
  874 
  875 int
  876 sierra_init (Camera *camera, GPContext *context)
  877 {
  878     unsigned char buf[SIERRA_PACKET_SIZE], packet[4096];
  879     int ret, r = 0;
  880     GPPortSettings settings;
  881 
  882     GP_DEBUG ("Sending initialization sequence to the camera");
  883 
  884     /* Only serial connections need to be initialized. */
  885     if (camera->port->type != GP_PORT_SERIAL)
  886         return GP_OK;
  887 
  888     /*
  889      * It seems that the initialization sequence needs to be sent at
  890      * 19200.
  891      */
  892     CHECK (gp_port_get_settings (camera->port, &settings));
  893     if (settings.serial.speed != 19200) {
  894         settings.serial.speed = 19200;
  895         CHECK (gp_port_set_settings (camera->port, settings));
  896     }
  897     CHECK (gp_port_set_pin (camera->port, GP_PIN_DTR, GP_LEVEL_HIGH));
  898 
  899     packet[0] = NUL;
  900 
  901     while (1) {
  902 
  903         /* Send NUL */
  904         CHECK (sierra_write_packet (camera, (char *)packet, context));
  905 
  906         /* Read the response */
  907         ret = sierra_read_packet (camera, buf, context);
  908         if (ret == GP_ERROR_TIMEOUT) {
  909             if (++r > 2) {
  910                 gp_context_error (context,
  911                     _("Transmission timed out even after "
  912                       "2 retries. Giving up..."));
  913                 return (GP_ERROR_TIMEOUT);
  914             }
  915             GP_DEBUG ("Retrying...");
  916             continue;
  917         }
  918         CHECK (ret);
  919 
  920         switch (buf[0]) {
  921         case SIERRA_PACKET_NAK:
  922 
  923             /* Everything is fine. */
  924             return GP_OK;
  925 
  926         case SIERRA_PACKET_SESSION_END:
  927         default:
  928             if (++r > 3) {
  929                 gp_context_error (context,
  930                     _("Got unexpected result "
  931                       "0x%x. Please contact "
  932                       "%s."),
  933                     buf[0], MAIL_GPHOTO_DEVEL);
  934                 return GP_ERROR;
  935             }
  936             break;
  937         }
  938     }
  939 }
  940 
  941 static struct {
  942         SierraSpeed speed;
  943         int bit_rate;
  944 } SierraSpeeds[] = {
  945         {SIERRA_SPEED_9600  ,   9600},
  946         {SIERRA_SPEED_19200 ,  19200},
  947         {SIERRA_SPEED_38400 ,  38400},
  948         {SIERRA_SPEED_57600 ,  57600},
  949         {SIERRA_SPEED_115200, 115200},
  950         {0, 0}
  951 };
  952 
  953 int
  954 sierra_set_speed (Camera *camera, SierraSpeed speed, GPContext *context)
  955 {
  956     GPPortSettings settings;
  957     unsigned int i, bit_rate;
  958 
  959     /* Only serial connections have different speeds. */
  960     if (camera->port->type != GP_PORT_SERIAL)
  961         return GP_OK;
  962 
  963     /*
  964      * Check that the requested speed is valid. We don't want to bug
  965      * the user with our coding errors, therefore if the requested
  966      * speed is invalid, we use 19200.
  967      */
  968     for (i = 0; SierraSpeeds[i].bit_rate; i++)
  969         if (SierraSpeeds[i].speed == speed)
  970             break;
  971     if (SierraSpeeds[i].bit_rate)
  972         bit_rate = SierraSpeeds[i].bit_rate;
  973     else {
  974         GP_DEBUG ("Invalid speed %i. Using %i (19200, default).",
  975               speed, SIERRA_SPEED_19200);
  976         speed = SIERRA_SPEED_19200;
  977         bit_rate = 19200;
  978     }
  979 
  980     /*
  981      * Check if we need to change the speed or if we are currently
  982      * using the requested speed. The reason why we are doing that is
  983      * that (at least some) cameras reject the request for a speed if
  984      * they are currently operating at that speed.
  985      */
  986     CHECK (gp_port_get_settings (camera->port, &settings));
  987     if ((unsigned int)settings.serial.speed == bit_rate)
  988         return GP_OK;
  989 
  990     /*
  991      * Tell the camera about the new speed. Note that a speed change
  992      * automatically starts a new session.
  993      */
  994     GP_DEBUG ("Setting speed to %i (%i bps)", speed, bit_rate);
  995     camera->pl->first_packet = 1;
  996     CHECK (sierra_set_int_register (camera, 17, speed, context));
  997 
  998     /* Now switch the port to the new speed. */
  999     CHECK (gp_port_get_settings (camera->port, &settings));
 1000     settings.serial.speed = bit_rate;
 1001     CHECK (gp_port_set_settings (camera->port, settings));
 1002     CHECK (gp_port_set_pin (camera->port, GP_PIN_DTR, GP_LEVEL_HIGH));
 1003 
 1004     usleep (10 * 1000);
 1005     return GP_OK;
 1006 }
 1007 
 1008 int sierra_sub_action (Camera *camera, SierraAction action, int sub_action,
 1009                GPContext *context)
 1010 {
 1011     char buf[SIERRA_PACKET_SIZE];
 1012 
 1013     CHECK (sierra_build_packet (camera, SIERRA_PACKET_COMMAND, 0, 3, buf));
 1014     buf[4] = 0x02;
 1015     buf[5] = action;
 1016     buf[6] = sub_action;
 1017 
 1018     GP_DEBUG ("sierra_sub_action: action %d, sub action %d", action,
 1019           sub_action);
 1020     CHECK (sierra_transmit_ack (camera, buf, context));
 1021     GP_DEBUG ("Waiting for acknowledgement...");
 1022     CHECK (sierra_read_packet_wait (camera, buf, context));
 1023 
 1024     switch (buf[0]) {
 1025     case ACK: /* reported on capture on Olympus 4040 */
 1026     case SIERRA_PACKET_ENQ:
 1027         return (GP_OK);
 1028     default:
 1029         gp_context_error (context, _("Received unexpected answer "
 1030         "(%i). Please contact %s."), buf[0], MAIL_GPHOTO_DEVEL);
 1031         return (GP_ERROR);
 1032     }
 1033 
 1034     return GP_OK;
 1035 }
 1036 
 1037 static int
 1038 sierra_action (Camera *camera, SierraAction action, GPContext *context)
 1039 {
 1040     return(sierra_sub_action (camera, action, 0, context));
 1041 }
 1042 
 1043 int
 1044 sierra_set_int_register (Camera *camera, int reg, int value,
 1045              GPContext *context)
 1046 {
 1047     char p[4096];
 1048 
 1049     GP_DEBUG ("sierra_set_int_register: register %i value %i", reg, value);
 1050 
 1051     CHECK (sierra_build_packet (camera, SIERRA_PACKET_COMMAND, 0,
 1052                     (value < 0) ? 2 : 6, p));
 1053 
 1054     /* Fill in the data */
 1055     p[4] = 0x00;
 1056     p[5] = reg;
 1057     if (value >= 0) {
 1058         p[6] = (value)     & 0xff;
 1059         p[7] = (value>>8)  & 0xff;
 1060         p[8] = (value>>16) & 0xff;
 1061         p[9] = (value>>24) & 0xff;
 1062     }
 1063 
 1064     /* Send packet */
 1065     CHECK (sierra_transmit_ack (camera, p, context));
 1066 
 1067     return GP_OK;
 1068 }
 1069 
 1070 int sierra_get_int_register (Camera *camera, int reg, int *value, GPContext *context)
 1071 {
 1072     int r = 0;
 1073     unsigned char p[4096], buf[SIERRA_PACKET_SIZE];
 1074 
 1075     GP_DEBUG ("sierra_get_int_register: register 0x%02x...", reg);
 1076 
 1077     /* Build and send the packet. */
 1078     CHECK (sierra_build_packet (camera, SIERRA_PACKET_COMMAND, 0, 2, (char *)p));
 1079     p[4] = 0x01;
 1080     p[5] = reg;
 1081     CHECK (sierra_write_packet (camera, (char *)p, context));
 1082 
 1083     while (1) {
 1084 
 1085         /* Read the response */
 1086         buf[0] = 0;
 1087         CHECK (sierra_read_packet_wait (camera, (char *)buf, context));
 1088         GP_DEBUG ("Successfully read packet. Interpreting result "
 1089               "(0x%02x)", buf[0]);
 1090         switch (buf[0]) {
 1091         case SIERRA_PACKET_INVALID:
 1092             gp_context_error (context, _("Could not get "
 1093                 "register %i. Please contact "
 1094                 "%s."), reg, MAIL_GPHOTO_DEVEL);
 1095             return GP_ERROR;
 1096         case SIERRA_PACKET_DATA_END:
 1097             r = ((unsigned char) buf[4]) +
 1098                 ((unsigned char) buf[5] * 256) +
 1099                 ((unsigned char) buf[6] * 65536) +
 1100                 ((unsigned char) buf[7] * 16777216);
 1101             *value = r;
 1102             GP_DEBUG ("Value of register 0x%02x: 0x%02x. ", reg, r);
 1103             CHECK (sierra_write_ack (camera, context));
 1104             GP_DEBUG ("Read value of register 0x%02x and wrote "
 1105                   "acknowledgement. Returning.", reg);
 1106             return GP_OK;
 1107 
 1108         case SIERRA_PACKET_SESSION_END:
 1109         case SIERRA_PACKET_SESSION_ERROR:
 1110         case SIERRA_PACKET_WRONG_SPEED:
 1111             if (++r > 2) {
 1112                 gp_context_error (context, _("Too many "
 1113                         "retries failed."));
 1114                 return GP_ERROR;
 1115             }
 1116 
 1117             /*
 1118              * The camera has ended this session and
 1119              * reverted the speed back to 19200. Reinitialize
 1120              * the connection and resend the packet. We use the
 1121              * default speed from now on.
 1122              */
 1123             CHECK (sierra_init (camera, context));
 1124             CHECK (sierra_set_speed (camera, SIERRA_SPEED_19200,
 1125                          context));
 1126             CHECK (sierra_write_packet (camera, (char *)p, context));
 1127 
 1128             break;
 1129 
 1130         default:
 1131             if (++r > 2) {
 1132                 gp_context_error (context, _("Too many "
 1133                     "retries failed."));
 1134                 return GP_ERROR;
 1135             }
 1136 
 1137             /* Tell the camera to send again. */
 1138             CHECK (sierra_write_nak (camera, context));
 1139             break;
 1140         }
 1141     }
 1142 
 1143     return GP_ERROR_IO;
 1144 }
 1145 
 1146 int
 1147 sierra_set_string_register (Camera *camera, int reg, const char *s,
 1148                 long int length, GPContext *context)
 1149 {
 1150 
 1151     char packet[4096];
 1152     char type;
 1153     long int x=0;
 1154     int seq=0, size=0;
 1155     int do_percent;
 1156     unsigned int id = 0;
 1157 
 1158     GP_DEBUG ("sierra_set_string_register: reg %i, value '%s'", reg, s);
 1159 
 1160     /* Make use of the progress bar when the packet is "large enough" */
 1161     if (length > MAX_DATA_FIELD_LENGTH) {
 1162         do_percent = 1;
 1163         /*
 1164          * This code can lead to recursive calls in gtkam - the
 1165          * main problem is when thumbnails are being downloaded,
 1166          * gtkam tries to download another thumbnail when
 1167          * gp_context_progress_update() is called. There are also
 1168          * other areas in gtkam that can recursively call into
 1169          * this function.
 1170          */
 1171         id = gp_context_progress_start (context, length,
 1172                         _("Sending data..."));
 1173     }
 1174     else
 1175         do_percent = 0;
 1176 
 1177     while (x < length) {
 1178         if (x == 0) {
 1179             type = SIERRA_PACKET_COMMAND;
 1180             size = (length + 2 - x) > MAX_DATA_FIELD_LENGTH
 1181                 ? MAX_DATA_FIELD_LENGTH : length + 2;
 1182         }  else {
 1183             size = (length - x) > MAX_DATA_FIELD_LENGTH
 1184                 ? MAX_DATA_FIELD_LENGTH : length-x;
 1185             if (x + size < length)
 1186                 type = SIERRA_PACKET_DATA;
 1187             else
 1188                 type = SIERRA_PACKET_DATA_END;
 1189         }
 1190         CHECK (sierra_build_packet (camera, type, seq, size, packet));
 1191 
 1192         if (type == SIERRA_PACKET_COMMAND) {
 1193             packet[4] = 0x03;
 1194             packet[5] = reg;
 1195             memcpy (&packet[6], &s[x], size-2);
 1196             x += size - 2;
 1197         } else  {
 1198             packet[1] = seq++;
 1199             memcpy (&packet[4], &s[x], size);
 1200             x += size;
 1201         }
 1202 
 1203         /* Transmit packet */
 1204         CHECK (sierra_transmit_ack (camera, packet, context));
 1205         if (do_percent)
 1206             gp_context_progress_update (context, id, x);
 1207     }
 1208     if (do_percent)
 1209         gp_context_progress_stop (context, id);
 1210 
 1211     return GP_OK;
 1212 }
 1213 
 1214 int sierra_get_string_register (Camera *camera, int reg, int fnumber,
 1215                                 CameraFile *file, unsigned char *b,
 1216                 unsigned int *b_len, GPContext *context)
 1217 {
 1218     unsigned char p[34816];
 1219     unsigned int packlength, total = (b_len) ? *b_len : 0;
 1220     int retries, r;
 1221     unsigned int min_progress_bytes;
 1222     static int in_function = 0;
 1223     unsigned int id = 0;
 1224 
 1225     GP_DEBUG ("sierra_get_string_register:  reg %i, file number %i, "
 1226           " total %d, flags 0x%x", reg, fnumber, total,
 1227           camera->pl->flags);
 1228 
 1229     if (in_function != 0) {
 1230         gp_context_error (context, _("recursive calls are not"
 1231             " supported by the sierra driver! Please contact"
 1232             " %s."), MAIL_GPHOTO_DEVEL);
 1233         return GP_ERROR;
 1234     }
 1235     in_function = 1;
 1236 
 1237     /* Set the current picture number */
 1238     if (fnumber >= 0)
 1239         CHECK (sierra_set_int_register (camera, 4, fnumber, context));
 1240 
 1241     /* Build and send the request */
 1242     CHECK (sierra_build_packet (camera, SIERRA_PACKET_COMMAND, 0, 2, (char *)p));
 1243     /*
 1244      * If the extended protocol is enabled, use code 0x06 so we can send
 1245      * and receive 32k size packages, otherwise code 0x04 is used and
 1246      * we have 2k size packages.
 1247      */
 1248     if (camera->pl->flags & SIERRA_EXT_PROTO) {
 1249         p[4] = 0x06;
 1250         min_progress_bytes = 32 * 1024;
 1251     } else {
 1252         p[4] = 0x04;
 1253         min_progress_bytes = 2 * 1024;
 1254     }
 1255     p[5] = reg;
 1256     CHECK (sierra_write_packet (camera, (char *)p, context));
 1257 
 1258     if (file && total > min_progress_bytes) {
 1259         id = gp_context_progress_start (context, total, _("Downloading data..."));
 1260     }
 1261 
 1262     /* Read all the data packets */
 1263     *b_len = 0;
 1264     retries = 0;
 1265     do {
 1266 
 1267         /* Read one packet and retry on timeout. */
 1268         r = sierra_read_packet (camera, p, context);
 1269         if (r == GP_ERROR_TIMEOUT) {
 1270             if (++retries > RETRIES) {
 1271                 in_function = 0;
 1272                 return (r);
 1273             }
 1274             GP_DEBUG ("Timeout! Retrying (%i of %i)...",
 1275                   retries, RETRIES);
 1276             CHECK (sierra_write_nak (camera, context));
 1277             continue;
 1278         }
 1279         CHECK (r);
 1280 
 1281         GP_DEBUG ("sierra_get_string_register p[0] is %d", p[0]);
 1282         switch (p[0]) {
 1283         case SIERRA_PACKET_INVALID:
 1284             gp_context_error (context, _("Could not get "
 1285                 "string register %i. Please contact "
 1286                 "%s."), reg, MAIL_GPHOTO_DEVEL);
 1287             in_function = 0;
 1288             return GP_ERROR;
 1289         default:
 1290             break;
 1291         }
 1292         CHECK (sierra_write_ack (camera, context));
 1293 
 1294         packlength = p[2] | (p[3] << 8);
 1295         GP_DEBUG ("Packet length: %d", packlength);
 1296 
 1297         if (b)
 1298             memcpy (&b[*b_len], &p[4], packlength);
 1299         *b_len += packlength;
 1300 
 1301         if (file) {
 1302             CHECK (gp_file_append (file, (char *)&p[4], packlength));
 1303             if (total > min_progress_bytes)
 1304             gp_context_progress_update (context, id, *b_len);
 1305         }
 1306 
 1307     } while (p[0] != SIERRA_PACKET_DATA_END);
 1308     if (file && total > min_progress_bytes)
 1309         gp_context_progress_stop (context, id);
 1310 
 1311     GP_DEBUG ("sierra_get_string_register: completed OK, *b_len %d",
 1312           *b_len);
 1313     in_function = 0;
 1314     return GP_OK;
 1315 }
 1316 
 1317 int
 1318 sierra_delete_all (Camera *camera, GPContext *context)
 1319 {
 1320     CHECK (sierra_action (camera, SIERRA_ACTION_DELETE_ALL, context));
 1321 
 1322     return GP_OK;
 1323 }
 1324 
 1325 int
 1326 sierra_delete (Camera *camera, int picture_number, GPContext *context)
 1327 {
 1328     /* Tell the camera which picture to delete and execute command. */
 1329     CHECK (sierra_set_int_register (camera, 4, picture_number, context));
 1330     CHECK (sierra_action (camera, SIERRA_ACTION_DELETE, context));
 1331 
 1332     return GP_OK;
 1333 }
 1334 
 1335 int
 1336 sierra_end_session (Camera *camera, GPContext *context)
 1337 {
 1338     CHECK (sierra_action (camera, SIERRA_ACTION_END, context));
 1339 
 1340     return GP_OK;
 1341 }
 1342 
 1343 int
 1344 sierra_capture_preview (Camera *camera, CameraFile *file, GPContext *context)
 1345 {
 1346     unsigned int size;
 1347 
 1348     /* Send to the camera the capture request and wait
 1349        for the completion */
 1350     CHECK (sierra_action (camera, SIERRA_ACTION_PREVIEW, context));
 1351 
 1352     /* Retrieve the preview and set the MIME type */
 1353     CHECK (sierra_get_int_register (camera, 12, (int *)&size, context));
 1354     CHECK (sierra_get_string_register (camera, 14, 0, file, NULL, &size,
 1355                        context));
 1356     CHECK (gp_file_set_mime_type (file, GP_MIME_JPEG));
 1357 
 1358     return GP_OK;
 1359 }
 1360 
 1361 int
 1362 sierra_capture (Camera *camera, CameraCaptureType type,
 1363         CameraFilePath *filepath, GPContext *context)
 1364 {
 1365     int n, r;
 1366     unsigned int len = 0;
 1367     char filename[128];
 1368     char *folder;
 1369     int timeout;
 1370 
 1371     GP_DEBUG ("* sierra_capture");
 1372 
 1373     /* We can only capture images */
 1374     if (type != GP_CAPTURE_IMAGE)
 1375         return GP_ERROR_NOT_SUPPORTED;
 1376 
 1377     /*
 1378      * This is a non-fatal check if a memory card is present. Some
 1379      * cameras don't understand this command and error out here.
 1380      * Since some cameras do not like it at all, do not send it for those.
 1381      */
 1382     if (!(camera->pl->flags & SIERRA_NO_51)) {
 1383         r = sierra_get_int_register (camera, 51, &n, context);
 1384         if ((r >= 0) && (n == 1)) {
 1385             gp_context_error (context, _("No memory card present"));
 1386             return GP_ERROR_NOT_SUPPORTED;
 1387         }
 1388     }
 1389 
 1390     /*
 1391      * Raise the timeout before the capture, since it can take longer,
 1392      * the shutter speed alone could push us over 10 seconds.
 1393      */
 1394     CHECK (gp_port_get_timeout (camera->port, &timeout));
 1395     CHECK (gp_port_set_timeout (camera->port, 20000)); /* 20 seconds */
 1396     /* Send to the camera the capture request and wait
 1397        for the completion */
 1398     CHECK (sierra_action (camera, SIERRA_ACTION_CAPTURE, context));
 1399     CHECK (gp_port_set_timeout (camera->port, timeout));
 1400 
 1401     if (filepath != NULL) {
 1402         /*
 1403          * After the picture is taken, register 4 is set to the
 1404          * current picture.
 1405          */
 1406         GP_DEBUG ("Getting picture number.");
 1407         r = sierra_get_int_register (camera, 4, &n, context);
 1408         if (r == GP_OK) {
 1409             GP_DEBUG ("Getting filename of file %i.", n);
 1410         }
 1411         /*
 1412          * We need to tell the frontend where the new image can be
 1413          * found.  Unfortunately, we can only figure out the
 1414          * filename. Therefore, reset the CameraFilesystem and let
 1415          * it search for the filename.
 1416          *
 1417          * If you know how to figure out where the image gets
 1418          * saved, please submit a patch.
 1419          *
 1420          * Not that some cameras that don't support filenames will
 1421          * return 8 blanks instead of reporting an error.
 1422          *
 1423          * Some newer cameras (Nikon*) do not return register 4, so
 1424          * ignore errors from that.
 1425          */
 1426         CHECK (sierra_get_string_register (camera, 79, 0, NULL,
 1427                            (unsigned char *)filename,
 1428                            &len, context));
 1429         if ((len <= 0) || !strcmp (filename, "        "))
 1430             snprintf (filename, sizeof (filename), "P101%04i.JPG", n);
 1431         GP_DEBUG ("... done ('%s')", filename);
 1432         CHECK (gp_filesystem_reset (camera->fs));
 1433         CHECK (gp_filesystem_get_folder (camera->fs, filename,
 1434                          &folder, context));
 1435         strncpy (filepath->folder, folder, sizeof (filepath->folder));
 1436         strncpy (filepath->name, filename, sizeof (filepath->name));
 1437     }
 1438 
 1439     GP_DEBUG ("* sierra_capture completed OK");
 1440     return GP_OK;
 1441 }
 1442 
 1443 int sierra_upload_file (Camera *camera, CameraFile *file, GPContext *context)
 1444 {
 1445     const char *data;
 1446     long unsigned int data_size;
 1447 
 1448     /* Put the "magic spell" in register 32 */
 1449     CHECK (sierra_set_int_register (camera, 32, 0x0FEC000E, context));
 1450 
 1451     /* Upload the file */
 1452     CHECK (gp_file_get_data_and_size (file, &data, &data_size));
 1453     CHECK (sierra_set_string_register (camera, 29, data, data_size, context));
 1454 
 1455     /* Send command to order the transfer into NVRAM and wait
 1456        for the completion */
 1457     CHECK (sierra_action (camera, SIERRA_ACTION_UPLOAD, context));
 1458 
 1459     return GP_OK;
 1460 }
 1461 
 1462 static unsigned int
 1463 get_int (const unsigned char b[])
 1464 {
 1465     return (b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24));
 1466 }
 1467 
 1468 int sierra_get_pic_info (Camera *camera, unsigned int n,
 1469              SierraPicInfo *pic_info, GPContext *context)
 1470 {
 1471     unsigned char buf[1024];
 1472     unsigned int buf_len = 0;
 1473     int value, audio_info[8];
 1474 
 1475     CHECK (sierra_get_string_register (camera, 47, n, NULL, buf,
 1476                        &buf_len, context));
 1477     if (buf_len == 0) {
 1478         /*
 1479          * Many (older) serial cameras seem to return 0 bytes back
 1480          * and effectively do not support register 47. Try using
 1481          * other registers to get the data.
 1482          *
 1483          * Don't fail on error so unsupported or semi-broken
 1484          * behaviour does not prevent downloads or other use.
 1485          */
 1486         memset(pic_info, 0, sizeof(*pic_info));
 1487         if (sierra_get_size(camera, 12, n, &value, context) == GP_OK) {
 1488             pic_info->size_file = value;
 1489         }
 1490         if (sierra_get_size(camera, 13, n, &value, context) == GP_OK) {
 1491             pic_info->size_preview = value;
 1492         }
 1493         /*
 1494          * If the following hangs any cameras, just delete this
 1495          * code, and assume that cameras with audio will get audio
 1496          * file information via reg 47.
 1497          *
 1498          * Note that the value variable as used here is number of
 1499          * bytes transferred, not the returned data. Some
 1500          * unsupported sierra commands return zero bytes.
 1501          */
 1502         if ((sierra_get_string_register (camera, 43, n, NULL,
 1503                 (unsigned char *) &audio_info,
 1504                 (unsigned int *)&value,
 1505                 context) == GP_OK) && (value != 0)) {
 1506             pic_info->size_audio = audio_info[0];
 1507         }
 1508         if (sierra_get_int_register (camera, 39, &value, context)
 1509             == GP_OK) {
 1510             pic_info->locked = value;
 1511         } else {
 1512             /*
 1513              * Default to marking as locked (not-deletable).
 1514              * It looks the file can still be deleted if the
 1515              * file is not really locked.
 1516              */
 1517             pic_info->locked = SIERRA_LOCKED_YES;
 1518         }
 1519         return (GP_OK);
 1520     }
 1521 
 1522     if (buf_len != 32) {
 1523         gp_context_error (context, _("Expected 32 bytes, got %i. "
 1524             "Please contact %s."), buf_len, MAIL_GPHOTO_DEVEL);
 1525         return (GP_ERROR_CORRUPTED_DATA);
 1526     }
 1527 
 1528     pic_info->size_file      = get_int (buf);
 1529     pic_info->size_preview   = get_int (buf + 4);
 1530     pic_info->size_audio     = get_int (buf + 8);
 1531     pic_info->resolution     = get_int (buf + 12);
 1532     pic_info->locked         = get_int (buf + 16);
 1533     pic_info->date           = get_int (buf + 20);
 1534     pic_info->animation_type = get_int (buf + 28);
 1535 
 1536     /* Make debugging easier */
 1537     GP_DEBUG ("sierra_get_pic_info ");
 1538     GP_DEBUG ("File size: %d",      pic_info->size_file);
 1539     GP_DEBUG ("Preview size: %i",   pic_info->size_preview);
 1540     GP_DEBUG ("Audio size: %i",     pic_info->size_audio);
 1541     GP_DEBUG ("Resolution: %i",     pic_info->resolution);
 1542     GP_DEBUG ("Locked: %i",         pic_info->locked);
 1543     GP_DEBUG ("Date: %i",           pic_info->date);
 1544     GP_DEBUG ("Animation type: %i", pic_info->animation_type);
 1545 
 1546     return GP_OK;
 1547 }
 1548 
 1549 int sierra_set_locked (Camera *camera, unsigned int n, SierraLocked locked,
 1550                GPContext *context)
 1551 {
 1552     CHECK (sierra_set_int_register (camera, 4, n, context));
 1553     CHECK (sierra_sub_action (camera, SIERRA_ACTION_PROT_STATE,
 1554                   (int) locked, context));
 1555     return GP_OK;
 1556 }
 1557 
 1558 int sierra_get_size (Camera *camera, int reg, unsigned int n, int *value,
 1559              GPContext *context)
 1560 {
 1561     CHECK (sierra_set_int_register (camera, 4, n, context));
 1562     CHECK (sierra_get_int_register (camera, reg, value, context));
 1563     return GP_OK;
 1564 }