/* This is the parent function, who calls most of the functions below. It returns GP_ERROR if it cannot get the camera data, and GP_OK otherwise. The subroutines will print out more detained information should they fail. */ int dimagev_get_camera_data(dimagev_t *dimagev) { dimagev_packet *p, *raw; unsigned char char_buffer; /* Check the device. */ if ( dimagev->dev == NULL ) { GP_DEBUG( "dimagev_get_camera_data::device not valid"); return GP_ERROR_BAD_PARAMETERS; } /* Let's say hello and get the current status. */ if ( ( p = dimagev_make_packet(DIMAGEV_GET_DATA, 1, 0)) == NULL ) { GP_DEBUG( "dimagev_get_camera_data::unable to allocate packet"); return GP_ERROR_NO_MEMORY; } if ( gp_port_write(dimagev->dev, (char*)p->buffer, p->length) < GP_OK ) { GP_DEBUG( "dimagev_get_camera_data::unable to write packet"); free(p); return GP_ERROR_IO; } else if ( gp_port_read(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_camera_data::no response from camera"); free(p); return GP_ERROR_IO; } free(p); switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: GP_DEBUG( "dimagev_get_camera_data::camera did not acknowledge transmission"); return GP_ERROR_IO; case DIMAGEV_CAN: GP_DEBUG( "dimagev_get_camera_data::camera cancels transmission"); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_get_camera_data::camera responded with unknown value %x", char_buffer); return GP_ERROR_IO; } if ( ( p = dimagev_read_packet(dimagev) ) == NULL ) { GP_DEBUG( "dimagev_get_camera_data::unable to read packet"); return GP_ERROR_IO; } char_buffer = DIMAGEV_EOT; if ( gp_port_write(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_camera_data::unable to send EOT"); free(p); return GP_ERROR_IO; } if ( gp_port_read(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_camera_data::no response from camera"); free(p); return GP_ERROR_IO; } switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: GP_DEBUG( "dimagev_get_camera_data::camera did not acknowledge transmission"); free(p); return GP_ERROR_IO; case DIMAGEV_CAN: GP_DEBUG( "dimagev_get_camera_data::camera cancels transmission"); free(p); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_get_camera_data::camera responded with unknown value %x", char_buffer); free(p); return GP_ERROR_IO; } if ( ( raw = dimagev_strip_packet(p) ) == NULL ) { GP_DEBUG( "dimagev_get_camera_data::unable to strip data packet"); free(p); return GP_ERROR; } if ( ( dimagev->data = dimagev_import_camera_data(raw->buffer)) == NULL ) { GP_DEBUG( "dimagev_get_camera_data::unable to read camera data"); free(raw); free(p); return GP_ERROR; } /* Sure it *should* get freed automagically, but why take the risk? */ free(p); free(raw); return GP_OK; }
/* This function sends the contents of a dimagev_data_t to the current camera. This allows many changes to be made (e.g. entering host mode and record mode) while only sending a single set_data command. */ int dimagev_send_data(dimagev_t *dimagev) { dimagev_packet *p; unsigned char *export_data, char_buffer; if ( dimagev == NULL ) { GP_DEBUG( "dimagev_send_data::unable to use NULL dimagev_t"); return GP_ERROR_BAD_PARAMETERS; } if ( ( export_data = dimagev_export_camera_data(dimagev->data) ) == NULL ) { GP_DEBUG( "dimagev_send_data::unable to export camera data"); return GP_ERROR; } dimagev_dump_camera_data(dimagev->data); if ( ( p = dimagev_make_packet(DIMAGEV_SET_DATA, 1, 0) ) == NULL ) { GP_DEBUG( "dimagev_send_data::unable to create set_data packet"); free(export_data); return GP_ERROR_NO_MEMORY; } if ( gp_port_write(dimagev->dev, (char*)p->buffer, p->length) < GP_OK ) { GP_DEBUG( "dimagev_send_data::unable to send set_data packet"); free(p); free(export_data); return GP_ERROR_IO; } else if ( gp_port_read(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_send_data::no response from camera - trying to send NAK"); free(p); free(export_data); return GP_ERROR_IO; } free(p); switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: GP_DEBUG( "dimagev_send_data::camera did not acknowledge transmission"); free(export_data); return GP_ERROR_IO; case DIMAGEV_CAN: GP_DEBUG( "dimagev_send_data::camera cancels transmission"); free(export_data); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_send_data::camera responded with unknown value %x", char_buffer); free(export_data); return GP_ERROR_IO; } if ( ( p = dimagev_make_packet(export_data, 9, 1) ) == NULL ) { GP_DEBUG( "dimagev_send_data::unable to create set_data packet"); free(export_data); return GP_ERROR_NO_MEMORY; } free(export_data); if ( gp_port_write(dimagev->dev, (char*)p->buffer, p->length) < GP_OK ) { GP_DEBUG( "dimagev_send_data::unable to send data packet"); free(p); return GP_ERROR_IO; } free(p); if ( gp_port_read(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_send_data::no response from camera"); return GP_ERROR_IO; } switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: GP_DEBUG( "dimagev_send_data::camera did not acknowledge transmission"); return GP_ERROR_IO; case DIMAGEV_CAN: GP_DEBUG( "dimagev_send_data::camera cancels transmission"); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_send_data::camera responded with unknown value %x", char_buffer); return GP_ERROR_IO; } char_buffer = DIMAGEV_EOT; if ( gp_port_write(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_send_data::unable to send EOT"); return GP_ERROR_IO; } if ( gp_port_read(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_send_data::no response from camera"); return GP_ERROR_IO; } switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: GP_DEBUG( "dimagev_send_data::camera did not acknowledge transmission"); return GP_ERROR_IO; case DIMAGEV_CAN: GP_DEBUG( "dimagev_send_data::camera cancels transmission"); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_send_data::camera responded with unknown value %x", char_buffer); return GP_ERROR_IO; } if ( sleep(3) != 0 ) { GP_DEBUG( "dimagev_send_data::sleep() returned non-zero value"); } return GP_OK; }
/* This is the parent function, who calls most of the functions below. It returns GP_ERROR if it cannot get the camera data, and GP_OK otherwise. The subroutines will print out more detained information should they fail. */ int dimagev_get_camera_info(dimagev_t *dimagev) { dimagev_packet *p, *raw; unsigned char char_buffer; /* Check the device. */ if ( dimagev->dev == NULL ) { GP_DEBUG( "dimagev_get_camera_info::device not valid"); return GP_ERROR_BAD_PARAMETERS; } /* Make sure that the old info struct is fred, and allocate a new one. */ /* if ( dimagev->info != NULL ) { free(dimagev->info); } */ /* Let's say hello and get the current status. */ if ( ( p = dimagev_make_packet(DIMAGEV_INQUIRY, 1, 0)) == NULL ) { GP_DEBUG( "dimagev_get_camera_info::unable to allocate packet"); return GP_ERROR_IO; } if ( gp_port_write(dimagev->dev, p->buffer, p->length) < GP_OK ) { GP_DEBUG( "dimagev_get_camera_info::unable to write packet"); free(p); return GP_ERROR_IO; } else if ( gp_port_read(dimagev->dev, &char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_camera_info::no response from camera"); free(p); return GP_ERROR_IO; } free(p); switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: /* Keep trying until a CAN is issued. */ GP_DEBUG( "dimagev_get_camera_info::camera did not acknowledge transmission"); return dimagev_get_camera_info(dimagev); case DIMAGEV_CAN: GP_DEBUG( "dimagev_get_camera_info::camera cancels transmission"); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_get_camera_info::camera responded with unknown value %x", char_buffer); return GP_ERROR_IO; } if ( ( p = dimagev_read_packet(dimagev) ) == NULL ) { GP_DEBUG( "dimagev_get_camera_info::unable to read packet"); return GP_ERROR_IO; } char_buffer = DIMAGEV_EOT; if ( gp_port_write(dimagev->dev, &char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_camera_info::unable to send EOT"); free(p); return GP_ERROR_IO; } if ( gp_port_read(dimagev->dev, &char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_camera_info::no response from camera"); free(p); return GP_ERROR_IO; } switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: GP_DEBUG( "dimagev_get_camera_info::camera did not acknowledge transmission"); free(p); return GP_ERROR_IO; case DIMAGEV_CAN: GP_DEBUG( "dimagev_get_camera_info::camera cancels transmission"); free(p); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_get_camera_info::camera responded with unknown value %x", char_buffer); free(p); return GP_ERROR_IO; } if ( ( raw = dimagev_strip_packet(p) ) == NULL ) { GP_DEBUG( "dimagev_get_camera_info::unable to strip data packet"); free(p); return GP_ERROR_NO_MEMORY; } if ( ( dimagev->info = dimagev_import_camera_info(raw->buffer) ) == NULL ) { GP_DEBUG( "dimagev_get_camera_info::unable to read camera info"); free(p); free(raw); return GP_ERROR; } /* Sure it *should* get fred automagically, but why take the risk? */ free(p); free(raw); return GP_OK; }
int dimagev_delete_picture(dimagev_t *dimagev, int file_number) { dimagev_packet *p, *raw; unsigned char command_buffer[3]; char char_buffer = 0; if ( dimagev == NULL ) { GP_DEBUG( "dimagev_delete_picture::unable to use NULL dimagev_t"); return GP_ERROR_BAD_PARAMETERS; } dimagev_dump_camera_status(dimagev->status); /* An image can only be deleted if the card is normal or full. */ if ( dimagev->status->card_status > (unsigned char) 1 ) { GP_DEBUG( "dimagev_delete_picture::memory card does not permit deletion"); return GP_ERROR; } if ( dimagev->data->host_mode != (unsigned char) 1 ) { dimagev->data->host_mode = (unsigned char) 1; if ( dimagev_send_data(dimagev) < GP_OK ) { GP_DEBUG( "dimagev_delete_picture::unable to set host mode"); return GP_ERROR_IO; } } /* First make the command packet. */ command_buffer[0] = 0x05; command_buffer[1] = (unsigned char)( file_number / 256 ); command_buffer[2] = (unsigned char)( file_number % 256 ); if ( ( p = dimagev_make_packet(command_buffer, 3, 0) ) == NULL ) { GP_DEBUG( "dimagev_delete_picture::unable to allocate command packet"); return GP_ERROR_NO_MEMORY; } if ( gp_port_write(dimagev->dev, (char *)p->buffer, p->length) < GP_OK ) { GP_DEBUG( "dimagev_delete_picture::unable to send set_data packet"); free(p); return GP_ERROR_IO; } else if ( gp_port_read(dimagev->dev, &char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_delete_picture::no response from camera"); free(p); return GP_ERROR_IO; } free(p); switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: GP_DEBUG( "dimagev_delete_picture::camera did not acknowledge transmission"); return GP_ERROR_IO; case DIMAGEV_CAN: GP_DEBUG( "dimagev_delete_picture::camera cancels transmission"); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_delete_picture::camera responded with unknown value %x", char_buffer); return GP_ERROR_IO; } if ( ( p = dimagev_read_packet(dimagev) ) == NULL ) { GP_DEBUG( "dimagev_delete_picture::unable to read packet"); return GP_ERROR_IO; } if ( ( raw = dimagev_strip_packet(p) ) == NULL ) { GP_DEBUG( "dimagev_delete_picture::unable to strip packet"); free(p); return GP_ERROR; } free(p); if ( raw->buffer[0] != (unsigned char) 0 ) { GP_DEBUG( "dimagev_delete_picture::delete returned error code"); free(raw); return GP_ERROR_NO_MEMORY; } free(raw); char_buffer=DIMAGEV_EOT; if ( gp_port_write(dimagev->dev, &char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_delete_picture::unable to send ACK"); return GP_ERROR_IO; } if ( gp_port_read(dimagev->dev, &char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_delete_picture::no response from camera"); return GP_ERROR_IO; } switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: GP_DEBUG( "dimagev_delete_picture::camera did not acknowledge transmission"); return GP_ERROR_IO; case DIMAGEV_CAN: GP_DEBUG( "dimagev_delete_picture::camera cancels transmission"); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_delete_picture::camera responded with unknown value %x", char_buffer); return GP_ERROR_IO; } return GP_OK; }
int dimagev_get_picture(dimagev_t *dimagev, int file_number, CameraFile *file) { int total_packets, i; unsigned long size = 0; dimagev_packet *p, *r; unsigned char char_buffer, command_buffer[3]; char *data; if ( dimagev->data->host_mode != (unsigned char) 1 ) { dimagev->data->host_mode = (unsigned char) 1; if ( dimagev_send_data(dimagev) < GP_OK ) { GP_DEBUG( "dimagev_get_picture::unable to set host mode"); return GP_ERROR_IO; } } GP_DEBUG( "dimagev_get_picture::file_number is %d", file_number); /* Maybe check if it exists? Check the file type? */ /* First make the command packet. */ command_buffer[0] = 0x04; command_buffer[1] = (unsigned char)( file_number / 256 ); command_buffer[2] = (unsigned char)( file_number % 256 ); if ( ( p = dimagev_make_packet(command_buffer, 3, 0) ) == NULL ) { GP_DEBUG( "dimagev_get_picture::unable to allocate command packet"); return GP_ERROR_NO_MEMORY; } if ( gp_port_write(dimagev->dev, (char *)p->buffer, p->length) < GP_OK ) { GP_DEBUG( "dimagev_get_picture::unable to send set_data packet"); free(p); return GP_ERROR_IO; } else if ( gp_port_read(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_picture::no response from camera"); free(p); return GP_ERROR_IO; } free(p); switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: GP_DEBUG( "dimagev_get_picture::camera did not acknowledge transmission"); return dimagev_get_picture(dimagev, file_number, file); /* return GP_ERROR_IO;*/ case DIMAGEV_CAN: GP_DEBUG( "dimagev_get_picture::camera cancels transmission"); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_get_picture::camera responded with unknown value %x", char_buffer); return GP_ERROR_IO; } if ( ( p = dimagev_read_packet(dimagev) ) == NULL ) { GP_DEBUG( "dimagev_get_picture::unable to read packet"); return GP_ERROR_IO; } if ( ( r = dimagev_strip_packet(p) ) == NULL ) { GP_DEBUG( "dimagev_get_picture::unable to strip packet"); free(p); return GP_ERROR_NO_MEMORY; } free(p); total_packets = (int) r->buffer[0]; /* Allocate an extra byte just in case. */ if ( ( data = malloc((size_t)((993 * total_packets) + 1)) ) == NULL ) { GP_DEBUG( "dimagev_get_picture::unable to allocate buffer for file"); free(r); return GP_ERROR_NO_MEMORY; } memcpy(data, &(r->buffer[1]), (size_t) r->length ); size += ( r->length - 2 ); free(r); for ( i = 0 ; i < ( total_packets -1 ) ; i++ ) { char_buffer=DIMAGEV_ACK; if ( gp_port_write(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_picture::unable to send ACK"); free(data); return GP_ERROR_IO; } if ( ( p = dimagev_read_packet(dimagev) ) == NULL ) { /* GP_DEBUG( "dimagev_get_picture::unable to read packet"); return GP_ERROR_IO; */ GP_DEBUG( "dimagev_get_picture::sending NAK to get retry"); char_buffer=DIMAGEV_NAK; if ( gp_port_write(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_picture::unable to send NAK"); free(data); return GP_ERROR_IO; } if ( ( p = dimagev_read_packet(dimagev) ) == NULL ) { GP_DEBUG( "dimagev_get_picture::unable to read packet"); free(data); return GP_ERROR_IO; } } if ( ( r = dimagev_strip_packet(p) ) == NULL ) { GP_DEBUG( "dimagev_get_picture::unable to strip packet"); free(data); free(p); return GP_ERROR_NO_MEMORY; } free(p); memcpy(&( data[ ( size + 1) ] ), r->buffer, (size_t) r->length ); size += r->length; free(r); } size++; char_buffer=DIMAGEV_EOT; if ( gp_port_write(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_picture::unable to send ACK"); free(data); return GP_ERROR_IO; } if ( gp_port_read(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_picture::no response from camera"); free(data); return GP_ERROR_IO; } switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: GP_DEBUG( "dimagev_get_picture::camera did not acknowledge transmission"); free(data); return GP_ERROR_IO; case DIMAGEV_CAN: GP_DEBUG( "dimagev_get_picture::camera cancels transmission"); free(data); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_get_picture::camera responded with unknown value %x", char_buffer); free(data); return GP_ERROR_IO; } gp_file_set_data_and_size (file, data, size); return GP_OK; }
int dimagev_get_thumbnail(dimagev_t *dimagev, int file_number, CameraFile *file) { dimagev_packet *p, *r; unsigned char char_buffer, command_buffer[3], *ycrcb_data; char *data; long int size = 0; if ( dimagev->data->host_mode != (unsigned char) 1 ) { dimagev->data->host_mode = (unsigned char) 1; if ( dimagev_send_data(dimagev) < GP_OK ) { GP_DEBUG( "dimagev_get_thumbnail::unable to set host mode"); return GP_ERROR_IO; } } /* First make the command packet. */ command_buffer[0] = 0x0d; command_buffer[1] = (unsigned char)( file_number / 256 ); command_buffer[2] = (unsigned char)( file_number % 256 ); if ( ( p = dimagev_make_packet(command_buffer, 3, 0) ) == NULL ) { GP_DEBUG( "dimagev_get_thumbnail::unable to allocate command packet"); return GP_ERROR_NO_MEMORY; } if ( gp_port_write(dimagev->dev, (char *)p->buffer, p->length) < GP_OK ) { GP_DEBUG( "dimagev_get_thumbnail::unable to send set_data packet"); free(p); return GP_ERROR_IO; } else if ( gp_port_read(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_thumbnail::no response from camera"); free(p); return GP_ERROR_IO; } free(p); switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: GP_DEBUG( "dimagev_get_thumbnail::camera did not acknowledge transmission"); return dimagev_get_thumbnail(dimagev, file_number, file); /* return GP_ERROR_IO;*/ case DIMAGEV_CAN: GP_DEBUG( "dimagev_get_thumbnail::camera cancels transmission"); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_get_thumbnail::camera responded with unknown value %x", char_buffer); return GP_ERROR_IO; } if ( ( p = dimagev_read_packet(dimagev) ) == NULL ) { GP_DEBUG( "dimagev_get_thumbnail::unable to read packet"); return GP_ERROR_IO; } if ( ( r = dimagev_strip_packet(p) ) == NULL ) { GP_DEBUG( "dimagev_get_thumbnail::unable to strip packet"); free(p); return GP_ERROR_NO_MEMORY; } free(p); /* Unlike normal images, we are guaranteed 9600 bytes *exactly*. */ /* Allocate an extra byte just in case. */ if ( ( ycrcb_data = malloc(9600) ) == NULL ) { GP_DEBUG( "dimagev_get_thumbnail::unable to allocate buffer for file"); free(r); return GP_ERROR_NO_MEMORY; } memcpy(ycrcb_data, r->buffer, (size_t) r->length ); size += r->length - 1 ; free(r); while ( size < 9599 ) { char_buffer=DIMAGEV_ACK; if ( gp_port_write(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_thumbnail::unable to send ACK"); free(ycrcb_data); return GP_ERROR_IO; } if ( ( p = dimagev_read_packet(dimagev) ) == NULL ) { GP_DEBUG( "dimagev_get_thumbnail::unable to read packet"); free(ycrcb_data); return GP_ERROR_IO; } if ( ( r = dimagev_strip_packet(p) ) == NULL ) { GP_DEBUG( "dimagev_get_thumbnail::unable to strip packet"); free(p); free(ycrcb_data); return GP_ERROR_NO_MEMORY; } free(p); memcpy(&( ycrcb_data[ ( size + 1) ] ), r->buffer, (size_t) r->length ); size += r->length; free(r); GP_DEBUG( "dimagev_get_thumbnail::current file size is %ld", size); } size++; char_buffer=DIMAGEV_EOT; if ( gp_port_write(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_thumbnail::unable to send ACK"); free(ycrcb_data); return GP_ERROR_IO; } if ( gp_port_read(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_get_thumbnail::no response from camera"); free(ycrcb_data); return GP_ERROR_IO; } switch ( char_buffer ) { case DIMAGEV_ACK: break; case DIMAGEV_NAK: GP_DEBUG( "dimagev_get_thumbnail::camera did not acknowledge transmission"); free(ycrcb_data); return GP_ERROR_IO; case DIMAGEV_CAN: GP_DEBUG( "dimagev_get_thumbnail::camera cancels transmission"); free(ycrcb_data); return GP_ERROR_IO; default: GP_DEBUG( "dimagev_get_thumbnail::camera responded with unknown value %x", char_buffer); free(ycrcb_data); return GP_ERROR_IO; } data = (char *)dimagev_ycbcr_to_ppm(ycrcb_data); size = 14413; gp_file_set_data_and_size (file, data, size); return GP_OK; }