/** * \brief Check for interrupt without wait * \param port a GPPort * \param data a pointer to an allocated buffer * \param size the number of bytes that should be read * * Reads a specified number of bytes from the inerrupt endpoint * into the supplied buffer. * Function waits 50 miliseconds for data on interrupt endpoint. * * \return a gphoto2 error code **/ int gp_port_check_int_fast (GPPort *port, char *data, int size) { int retval; gp_log (GP_LOG_DATA, __func__, "Reading %i = 0x%x bytes from interrupt endpoint...", size, size); C_PARAMS (port); CHECK_INIT (port); /* Check if we read as many bytes as expected */ CHECK_SUPP (port, "check_int", port->pc->ops->check_int); retval = port->pc->ops->check_int (port, data, size, FAST_TIMEOUT); CHECK_RESULT (retval); #ifdef IGNORE_EMPTY_INTR_READS /* For Canon cameras, we will make lots of reads that will return zero length. Don't bother to log them as errors. */ if (retval != 0 ) #endif LOG_DATA (data, retval, size, "Read ", "from interrupt endpoint (fast):"); return (retval); }
/** * \brief Send a USB interface control message with input data * * \param port a GPPort * \param request control request code * \param value control value * \param index control index * \param bytes pointer to data * \param size size of the data * * Sends a specific USB control command and read associated data. * * \return a gphoto2 error code */ int gp_port_usb_msg_interface_read (GPPort *port, int request, int value, int index, char *bytes, int size) { int retval; gp_log (GP_LOG_DEBUG, "gphoto2-port", "Reading message " "(request=0x%x value=0x%x index=0x%x size=%i=0x%x)...", request, value, index, size, size); CHECK_NULL (port); CHECK_INIT (port); CHECK_SUPP (port, "msg_read", port->pc->ops->msg_interface_read); retval = port->pc->ops->msg_interface_read (port, request, value, index, bytes, size); CHECK_RESULT (retval); if (retval != size) gp_log (GP_LOG_DEBUG, "gphoto2-port", "Could only read %i " "out of %i byte(s)", retval, size); gp_log_data ("gphoto2-port", bytes, retval); return (retval); }
/** * \brief Check for intterupt. * * \param port a GPPort * \param data a pointer to an allocated buffer * \param size the number of bytes that should be read * * Reads a specified number of bytes from the interrupt endpoint * into the supplied buffer. * Function waits port->timeout miliseconds for data on interrupt endpoint. * * \return a gphoto2 error code **/ int gp_port_check_int (GPPort *port, char *data, int size) { int retval; gp_log (GP_LOG_DEBUG, "gphoto2-port", ngettext( "Reading %i=0x%x byte from interrupt endpoint...", "Reading %i=0x%x bytes from interrupt endpoint...", size), size, size); CHECK_NULL (port); CHECK_INIT (port); /* Check if we read as many bytes as expected */ CHECK_SUPP (port, "check_int", port->pc->ops->check_int); retval = port->pc->ops->check_int (port, data, size, port->timeout); CHECK_RESULT (retval); if (retval != size) gp_log (GP_LOG_DEBUG, "gphoto2-port", _("Could only read %i " "out of %i byte(s)"), retval, size); gp_log_data ("gphoto2-port", data, retval); return (retval); }
/** * \brief Send a SCSI command to a port (for usb scsi ports) * * \param port a #GPPort * \param to_dev data direction, set to 1 for a scsi cmd which sends * data to the device, set to 0 for cmds which read data from the dev. * \param cmd buffer holding the command to send * \param cmd_size sizeof cmd buffer * \param sense buffer for returning scsi sense information * \param sense_size sizeof sense buffer * \param data buffer containing informatino to write to the device * (to_dev is 1), or to store data read from the device (to_dev 0). * * Send a SCSI command to a usb scsi port attached device. * * \return a gphoto2 error code **/ int gp_port_send_scsi_cmd (GPPort *port, int to_dev, char *cmd, int cmd_size, char *sense, int sense_size, char *data, int data_size) { int retval; gp_log (GP_LOG_DEBUG, "gphoto2-port", "Sending scsi cmd:"); gp_log_data ("gphoto2-port", cmd, cmd_size); if (to_dev && data_size) { gp_log (GP_LOG_DEBUG, "gphoto2-port", "scsi cmd data:"); gp_log_data ("gphoto2-port", data, data_size); } CHECK_NULL (port); CHECK_INIT (port); memset (sense, 0, sense_size); CHECK_SUPP (port, "send_scsi_cmd", port->pc->ops->send_scsi_cmd); retval = port->pc->ops->send_scsi_cmd (port, to_dev, cmd, cmd_size, sense, sense_size, data, data_size); gp_log (GP_LOG_DEBUG, "gphoto2-port", "scsi cmd result: %d", retval); if (sense[0] != 0) { gp_log (GP_LOG_DEBUG, "gphoto2-port", "sense data:"); gp_log_data ("gphoto2-port", sense, sense_size); /* https://secure.wikimedia.org/wikipedia/en/wiki/Key_Code_Qualifier */ gp_log(GP_LOG_DEBUG, "gphoto2-port","sense decided:"); if ((sense[0]&0x7f)!=0x70) { gp_log(GP_LOG_DEBUG, "gphoto2-port","\tInvalid header."); } gp_log(GP_LOG_DEBUG, "gphoto2-port", "\tCurrent command read filemark: %s",(sense[2]&0x80)?"yes":"no"); gp_log(GP_LOG_DEBUG, "gphoto2-port", "\tEarly warning passed: %s",(sense[2]&0x40)?"yes":"no"); gp_log(GP_LOG_DEBUG, "gphoto2-port", "\tIncorrect blocklengt: %s",(sense[2]&0x20)?"yes":"no"); gp_log(GP_LOG_DEBUG, "gphoto2-port", "\tSense Key: %d",sense[2]&0xf); if (sense[0]&0x80) gp_log(GP_LOG_DEBUG, "gphoto2-port", "\tResidual Length: %d",sense[3]*0x1000000+sense[4]*0x10000+sense[5]*0x100+sense[6]); gp_log(GP_LOG_DEBUG, "gphoto2-port", "\tAdditional Sense Length: %d",sense[7]); gp_log(GP_LOG_DEBUG, "gphoto2-port", "\tAdditional Sense Code: %d",sense[12]); gp_log(GP_LOG_DEBUG, "gphoto2-port", "\tAdditional Sense Code Qualifier: %d",sense[13]); if (sense[15]&0x80) { gp_log(GP_LOG_DEBUG, "gphoto2-port", "\tIllegal Param is in %s",(sense[15]&0x40)?"the CDB":"the Data Out Phase"); if (sense[15]&0x8) { gp_log(GP_LOG_DEBUG, "gphoto2-port", "Pointer at %d, bit %d",sense[16]*256+sense[17],sense[15]&0x7); } } } if (!to_dev && data_size) { gp_log (GP_LOG_DEBUG, "gphoto2-port", "scsi cmd data:"); gp_log_data ("gphoto2-port", data, data_size); } return retval; }
/** * \brief Find USB device by vendor/product * * \param port a GPPort * \param idvendor USB vendor id * \param idproduct USB product id * * Find the USB device with the specified vendor:product id pair. * * \return a gphoto2 error code */ int gp_port_usb_find_device (GPPort *port, int idvendor, int idproduct) { CHECK_NULL (port); CHECK_INIT (port); CHECK_SUPP (port, "find_device", port->pc->ops->find_device); CHECK_RESULT (port->pc->ops->find_device (port, idvendor, idproduct)); return (GP_OK); }
/** * \brief Find USB device by interface class * * \param port a GPPort * \param mainclass the USB interface class * \param subclass the USB interface subclass * \param protocol the USB interface protocol * * Find the USB device with the specified vendor:product id pair. * * \return a gphoto2 error code */ int gp_port_usb_find_device_by_class (GPPort *port, int mainclass, int subclass, int protocol) { CHECK_NULL (port); CHECK_INIT (port); CHECK_SUPP (port, "find_device_by_class", port->pc->ops->find_device_by_class); CHECK_RESULT (port->pc->ops->find_device_by_class (port, mainclass, subclass, protocol)); return (GP_OK); }
/** * \brief Flush data on serial port * * \param port a GPPort * \param direction the direction of the flush * * Flushes the serial output or input (depending on direction) * of the serial port. * * \return a gphoto2 error code */ int gp_port_flush (GPPort *port, int direction) { gp_log (GP_LOG_DEBUG, "gphoto2-port", _("Flushing port...")); CHECK_NULL (port); CHECK_SUPP (port, "flush", port->pc->ops->flush); CHECK_RESULT (port->pc->ops->flush (port, direction)); return (GP_OK); }
/** * \brief Flush data on serial port * * \param port a GPPort * \param direction the direction of the flush * * Flushes the serial output or input (depending on direction) * of the serial port. * * \return a gphoto2 error code */ int gp_port_flush (GPPort *port, int direction) { GP_LOG_D ("Flushing port..."); C_PARAMS (port); CHECK_SUPP (port, "flush", port->pc->ops->flush); CHECK_RESULT (port->pc->ops->flush (port, direction)); return (GP_OK); }
/** * \brief Reset a port. * \param port a #GPPort * * Resets a port. Device will likely reconnect and appear under a new id. * * \return a gphoto2 error code **/ int gp_port_reset (GPPort *port) { GP_LOG_D ("Resetting port..."); C_PARAMS (port); CHECK_INIT (port); CHECK_SUPP (port, "reset", port->pc->ops->reset); CHECK_RESULT (port->pc->ops->reset(port)); return (GP_OK); }
/** * \brief Close a port. * \param port a #GPPort * * Closes a port temporarily. It can afterwards be reopened using * #gp_port_open. * * \return a gphoto2 error code **/ int gp_port_close (GPPort *port) { GP_LOG_D ("Closing port..."); C_PARAMS (port); CHECK_INIT (port); CHECK_SUPP (port, "close", port->pc->ops->close); CHECK_RESULT (port->pc->ops->close(port)); return (GP_OK); }
/** * \brief Reset a port. * \param port a #GPPort * * Resets a port. Device will likely reconnect and appear under a new id. * * \return a gphoto2 error code **/ int gp_port_reset (GPPort *port) { gp_log (GP_LOG_DEBUG, "gphoto2-port", _("Resetting port...")); CHECK_NULL (port); CHECK_INIT (port); CHECK_SUPP (port, "reset", port->pc->ops->reset); CHECK_RESULT (port->pc->ops->reset(port)); return (GP_OK); }
/** * \brief Clear USB endpoint HALT condition * * \param port a GPPort * \param ep endpoint to clear HALT * * Clears the HALT (stall?) endpoint condition of the specified endpoint. * * \return a gphoto2 error code */ int gp_port_usb_clear_halt (GPPort *port, int ep) { GP_LOG_D ("Clear USB halt..."); C_PARAMS (port); CHECK_INIT (port); CHECK_SUPP (port, "clear_halt", port->pc->ops->clear_halt); CHECK_RESULT (port->pc->ops->clear_halt (port, ep)); return (GP_OK); }
/** * \brief Clear USB endpoint HALT condition * * \param port a GPPort * \param ep endpoint to clear HALT * * Clears the HALT (stall?) endpoint condition of the specified endpoint. * * \return a gphoto2 error code */ int gp_port_usb_clear_halt (GPPort *port, int ep) { gp_log (GP_LOG_DEBUG, "gphoto2-port", _("Clear halt...")); CHECK_NULL (port); CHECK_INIT (port); CHECK_SUPP (port, "clear_halt", port->pc->ops->clear_halt); CHECK_RESULT (port->pc->ops->clear_halt (port, ep)); return (GP_OK); }
/** * \brief Send a break over a serial port * * \param port a GPPort * \param duration duration of break in milliseconds * * Sends a break with the specified duration in milliseconds. * * \return a gphoto2 error code */ int gp_port_send_break (GPPort *port, int duration) { GP_LOG_D ("Sending break (%i milliseconds)...", duration); C_PARAMS (port); CHECK_INIT (port); CHECK_SUPP (port, "send_break", port->pc->ops->send_break); CHECK_RESULT (port->pc->ops->send_break (port, duration)); return (GP_OK); }
/** * \brief Close a port. * \param port a #GPPort * * Closes a port temporarily. It can afterwards be reopened using * #gp_port_open. * * \return a gphoto2 error code **/ int gp_port_close (GPPort *port) { gp_log (GP_LOG_DEBUG, "gphoto2-port", _("Closing port...")); CHECK_NULL (port); CHECK_INIT (port); CHECK_SUPP (port, "close", port->pc->ops->close); CHECK_RESULT (port->pc->ops->close(port)); return (GP_OK); }
/** * \brief Send a break over a serial port * * \param port a GPPort * \param duration duration of break in milliseconds * * Sends a break with the specified duration in milliseconds. * * \return a gphoto2 error code */ int gp_port_send_break (GPPort *port, int duration) { gp_log (GP_LOG_DEBUG, "gphoto2-port", _("Sending break (%i " "milliseconds)..."), duration); CHECK_NULL (port); CHECK_INIT (port); CHECK_SUPP (port, "send_break", port->pc->ops->send_break); CHECK_RESULT (port->pc->ops->send_break (port, duration)); return (GP_OK); }
/** * \brief Open a port. * \param port a #GPPort * * Opens a port which should have been created with #gp_port_new and * configured with #gp_port_set_info and #gp_port_set_settings * * \return a gphoto2 error code **/ int gp_port_open (GPPort *port) { C_PARAMS (port); CHECK_INIT (port); GP_LOG_D ("Opening %s port...", port->type == GP_PORT_SERIAL ? "SERIAL" : (port->type == GP_PORT_USB ? "USB" : "")); CHECK_SUPP (port, "open", port->pc->ops->open); CHECK_RESULT (port->pc->ops->open (port)); return GP_OK; }
/** * \brief Get setting of specific serial PIN * * \param port a GPPort * \param pin the serial pin to be retrieved * \param level the setting of the pin * * \return a gphoto2 error code */ int gp_port_get_pin (GPPort *port, GPPin pin, GPLevel *level) { GP_LOG_D ("Getting level of pin %i...", pin); C_PARAMS (port && level); CHECK_INIT (port); CHECK_SUPP (port, "get_pin", port->pc->ops->get_pin); CHECK_RESULT (port->pc->ops->get_pin (port, pin, level)); GP_LOG_D ("Level of pin %i: %i", pin, *level); return (GP_OK); }
/** * \brief Open a port. * \param port a #GPPort * * Opens a port which should have been created with #gp_port_new and * configured with #gp_port_set_info and #gp_port_set_settings * * \return a gphoto2 error code **/ int gp_port_open (GPPort *port) { CHECK_NULL (port); CHECK_INIT (port); gp_log (GP_LOG_DEBUG, "gphoto2-port", _("Opening %s port..."), port->type == GP_PORT_SERIAL ? "SERIAL" : (port->type == GP_PORT_USB ? "USB" : "")); CHECK_SUPP (port, "open", port->pc->ops->open); CHECK_RESULT (port->pc->ops->open (port)); return GP_OK; }
/** * \brief Seek on a port (for usb disk direct ports) * * \param port a #GPPort * \param offset offset to seek to * \param whence the underlying lseek call whence parameter * * Seeks to a specific offset on the usb disk * * \return a gphoto2 error code **/ int gp_port_seek (GPPort *port, int offset, int whence) { int retval; GP_LOG_D ("Seeking to: %d whence: %d", offset, whence); C_PARAMS (port); CHECK_INIT (port); CHECK_SUPP (port, "seek", port->pc->ops->seek); retval = port->pc->ops->seek (port, offset, whence); GP_LOG_D ("Seek result: %d", retval); return retval; }
/** * \brief Get setting of specific serial PIN * * \param port a GPPort * \param pin the serial pin to be retrieved * \param level the setting of the pin * * \return a gphoto2 error code */ int gp_port_get_pin (GPPort *port, GPPin pin, GPLevel *level) { gp_log (GP_LOG_DEBUG, "gphoto2-port", _("Getting level of pin %i..."), pin); CHECK_NULL (port && level); CHECK_INIT (port); CHECK_SUPP (port, "get_pin", port->pc->ops->get_pin); CHECK_RESULT (port->pc->ops->get_pin (port, pin, level)); gp_log (GP_LOG_DEBUG, "gphoto2-port", _("Level of pin %i: %i"), pin, *level); return (GP_OK); }
/** * \brief Send a USB control message with output data * * \param port a GPPort * \param request control request code * \param value control value * \param index control index * \param bytes pointer to data * \param size size of the data * * Sends a specific USB control command and write associated data. * * \return a gphoto2 error code */ int gp_port_usb_msg_write (GPPort *port, int request, int value, int index, char *bytes, int size) { int retval; GP_LOG_DATA (bytes, size, "Writing message (request=0x%x value=0x%x index=0x%x size=%i=0x%x):", request, value, index, size, size); C_PARAMS (port); CHECK_INIT (port); CHECK_SUPP (port, "msg_write", port->pc->ops->msg_write); retval = port->pc->ops->msg_write(port, request, value, index, bytes, size); CHECK_RESULT (retval); return (retval); }
/** * \brief Check for intterupt. * * \param port a GPPort * \param data a pointer to an allocated buffer * \param size the number of bytes that should be read * * Reads a specified number of bytes from the interrupt endpoint * into the supplied buffer. * Function waits port->timeout miliseconds for data on interrupt endpoint. * * \return a gphoto2 error code **/ int gp_port_check_int (GPPort *port, char *data, int size) { int retval; gp_log (GP_LOG_DATA, __func__, "Reading %i = 0x%x bytes from interrupt endpoint...", size, size); C_PARAMS (port); CHECK_INIT (port); /* Check if we read as many bytes as expected */ CHECK_SUPP (port, "check_int", port->pc->ops->check_int); retval = port->pc->ops->check_int (port, data, size, port->timeout); CHECK_RESULT (retval); LOG_DATA (data, retval, size, "Read ", "from interrupt endpoint:"); return (retval); }
/** * \brief Seek on a port (for usb disk direct ports) * * \param port a #GPPort * \param offset offset to seek to * \param whence the underlying lseek call whence parameter * * Seeks to a specific offset on the usb disk * * \return a gphoto2 error code **/ int gp_port_seek (GPPort *port, int offset, int whence) { int retval; gp_log (GP_LOG_DEBUG, "gphoto2-port", "Seeking to: %d whence: %d", offset, whence); CHECK_NULL (port); CHECK_INIT (port); CHECK_SUPP (port, "seek", port->pc->ops->seek); retval = port->pc->ops->seek (port, offset, whence); gp_log (GP_LOG_DEBUG, "gphoto2-port", "Seek result: %d", retval); return retval; }
/** * \brief Check for interrupt without wait * \param port a GPPort * \param data a pointer to an allocated buffer * \param size the number of bytes that should be read * * Reads a specified number of bytes from the inerrupt endpoint * into the supplied buffer. * Function waits 50 miliseconds for data on interrupt endpoint. * * \return a gphoto2 error code **/ int gp_port_check_int_fast (GPPort *port, char *data, int size) { int retval; CHECK_NULL (port); CHECK_INIT (port); /* Check if we read as many bytes as expected */ CHECK_SUPP (port, "check_int", port->pc->ops->check_int); retval = port->pc->ops->check_int (port, data, size, FAST_TIMEOUT); CHECK_RESULT (retval); #ifdef IGNORE_EMPTY_INTR_READS if (retval != size && retval != 0 ) #else if (retval != size ) #endif gp_log (GP_LOG_DEBUG, "gphoto2-port", ngettext( "Could only read %i out of %i byte", "Could only read %i out of %i bytes", size ), retval, size); #ifdef IGNORE_EMPTY_INTR_READS if ( retval != 0 ) { #endif /* For Canon cameras, we will make lots of reads that will return zero length. Don't bother to log them as errors. */ gp_log (GP_LOG_DEBUG, "gphoto2-port", ngettext( "Reading %i=0x%x byte from interrupt endpoint (fast)...", "Reading %i=0x%x bytes from interrupt endpoint (fast)...", size ), size, size); gp_log_data ("gphoto2-port", data, retval); #ifdef IGNORE_EMPTY_INTR_READS } #endif return (retval); }
/** * \brief Set port settings * \param port a #GPPort * \param settings the #GPPortSettings to be set * * Adjusts the settings of a port. You should always call * #gp_port_get_settings, adjust the values depending on the type of the port, * and then call #gp_port_set_settings. * * \return a gphoto2 error code **/ int gp_port_set_settings (GPPort *port, GPPortSettings settings) { GP_LOG_D ("Setting settings..."); C_PARAMS (port); CHECK_INIT (port); /* * We copy the settings to settings_pending and call update on the * port. */ memcpy (&port->settings_pending, &settings, sizeof (port->settings_pending)); CHECK_SUPP (port, "update", port->pc->ops->update); CHECK_RESULT (port->pc->ops->update (port)); return (GP_OK); }
/** * \brief Set port settings * \param port a #GPPort * \param settings the #GPPortSettings to be set * * Adjusts the settings of a port. You should always call * #gp_port_get_settings, adjust the values depending on the type of the port, * and then call #gp_port_set_settings. * * \return a gphoto2 error code **/ int gp_port_set_settings (GPPort *port, GPPortSettings settings) { gp_log (GP_LOG_DEBUG, "gphoto2-port", _("Setting settings...")); CHECK_NULL (port); CHECK_INIT (port); /* * We copy the settings to settings_pending and call update on the * port. */ memcpy (&port->settings_pending, &settings, sizeof (port->settings_pending)); CHECK_SUPP (port, "update", port->pc->ops->update); CHECK_RESULT (port->pc->ops->update (port)); return (GP_OK); }
/** * \brief Send a USB control message with output data * * \param port a GPPort * \param request control request code * \param value control value * \param index control index * \param bytes pointer to data * \param size size of the data * * Sends a specific USB control command and write associated data. * * \return a gphoto2 error code */ int gp_port_usb_msg_write (GPPort *port, int request, int value, int index, char *bytes, int size) { int retval; gp_log (GP_LOG_DEBUG, "gphoto2-port", _("Writing message " "(request=0x%x value=0x%x index=0x%x size=%i=0x%x)..."), request, value, index, size, size); gp_log_data ("gphoto2-port", bytes, size); CHECK_NULL (port); CHECK_INIT (port); CHECK_SUPP (port, "msg_write", port->pc->ops->msg_write); retval = port->pc->ops->msg_write(port, request, value, index, bytes, size); CHECK_RESULT (retval); return (retval); }
/** * \brief Send a USB control message with input data * * \param port a GPPort * \param request control request code * \param value control value * \param index control index * \param bytes pointer to data * \param size size of the data * * Sends a specific USB interface control command and read associated data. * * \return a gphoto2 error code */ int gp_port_usb_msg_read (GPPort *port, int request, int value, int index, char *bytes, int size) { int retval; gp_log (GP_LOG_DATA, __func__, "Reading message (request=0x%x value=0x%x index=0x%x size=%i=0x%x)...", request, value, index, size, size); C_PARAMS (port); CHECK_INIT (port); CHECK_SUPP (port, "msg_read", port->pc->ops->msg_read); retval = port->pc->ops->msg_read (port, request, value, index, bytes, size); CHECK_RESULT (retval); LOG_DATA (bytes, retval, size, "Read", "USB message (request=0x%x value=0x%x index=0x%x size=%i=0x%x)", request, value, index, size, size); return (retval); }
/** * \brief Read data from port * * \param port a #GPPort * \param data a pointer to an allocated buffer * \param size the number of bytes that should be read * * Reads a specified number of bytes from the port into the supplied buffer. * It returns the number of bytes read or a negative error code. * * \return a gphoto2 error code or the amount of data read **/ int gp_port_read (GPPort *port, char *data, int size) { int retval; gp_log (GP_LOG_DATA, __func__, "Reading %i = 0x%x bytes from port...", size, size); C_PARAMS (port); CHECK_INIT (port); /* Check if we read as many bytes as expected */ CHECK_SUPP (port, "read", port->pc->ops->read); retval = port->pc->ops->read (port, data, size); if (retval < 0) { GP_LOG_E ("Reading %i = 0x%x bytes from port failed: %s (%d)", size, size, gp_port_result_as_string(retval), retval); return retval; } LOG_DATA (data, retval, size, "Read ", "from port:"); return (retval); }