int jl2005c_delete_all (Camera *camera, GPPort *port) { gp_port_write(port, "\x09\x00", 2); usleep(10000); gp_port_write(port, "\x07\x00", 2); return GP_OK; }
static int digita_serial_send(CameraPrivateLibrary *dev, void *_buffer, int len) { char *buffer = _buffer; unsigned short s; int sent = 0, size; while (sent < len) { if ((len - sent) > dev->deviceframesize) size = dev->deviceframesize; else size = len - sent; if (poll_and_wait(dev->gpdev, size, sent == 0, (size + sent) == len) < 0) return -1; if (gp_port_write(dev->gpdev, buffer + sent, size) < 0) return -1; sent += size; } s = 0; if (gp_port_write(dev->gpdev, (void *)&s, sizeof(s)) < 0) return -1; return len; }
/* * Capture an image */ static int camera_capture (Camera* camera, CameraCaptureType type, CameraFilePath* path, GPContext *context) { unsigned char cmd[3], buf[256], ack; int ret, nbr_images,images_taken,i; GP_DEBUG ("*** ENTER: camera_capture ***"); /* Just check if there is space available yet */ cmd[0] = ESC; cmd[1] = GETCAMINFO; ret = gp_port_write (camera->port, (char*)cmd, 2); if (ret<GP_OK) return ret; ret = gp_port_read (camera->port, (char*)buf, INFO_BUFFER); nbr_images = (buf[FREE_IMAGE_PTR] << 8) | (buf[FREE_IMAGE_PTR+1]); images_taken = (buf[TAKEN_IMAGE_PTR] << 8) | (buf[TAKEN_IMAGE_PTR+1]); /* Capture the image */ cmd[0] = ESC; cmd[1] = CAPTUREIMAGE_CMD1; cmd[2] = CAPTUREIMAGE_CMD2; ret = gp_port_write (camera->port, (char*)cmd, sizeof(cmd)); if (ret<GP_OK) return ret; ret = gp_port_read (camera->port, (char*)&ack, ACK_LEN); if (ret<GP_OK) return ret; if (ack == NACK) { if (buf[CAMERA_MODE_PTR] != REC_MODE) gp_context_error(context, _("You must be in record " "mode to capture images.")); else if (!nbr_images) gp_context_error(context, _("No space available " "to capture new images. You must delete some " "images.")); else gp_context_error(context, _("Can't capture new images. " "Unknown error")); return (GP_ERROR); } /* Wait image writting in camera's memory */ for (i=0; i<=15; i++) { sleep(1); if ((ret = k_ping(camera->port)) == GP_OK) break; } if (ret < GP_OK) { gp_context_error(context, _("No answer from the camera.")); return (GP_ERROR); } /* Now register new image */ images_taken++; sprintf (path->name, FILENAME, (unsigned int) images_taken); return (GP_OK); }
static int mars_routine (Info *info, GPPort *port, char param, int n) { char c[16]; char start[2] = {0x19, 0x51}; char do_something[2]; char address1[2]; char address2[2]; char address3[2]; char address4[2]; char address5[2]; char address6[2]; do_something[0]= 0x19; do_something[1]=param; /* See protocol.txt for my theories about what these mean. */ address1[0] = 0x19; address1[1] = info[8*n+1]; address2[0] = 0x19; address2[1] = info[8*n+2]; address3[0] = 0x19; address3[1] = info[8*n+3]; address4[0] = 0x19; address4[1] = info[8*n+4]; address5[0] = 0x19; address5[1] = info[8*n+5]; address6[0] = 0x19; address6[1] = info[8*n+6]; memset(c,0,sizeof(c)); /*Routine used in initialization, photo download, and reset. */ m_read(port, c, 16); m_command(port, start, 2, c); m_command(port, do_something, 2, c); m_command(port, address1, 2, c); c[0] = 0; gp_port_write(port, address2, 2); /* Moving the memory cursor to the given address? */ while (( c[0] != 0xa) ) { m_read(port, c, 16); } m_command(port, address3, 2, c); m_command(port, address4, 2, c); m_command(port, address5, 2, c); m_command(port, address6, 2, c); gp_port_write(port, "\x19", 1); gp_port_read(port, c , 16); /* Next thing is to switch the inep. Some cameras need a pause here */ usleep (MARS_SLEEP); return(c[0]); }
int jl2005c_reset (Camera *camera, GPPort *port) { int downloadsize = MAX_DLSIZE; /* If any data has been downloaded, these cameras want all data to be * dumped before exit. If that is not yet done, then do it now! */ if(camera->pl->data_reg_opened) { while (camera->pl->bytes_read_from_camera < camera->pl->total_data_in_camera ) { if (! camera->pl->data_cache ) camera->pl->data_cache = malloc (MAX_DLSIZE); downloadsize = MAX_DLSIZE; if (camera->pl->bytes_read_from_camera + MAX_DLSIZE >= camera->pl->total_data_in_camera ) downloadsize = camera->pl->total_data_in_camera - camera->pl->bytes_read_from_camera; if (downloadsize) jl2005c_read_data (camera->port, (char *) camera->pl->data_cache, downloadsize); camera->pl->bytes_read_from_camera += downloadsize; } } gp_port_write(port, "\x07\x00", 2); camera->pl->data_reg_opened = 0; return GP_OK; }
uint16_t ptp_usb_sendreq (PTPParams* params, PTPContainer* req) { int res; PTPUSBBulkContainer usbreq; unsigned long towrite; Camera *camera = ((PTPData *)params->data)->camera; /* build appropriate USB container */ usbreq.length=htod32(PTP_USB_BULK_REQ_LEN- (sizeof(uint32_t)*(5-req->Nparam))); usbreq.type=htod16(PTP_USB_CONTAINER_COMMAND); usbreq.code=htod16(req->Code); usbreq.trans_id=htod32(req->Transaction_ID); usbreq.payload.params.param1=htod32(req->Param1); usbreq.payload.params.param2=htod32(req->Param2); usbreq.payload.params.param3=htod32(req->Param3); usbreq.payload.params.param4=htod32(req->Param4); usbreq.payload.params.param5=htod32(req->Param5); /* send it to responder */ towrite = PTP_USB_BULK_REQ_LEN-(sizeof(uint32_t)*(5-req->Nparam)); res = gp_port_write (camera->port, (char*)&usbreq, towrite); if (res != towrite) { gp_log (GP_LOG_DEBUG, "ptp2/usb_sendreq", "request code 0x%04x sending req result %d", req->Code,res); return PTP_ERROR_IO; } return PTP_RC_OK; }
static int m_command (GPPort *port, char *command, int size, char *response) { gp_port_write(port, command, size); m_read(port, response, 16); return GP_OK; }
static int SDSC_send (GPPort *port, unsigned char command) { CHECK_RESULT (gp_port_write (port, &command, 1)); return (GP_OK); }
static int m_read (GPPort *port, char *data, int size) { gp_port_write(port, "\x21", 1); gp_port_read(port, data, 16); return GP_OK; }
/* * Delete all images */ static int delete_all_func (CameraFilesystem *fs, const char *folder, void *data, GPContext *context) { unsigned char cmd[7], ack; int ret; Camera *camera = data; GP_DEBUG ("*** ENTER: delete_all_func ***"); cmd[0] = ESC; cmd[1] = ERASEIMAGE_CMD1; cmd[2] = IMAGE_CMD2; cmd[3] = 0x30; cmd[4] = 0x30; cmd[5] = 0x30; cmd[6] = 0x30; ret = gp_port_write (camera->port, (char*)cmd, sizeof(cmd)); if (ret<GP_OK) return ret; ret = gp_port_read (camera->port, (char*)&ack, ACK_LEN); if (ret<GP_OK) return ret; if (ack != ACK) { gp_context_error(context, _("Can't delete all images.")); return (GP_ERROR); } return (GP_OK); }
/* * check for a camera, or a modem, send AT, if the response is 0x21, * it is a camera, if it is "AT" it's a modem. * * returns GP_OK = camera * GP_ERROR_MODEL_NOT_FOUND = modem * other = error */ int mesa_modem_check( GPPort *port ) { uint8_t b[3]; b[0] = 'A'; b[1] = 'T'; b[2] = '\r'; CHECK (gp_port_write( port, b, sizeof( b ) )); /* Expect at least one byte */ if ( mesa_read( port, b, 1, 5, 0 ) < 1 ) { return GP_ERROR_TIMEOUT; } if ( b[0] == CMD_ACK ) return GP_OK; /* Anything past this point results in an error */ if ( mesa_read( port, b+1, sizeof(b) - 1, 2, 2 ) == sizeof(b) - 1 ) { if ( b[0] == 'A' && b[1] == 'T' ) { mesa_flush( port, 10 ); return GP_ERROR_MODEL_NOT_FOUND; } } mesa_flush( port, 10 ); return GP_ERROR; }
/* Filenames are always 12 bytes long */ int32_t soundvision_send_file_command(const char *filename, CameraPrivateLibrary *dev) { char file_cmd[16]; htole32a(&file_cmd[0],0xc); /* Length is 12 little-endian 32 bits */ strncpy(&file_cmd[4],filename,12); /* Filename is 12 bytes at the end */ return gp_port_write (dev->gpdev, file_cmd, sizeof(file_cmd)); }
int jl2005c_open_data_reg (Camera *camera, GPPort *port) { gp_port_write (port, "\x0b\x00",2); usleep (10000); GP_DEBUG("Opening data register.\n"); camera->pl->data_reg_opened = 1; return GP_OK; }
int camera_init (Camera *camera, GPContext *context) { GPPortSettings settings; int speeds[] = { 115200, 9600, 19200, 38400, 57600, 115200 }; int ret, i; char cmd[3], buf[1]; /* First, set up all the function pointers. */ camera->functions->capture = camera_capture; camera->functions->about = camera_about; camera->functions->get_config = camera_get_config; camera->functions->set_config = camera_set_config; camera->functions->summary = camera_summary; camera->functions->manual = camera_manual; /* Now, tell the filesystem where to get lists, files and info */ gp_filesystem_set_funcs (camera->fs, &fsfuncs, camera); /* * The port is already provided with camera->port (and * already open). You just have to use functions like * gp_port_timeout_set, gp_port_settings_get, gp_port_settings_set. */ gp_port_get_settings (camera->port, &settings); settings.serial.speed = 115200; settings.serial.bits = 8; settings.serial.stopbits= 1; settings.serial.parity = 0; gp_port_set_settings (camera->port, settings); /* * Once you have configured the port, you should check if a * connection to the camera can be established. */ for (i=0;i<sizeof(speeds)/sizeof(speeds[0]);i++) { gp_port_get_settings (camera->port, &settings); settings.serial.speed = speeds[i]; gp_port_set_settings (camera->port, settings); if (GP_OK<=k_ping (camera->port)) break; } if (i == sizeof(speeds)/sizeof(speeds[0])) return GP_ERROR; cmd[0] = ESC; cmd[1] = SETSPEED; cmd[2] = 0x30 + 4; /* speed nr 4:(9600, 19200, 38400, 57600, 115200) */ ret = gp_port_write (camera->port, cmd, 3); if (ret<GP_OK) return ret; ret = gp_port_read (camera->port, buf, 1); if (ret<GP_OK) return ret; if (buf[0] != ACK) return GP_ERROR; gp_port_get_settings (camera->port, &settings); settings.serial.speed = 115200; gp_port_set_settings (camera->port, settings); return GP_OK; }
static int ultrapocket_command(GPPort *port, int iswrite, unsigned char *data, int datasize) { int ret; if (iswrite) ret = gp_port_write(port, (char *)data, datasize); else ret = gp_port_read(port, (char *)data, datasize); return ret; }
/* * l859_sendcmd - Send command to camera */ static int l859_sendcmd(Camera *camera, uint8_t cmd) { GP_DEBUG ("Sending command: 0x%02x.", cmd); memset(camera->pl->buf, 0, 1); camera->pl->buf[0] = cmd; return gp_port_write(camera->port, camera->pl->buf, 1); }
/* * Read image informations */ static int k_info_img (unsigned int image_no, void *data, CameraFileInfo* info, int *data_number) { unsigned char cmd[6], buf[INFO_BUFFER]; Camera *camera = data; int ret; /* Read file information */ cmd[0] = ESC; cmd[1] = GETIMAGEINFO; cmd[2] = 0x30 + ((image_no/1000)%10); cmd[3] = 0x30 + ((image_no/100 )%10); cmd[4] = 0x30 + ((image_no/10 )%10); cmd[5] = 0x30 + ( image_no %10); ret = gp_port_write (camera->port, (char*)cmd, sizeof(cmd)); if (ret<GP_OK) return ret; ret = gp_port_read (camera->port, (char*)buf, INFO_BUFFER); if (ret<GP_OK) return ret; /* Search the image data number into the memory */ if (data_number != NULL) *data_number = (buf[IMAGE_NUMBER] << 8) | (buf[IMAGE_NUMBER+1]); /* Get the file info here and write it into <info> */ /* There is no audio support with this camera */ info->audio.fields = GP_FILE_INFO_NONE; /* Preview informations */ info->preview.fields = GP_FILE_INFO_TYPE | GP_FILE_INFO_SIZE | GP_FILE_INFO_WIDTH | GP_FILE_INFO_HEIGHT; strcpy (info->preview.type, GP_MIME_JPEG); info->preview.size = ((buf[PREVIEW_SIZE_PTR] << 24) | (buf[PREVIEW_SIZE_PTR+1] << 16) | (buf[PREVIEW_SIZE_PTR+2] << 8) | buf[PREVIEW_SIZE_PTR+3]); info->preview.width = PREVIEW_WIDTH; info->preview.height = PREVIEW_HEIGHT; /* Image information */ info->file.fields = GP_FILE_INFO_TYPE | GP_FILE_INFO_SIZE | GP_FILE_INFO_WIDTH | GP_FILE_INFO_HEIGHT | GP_FILE_INFO_PERMISSIONS; strcpy (info->file.type, GP_MIME_JPEG); info->file.size = ((buf[IMAGE_SIZE_PTR] << 24) | (buf[IMAGE_SIZE_PTR+1] << 16) | (buf[IMAGE_SIZE_PTR+2] << 8) | buf[IMAGE_SIZE_PTR+3]); info->file.width = IMAGE_WIDTH; info->file.height = IMAGE_HEIGHT; if (buf[IMAGE_PROTECTION_FLAG] == IMAGE_PROTECTED) info->file.permissions = GP_FILE_PERM_READ; else info->file.permissions = GP_FILE_PERM_ALL; return (GP_OK); }
/* * downloads data from camera and send * a checksum every 512 bytes. */ int mdc800_rs232_download (GPPort *port,unsigned char* buffer, int size) { int readen=0,i,j; unsigned char checksum; unsigned char DSC_checksum; int numtries=0; gp_port_set_timeout(port, MDC800_DEFAULT_TIMEOUT ); while (readen < size) { if (!mdc800_rs232_receive (port,&buffer[readen],512)) return readen; checksum=0; for (i=0; i<512; i++) checksum=(checksum+buffer[readen+i])%256; if (gp_port_write (port,(char*) &checksum,1) < GP_OK) return readen; if (!mdc800_rs232_receive (port,&DSC_checksum,1)) return readen; if (checksum != DSC_checksum) { numtries++; printCError ("(mdc800_rs232_download) checksum: software %i, DSC %i , reload block! (%i) \n",checksum,DSC_checksum,numtries); if (numtries > 10) { printCError ("(mdc800_rs232_download) to many retries, giving up.."); return 0; } } else { readen+=512; numtries=0; } } for (i=0; i<4; i++) { printCError ("%i: ",i); for (j=0; j<8; j++) printCError (" %i", buffer[i*8+j]); printCError ("\n"); } return readen; }
/* * Check the connection and the camera */ static int k_ping (GPPort *port) { char cmd[2], buf[1]; int ret; cmd[0] = ESC; cmd[1] = PING; ret = gp_port_write (port, cmd, 2); if (ret<GP_OK) return ret; ret = gp_port_read (port, buf, 1); if (ret<GP_OK) return ret; if (buf[0] != ACK) return GP_ERROR; return GP_OK; }
/* Regular commands always 8 bytes long */ int32_t soundvision_send_command(uint32_t command, uint32_t argument, CameraPrivateLibrary *dev) { uint8_t cmd[12]; int result; htole32a(&cmd[0],8); /* Length "8" in little-endian 32bits */ htole32a(&cmd[4],command); /* Command is a little-endian 32bits */ htole32a(&cmd[8],argument); /* Argument is a little-endian 32bits */ result=gp_port_write(dev->gpdev,(char *)&cmd,sizeof(cmd)); if (result<0) return result; return GP_OK; }
static int dwrite(GPPort*port, caddr_t buf, int xsize) { int i; int ret = gp_port_write(port,buf,xsize); if (ret < GP_OK) { perror("dwrite"); return -1; } fprintf(stderr,"dwrite[%d/%d]:",xsize,ret); for (i=0;i<xsize;i++) fprintf(stderr,"%02x,",buf[i]); fprintf(stderr,"\n"); return ret; }
/* * Delete one image * The image mustn't be protected */ static int delete_file_func (CameraFilesystem *fs, const char *folder, const char *filename, void *data, GPContext *context) { Camera *camera = data; CameraFileInfo file_info; unsigned char cmd[7], ack; int image_no; int ret; GP_DEBUG ("*** ENTER: delete_file_func ***"); image_no = gp_filesystem_number(fs, folder, filename, context); if (image_no < 0) return image_no; image_no++; ret = k_info_img (image_no, data, (CameraFileInfo *)&file_info, &image_no); if (ret < GP_OK) return ret; /* Now, check if the image isn't protected */ if (file_info.file.permissions == GP_FILE_PERM_READ) { gp_context_error(context, _("Image %s is delete protected."), filename); return (GP_ERROR); } /* Erase the image */ cmd[0] = ESC; cmd[1] = ERASEIMAGE_CMD1; cmd[2] = IMAGE_CMD2; cmd[3] = 0x30 + ((image_no/1000)%10); cmd[4] = 0x30 + ((image_no/100 )%10); cmd[5] = 0x30 + ((image_no/10 )%10); cmd[6] = 0x30 + ( image_no %10); ret = gp_port_write (camera->port, (char*)cmd, sizeof(cmd)); if (ret<GP_OK) return ret; ret = gp_port_read (camera->port, (char*)&ack, ACK_LEN); if (ret<GP_OK) return ret; if (ack != ACK) { gp_context_error(context, _("Can't delete image %s."),filename); return (GP_ERROR); } return (GP_OK); }
static int poll_and_wait(gp_port *dev, int length, int bob, int eob) { unsigned short s, poll, poll_reply; poll = POLL_POLL | POLL_CMD | (length & POLL_LENGTH_MASK) | (bob ? POLL_BOB : 0) | (eob ? POLL_EOB : 0); do { s = htobe16(poll); if (gp_port_write(dev, (void *)&s, sizeof(s)) < 0) return -1; if (gp_port_read(dev, (void *)&s, sizeof(s)) < 0) return -1; poll_reply = be16toh(s); } while (poll_reply & POLL_NAK); return 0; }
static int poll_and_reply(gp_port *dev, int *length, int *eob, int nak) { unsigned short s, poll; if (gp_port_read(dev, (void *)&s, sizeof(s)) < 0) return -1; poll = be16toh(s); if (length) *length = poll & POLL_LENGTH_MASK; if (eob) *eob = poll & POLL_EOB; s = htobe16(nak ? POLL_NAK : POLL_ACK); if (gp_port_write(dev, (void *)&s, sizeof(s)) < 0) return -1; return 0; }
/* Send a command to the camera and read the acknowledgement byte */ int mesa_send_command( GPPort *port, uint8_t *cmd, int n, int ackTimeout ) { uint8_t c; CHECK (gp_port_write( port, cmd, n )); if ( mesa_read( port, &c, 1, ackTimeout, 0 ) != 1 ) { debuglog("mesa_send_command: timeout"); return GP_ERROR_TIMEOUT; } if ( c != CMD_ACK ) { debuglog("mesa_send_command: error response"); return GP_ERROR_CORRUPTED_DATA; } return GP_OK; }
/* * Create the image list */ static int file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list, void *data, GPContext *context) { Camera *camera = data; unsigned char cmd[2], buf[INFO_BUFFER]; int num, ret; GP_DEBUG ("*** ENTER: file_list_func ***"); cmd[0] = ESC; cmd[1] = GETCAMINFO; ret = gp_port_write (camera->port, (char*)cmd, sizeof(cmd)); if (ret<GP_OK) return ret; ret = gp_port_read (camera->port, (char*)buf, INFO_BUFFER); if (ret<GP_OK) return ret; num = (buf[TAKEN_IMAGE_PTR] << 8) | (buf[TAKEN_IMAGE_PTR+1]); gp_list_populate (list, FILENAME, num); return GP_OK; }
uint16_t ptp_usb_sendreq (PTPParams* params, PTPContainer* req) { int res, towrite, do_retry = TRUE; PTPUSBBulkContainer usbreq; Camera *camera = ((PTPData *)params->data)->camera; GP_LOG_D ("Sending PTP_OC 0x%0x (%s) request...", req->Code, ptp_get_opcode_name(params, req->Code)); /* build appropriate USB container */ usbreq.length=htod32(PTP_USB_BULK_REQ_LEN- (sizeof(uint32_t)*(5-req->Nparam))); usbreq.type=htod16(PTP_USB_CONTAINER_COMMAND); usbreq.code=htod16(req->Code); usbreq.trans_id=htod32(req->Transaction_ID); usbreq.payload.params.param1=htod32(req->Param1); usbreq.payload.params.param2=htod32(req->Param2); usbreq.payload.params.param3=htod32(req->Param3); usbreq.payload.params.param4=htod32(req->Param4); usbreq.payload.params.param5=htod32(req->Param5); /* send it to responder */ towrite = PTP_USB_BULK_REQ_LEN-(sizeof(uint32_t)*(5-req->Nparam)); retry: res = gp_port_write (camera->port, (char*)&usbreq, towrite); if (res != towrite) { if (res < 0) { GP_LOG_E ("PTP_OC 0x%04x sending req failed: %s (%d)", req->Code, gp_port_result_as_string(res), res); if (res == GP_ERROR_IO_WRITE && do_retry) { GP_LOG_D ("Clearing halt on OUT EP and retrying once."); gp_port_usb_clear_halt (camera->port, GP_PORT_USB_ENDPOINT_OUT); do_retry = FALSE; goto retry; } } else GP_LOG_E ("PTP_OC 0x%04x sending req failed: wrote only %d of %d bytes", req->Code, res, towrite); return PTP_ERROR_IO; } return PTP_RC_OK; }
int mars_init (Camera *camera, GPPort *port, Info *info) { char c[16]; unsigned char status = 0; memset(info,0, sizeof(*info)); memset(c,0,sizeof(c)); GP_DEBUG("Running mars_init\n"); /* Init routine done twice, usually. First time is a dry run. But if * camera reports 0x02 it is "jammed" and we must clear it. */ m_read(port, c, 16); if ( (c[0] == 0x02 ) ) { gp_port_write(port, "\x19", 1); gp_port_read(port, c, 16); } else { status = mars_routine (info, port, INIT, 0); GP_DEBUG("status = 0x%x\n", status); } /* Not a typo. This _will_ download the config data ;) */ mars_read_picture_data (camera, info, port, (char *)info, 0x2000, 0); /* Removing extraneous line(s) of data. See "protocol.txt" */ if ((info[0] == 0xff)&& (info[1] == 0)&&(info[2]==0xff)) memmove(info, info + 16, 0x1ff0); /* Saving config */ else memcpy(info, info + 144, 0x1f70); /* Saving config */ GP_DEBUG("Leaving mars_init\n"); return GP_OK; }
dimagev_packet *dimagev_read_packet(dimagev_t *dimagev) { dimagev_packet *p; unsigned char char_buffer; if ( ( p = malloc(sizeof(dimagev_packet)) ) == NULL ) { GP_DEBUG("dimagev_read_packet::unable to allocate packet"); return NULL; } if ( gp_port_read(dimagev->dev, p->buffer, 4) < GP_OK ) { GP_DEBUG( "dimagev_read_packet::unable to read packet header - will try to send NAK"); free(p); /* Send a NAK */ char_buffer = DIMAGEV_NAK; if ( gp_port_write(dimagev->dev, &char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_read_packet::unable to send NAK"); return NULL; } /* Who likes recursion? */ return ( p = dimagev_read_packet(dimagev)); } p->length = ( p->buffer[2] * 256 ) + ( p->buffer[3] ); if ( gp_port_read(dimagev->dev, &(p->buffer[4]), ( p->length - 4)) < GP_OK ) { GP_DEBUG( "dimagev_read_packet::unable to read packet body - will try to send NAK"); free(p); /* Send a NAK */ char_buffer = DIMAGEV_NAK; if ( gp_port_write(dimagev->dev, &char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_read_packet::unable to send NAK"); return NULL; } /* Who likes recursion? */ return ( p = dimagev_read_packet(dimagev)); } /* Now we *should* have a packet. Let's do a sanity check. */ if ( dimagev_verify_packet(p) < GP_OK ) { GP_DEBUG( "dimagev_read_packet::got an invalid packet - will try to send NAK"); free(p); /* Send a NAK */ char_buffer = DIMAGEV_NAK; if ( gp_port_write(dimagev->dev, &char_buffer, 1) < GP_OK ) { GP_DEBUG( "dimagev_read_packet::unable to send NAK"); return NULL; } /* Who likes recursion? */ return ( p = dimagev_read_packet(dimagev)); } return p; }
/* 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; }