reports data overflow. git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@6007 67ed7778-7388-44ab-90cf-0a291f65f57c
698 lines
17 KiB
C
698 lines
17 KiB
C
/****************************************************************/
|
|
/* library.c - Gphoto2 library for the KBGear JamCam v2 and v3 */
|
|
/* */
|
|
/* Copyright © 2001 Chris Pinkham */
|
|
/* */
|
|
/* Author: Chris Pinkham <cpinkham@infi.net> */
|
|
/* */
|
|
/* This library is free software; you can redistribute it */
|
|
/* and/or modify it under the terms of the GNU Library General */
|
|
/* Public License as published by the Free Software Foundation; */
|
|
/* either version 2 of the License, or (at your option) any */
|
|
/* later version. */
|
|
/* */
|
|
/* This library is distributed in the hope that it will be */
|
|
/* useful, but WITHOUT ANY WARRANTY; without even the implied */
|
|
/* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */
|
|
/* PURPOSE. See the GNU Library General Public License for */
|
|
/* more details. */
|
|
/* */
|
|
/* You should have received a copy of the GNU Library General */
|
|
/* Public License along with this library; if not, write to the */
|
|
/* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */
|
|
/* Boston, MA 02111-1307, USA. */
|
|
/****************************************************************/
|
|
#include "config.h"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <gphoto2.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
#include <math.h>
|
|
|
|
#include "library.h"
|
|
|
|
#ifdef ENABLE_NLS
|
|
# include <libintl.h>
|
|
# undef _
|
|
# define _(String) dgettext (GETTEXT_PACKAGE, String)
|
|
# ifdef gettext_noop
|
|
# define N_(String) gettext_noop (String)
|
|
# else
|
|
# define N_(String) (String)
|
|
# endif
|
|
#else
|
|
# define textdomain(String) (String)
|
|
# define gettext(String) (String)
|
|
# define dgettext(Domain,Message) (Message)
|
|
# define dcgettext(Domain,Message,Type) (Message)
|
|
# define bindtextdomain(Domain,Directory) (Domain)
|
|
# define _(String) (String)
|
|
# define N_(String) (String)
|
|
#endif
|
|
|
|
#define GP_MODULE
|
|
|
|
struct jamcam_file jamcam_files[1024];
|
|
static int jamcam_count = 0;
|
|
static int jamcam_mmc_card_size = 0;
|
|
|
|
|
|
static int jamcam_set_int_at_pos( unsigned char *buf, int pos, int value ) {
|
|
|
|
buf[pos + 0] = ( value ) & 0xff;
|
|
buf[pos + 1] = ( value >> 8 ) & 0xff;
|
|
buf[pos + 2] = ( value >> 16 ) & 0xff;
|
|
buf[pos + 3] = ( value >> 24 ) & 0xff;
|
|
|
|
return( value );
|
|
}
|
|
|
|
static int jamcam_get_int_at_pos( unsigned char *buf, int pos ) {
|
|
int ret = 0;
|
|
|
|
ret += buf[pos + 0];
|
|
ret += buf[pos + 1] * 256;
|
|
ret += buf[pos + 2] * 256 * 256;
|
|
ret += buf[pos + 3] * 256 * 256 * 256;
|
|
|
|
return( ret );
|
|
}
|
|
|
|
static int jamcam_set_usb_mem_pointer( Camera *camera, int position ) {
|
|
char reply[8];
|
|
|
|
GP_DEBUG ("* jamcam_set_usb_mem_pointer");
|
|
GP_DEBUG ("*** position: %d (0x%x)",
|
|
position, position);
|
|
|
|
gp_port_usb_msg_write( camera->port,
|
|
0xa1,
|
|
( position ) & 0xffff,
|
|
( position >> 16 ) & 0xffff,
|
|
NULL, 0 );
|
|
|
|
gp_port_usb_msg_read( camera->port,
|
|
0xa0,
|
|
0,
|
|
0,
|
|
reply, 8 );
|
|
|
|
return( GP_OK );
|
|
}
|
|
|
|
|
|
/* get the number of images on the mmc card */
|
|
static int jamcam_mmc_card_file_count (Camera *camera) {
|
|
char buf[16];
|
|
unsigned char reply[512];
|
|
unsigned int position = 0x40000000;
|
|
int data_incr;
|
|
int width;
|
|
int height;
|
|
|
|
GP_DEBUG ("* jamcam_mmc_card_file_count");
|
|
|
|
memset( buf, 0, sizeof( buf ));
|
|
|
|
switch( camera->port->type ) {
|
|
default:
|
|
case GP_PORT_SERIAL:
|
|
strcpy( buf, "KB00" );
|
|
jamcam_set_int_at_pos( buf, 4, position );
|
|
jamcam_write_packet( camera, buf, 8 );
|
|
|
|
jamcam_read_packet( camera, reply, 16 );
|
|
|
|
while( strncmp( reply, "KB", 2 ) == 0 ) {
|
|
width = (reply[5] * 256) + reply[4];
|
|
height = (reply[7] * 256) + reply[6];
|
|
|
|
data_incr = jamcam_get_int_at_pos( reply, 8 );
|
|
|
|
jamcam_files[jamcam_count].position = position;
|
|
jamcam_files[jamcam_count].width = width;
|
|
jamcam_files[jamcam_count].height = height;
|
|
jamcam_files[jamcam_count].data_incr = data_incr;
|
|
|
|
jamcam_count++;
|
|
|
|
position += data_incr;
|
|
|
|
jamcam_set_int_at_pos( buf, 4, position );
|
|
jamcam_write_packet( camera, buf, 8 );
|
|
|
|
jamcam_read_packet( camera, reply, 16 );
|
|
}
|
|
break;
|
|
|
|
case GP_PORT_USB:
|
|
gp_port_usb_msg_write( camera->port,
|
|
0xa5,
|
|
0x0005,
|
|
0x0000,
|
|
NULL, 0 );
|
|
|
|
jamcam_set_usb_mem_pointer( camera, position );
|
|
|
|
CHECK( gp_port_read (camera->port, reply, 0x10 ));
|
|
|
|
width = (reply[13] * 256) + reply[12];
|
|
height = (reply[15] * 256) + reply[14];
|
|
|
|
jamcam_set_usb_mem_pointer( camera, position + 8 );
|
|
|
|
CHECK( gp_port_read (camera->port, reply, 512 ));
|
|
|
|
gp_port_usb_msg_write( camera->port,
|
|
0xa5,
|
|
0x0006,
|
|
0x0000,
|
|
NULL, 0 );
|
|
|
|
while(((unsigned char)reply[0] != 0xff ) &&
|
|
((unsigned char)reply[0] != 0xaa ) &&
|
|
(((unsigned char)reply[0] != 0x00 ) ||
|
|
((unsigned char)reply[1] != 0x00 ))) {
|
|
data_incr = jamcam_get_int_at_pos( reply, 0 );
|
|
|
|
jamcam_files[jamcam_count].position = position;
|
|
jamcam_files[jamcam_count].width = width;
|
|
jamcam_files[jamcam_count].height = height;
|
|
jamcam_files[jamcam_count].data_incr = data_incr;
|
|
jamcam_count++;
|
|
|
|
position += data_incr;
|
|
|
|
gp_port_usb_msg_write( camera->port,
|
|
0xa5,
|
|
0x0005,
|
|
0x0000,
|
|
NULL, 0 );
|
|
|
|
jamcam_set_usb_mem_pointer( camera, position );
|
|
|
|
CHECK( gp_port_read (camera->port, reply, 0x10 ));
|
|
|
|
width = (reply[13] * 256) + reply[12];
|
|
height = (reply[15] * 256) + reply[14];
|
|
|
|
jamcam_set_usb_mem_pointer( camera, position + 8 );
|
|
|
|
CHECK( gp_port_read (camera->port, reply, 512 ));
|
|
|
|
gp_port_usb_msg_write( camera->port,
|
|
0xa5,
|
|
0x0006,
|
|
0x0000,
|
|
NULL, 0 );
|
|
}
|
|
break;
|
|
}
|
|
|
|
GP_DEBUG ( "*** returning with jamcam_count = %d", jamcam_count);
|
|
return( 0 );
|
|
}
|
|
|
|
int jamcam_file_count (Camera *camera) {
|
|
char buf[16];
|
|
unsigned char reply[16];
|
|
int position = 0;
|
|
int data_incr;
|
|
int width;
|
|
int height;
|
|
int last_offset_size = 0;
|
|
|
|
GP_DEBUG ("* jamcam_file_count");
|
|
|
|
jamcam_count = 0;
|
|
|
|
memset( buf, 0, sizeof( buf ));
|
|
|
|
switch( camera->port->type ) {
|
|
default:
|
|
case GP_PORT_SERIAL:
|
|
strcpy( buf, "KB00" );
|
|
jamcam_set_int_at_pos( buf, 4, position );
|
|
jamcam_write_packet( camera, buf, 8 );
|
|
|
|
jamcam_read_packet( camera, reply, 16 );
|
|
|
|
while( reply[0] == 'K' ) {
|
|
width = (reply[5] * 256) + reply[4];
|
|
height = (reply[7] * 256) + reply[6];
|
|
|
|
data_incr = jamcam_get_int_at_pos( reply, 8 );
|
|
|
|
last_offset_size = data_incr;
|
|
|
|
jamcam_files[jamcam_count].position = position;
|
|
jamcam_files[jamcam_count].width = width;
|
|
jamcam_files[jamcam_count].height = height;
|
|
jamcam_files[jamcam_count].data_incr = data_incr;
|
|
|
|
jamcam_count++;
|
|
|
|
position += data_incr;
|
|
|
|
jamcam_set_int_at_pos( buf, 4, position );
|
|
jamcam_write_packet( camera, buf, 8 );
|
|
|
|
jamcam_read_packet( camera, reply, 16 );
|
|
}
|
|
|
|
/* the v3 camera uses 0x3fdf0 data increments so check for MMC */
|
|
if ( last_offset_size == 0x03fdf0 ) {
|
|
jamcam_query_mmc_card( camera );
|
|
}
|
|
break;
|
|
|
|
case GP_PORT_USB:
|
|
jamcam_set_usb_mem_pointer( camera, position );
|
|
|
|
CHECK( gp_port_read (camera->port, reply, 0x10 ));
|
|
|
|
width = (reply[13] * 256) + reply[12];
|
|
height = (reply[15] * 256) + reply[14];
|
|
|
|
jamcam_set_usb_mem_pointer( camera, position + 8 );
|
|
|
|
CHECK( gp_port_read (camera->port, reply, 0x10 ));
|
|
|
|
while((unsigned char)reply[0] != 0xff ) {
|
|
data_incr = jamcam_get_int_at_pos( reply, 0 );
|
|
|
|
jamcam_files[jamcam_count].position = position;
|
|
jamcam_files[jamcam_count].width = width;
|
|
jamcam_files[jamcam_count].height = height;
|
|
jamcam_files[jamcam_count].data_incr = data_incr;
|
|
jamcam_count++;
|
|
|
|
position += data_incr;
|
|
|
|
jamcam_set_usb_mem_pointer( camera, position );
|
|
|
|
CHECK( gp_port_read (camera->port, reply, 0x10 ));
|
|
|
|
width = (reply[13] * 256) + reply[12];
|
|
height = (reply[15] * 256) + reply[14];
|
|
|
|
jamcam_set_usb_mem_pointer( camera, position + 8 );
|
|
|
|
CHECK( gp_port_read (camera->port, reply, 0x10 ));
|
|
}
|
|
break;
|
|
}
|
|
|
|
if ( jamcam_mmc_card_size ) {
|
|
jamcam_count += jamcam_mmc_card_file_count( camera );
|
|
}
|
|
|
|
GP_DEBUG ( "*** returning jamcam_count = %d", jamcam_count);
|
|
return( jamcam_count );
|
|
}
|
|
|
|
int jamcam_fetch_memory( Camera *camera, CameraFile *file,
|
|
char *data, int start, int length, GPContext *context) {
|
|
char tmp_buf[16];
|
|
char packet[16];
|
|
int new_start;
|
|
int new_end;
|
|
int bytes_read = 0;
|
|
int bytes_to_read;
|
|
int bytes_left = length;
|
|
int res = GP_OK;
|
|
unsigned int id = 0;
|
|
|
|
GP_DEBUG ("* jamcam_fetch_memory");
|
|
GP_DEBUG (" * start: %d (0x%x)",
|
|
start, start);
|
|
GP_DEBUG (" * length: %d (0x%x)",
|
|
length, length);
|
|
|
|
if ( length > 1000 )
|
|
id = gp_context_progress_start (context, length,
|
|
_("Downloading data..."));
|
|
|
|
while( bytes_left ) {
|
|
switch( camera->port->type ) {
|
|
default:
|
|
case GP_PORT_SERIAL:
|
|
bytes_to_read =
|
|
bytes_left > SER_PKT_SIZE ? SER_PKT_SIZE : bytes_left;
|
|
|
|
memset( packet, 0, sizeof( packet ));
|
|
strcpy( packet, "KB01" );
|
|
|
|
new_start = start + bytes_read;
|
|
new_end = start + bytes_read + bytes_to_read - 1;
|
|
|
|
/* start and end (inclusive) */
|
|
jamcam_set_int_at_pos( packet, 4, new_start );
|
|
jamcam_set_int_at_pos( packet, 8, new_end );
|
|
|
|
jamcam_write_packet( camera, packet, 12 );
|
|
|
|
CHECK (jamcam_read_packet( camera, data + bytes_read,
|
|
bytes_to_read ));
|
|
break;
|
|
case GP_PORT_USB:
|
|
bytes_to_read = bytes_left > USB_PKT_SIZE ? USB_PKT_SIZE : bytes_left;
|
|
|
|
/* for some reason this priming read fixes an offset problem */
|
|
/* in the images, we are only reading the first 16 bytes of */
|
|
/* data twice by doing this, so I don't know why it works */
|
|
jamcam_set_usb_mem_pointer( camera, start + bytes_read );
|
|
CHECK( gp_port_read (camera->port, tmp_buf, 16 ));
|
|
|
|
|
|
jamcam_set_usb_mem_pointer( camera, start + bytes_read );
|
|
CHECK( gp_port_read (camera->port, data + bytes_read, bytes_to_read ));
|
|
|
|
|
|
break;
|
|
}
|
|
|
|
bytes_left -= bytes_to_read;
|
|
bytes_read += bytes_to_read;
|
|
|
|
/* hate this hardcoded, but don't want to update here */
|
|
/* when downloading parts of a thumbnail */
|
|
if ( length > 1000 ) {
|
|
gp_context_progress_update (context, id, bytes_read);
|
|
if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) {
|
|
GP_DEBUG (" * CANCELED");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( length > 1000 )
|
|
gp_context_progress_stop (context, id);
|
|
|
|
if ( res == GP_OK ) {
|
|
GP_DEBUG (" * returning OK");
|
|
}
|
|
return( res );
|
|
}
|
|
|
|
int jamcam_request_image( Camera *camera, CameraFile *file,
|
|
char *buf, int *len, int number, GPContext *context ) {
|
|
int position;
|
|
int result;
|
|
char tmp_buf[300000];
|
|
|
|
GP_DEBUG ("* jamcam_request_image");
|
|
|
|
position = jamcam_files[number].position;
|
|
|
|
/* don't know why this is necessary, but do it anyway */
|
|
if ( camera->port->type == GP_PORT_USB ) {
|
|
position += 8;
|
|
}
|
|
|
|
if ( camera->port->type == GP_PORT_USB ) {
|
|
gp_port_usb_msg_write( camera->port,
|
|
0xa5,
|
|
0x0005,
|
|
0x0000,
|
|
NULL, 0 );
|
|
}
|
|
|
|
result = jamcam_fetch_memory( camera, file, tmp_buf, position,
|
|
jamcam_files[number].data_incr, context );
|
|
|
|
/* this seems to reset the camera to a sane status */
|
|
if ( camera->port->type == GP_PORT_USB ) {
|
|
gp_port_usb_msg_write( camera->port,
|
|
0xa5,
|
|
0x0006,
|
|
0x0000,
|
|
NULL, 0 );
|
|
}
|
|
|
|
if ( result == GP_OK ) {
|
|
*len = jamcam_files[number].width * jamcam_files[number].height;
|
|
memcpy( buf, tmp_buf + 0x10, *len );
|
|
}
|
|
|
|
return( result );
|
|
}
|
|
|
|
struct jamcam_file *jamcam_file_info(Camera *camera, int number)
|
|
{
|
|
return( &jamcam_files[number] );
|
|
}
|
|
|
|
int jamcam_request_thumbnail( Camera *camera, CameraFile *file,
|
|
char *buf, int *len, int number, GPContext *context ) {
|
|
char line[2048];
|
|
char packet[16];
|
|
int position;
|
|
int x, y;
|
|
int res = GP_OK;
|
|
char *ptr;
|
|
int bytes_to_read;
|
|
unsigned int id;
|
|
|
|
GP_DEBUG ("* jamcam_request_thumbnail");
|
|
|
|
memset( packet, 0, sizeof( packet ));
|
|
|
|
position = jamcam_files[number].position + 0x10;
|
|
|
|
*len = 4800;
|
|
|
|
ptr = buf;
|
|
|
|
if ( camera->port->type == GP_PORT_USB ) {
|
|
/* windows driver does this sometimes */
|
|
gp_port_usb_msg_write( camera->port,
|
|
0xa5,
|
|
0x0005,
|
|
0x0000,
|
|
NULL, 0 );
|
|
|
|
/* just read one row of data at a time */
|
|
bytes_to_read = jamcam_files[number].width;
|
|
} else {
|
|
/* MMC card is quirky, need to fetch larger amounts of data */
|
|
if ( position >= 0x40000000 ) {
|
|
/* serial with mmc card needs bigger packets */
|
|
bytes_to_read = 2048;
|
|
} else {
|
|
/* just read one row of data at a time */
|
|
bytes_to_read = jamcam_files[number].width;
|
|
}
|
|
}
|
|
|
|
|
|
/* fetch thumbnail lines and build the thumbnail */
|
|
position += 10 * jamcam_files[number].width;
|
|
id = gp_context_progress_start (context, 60.,
|
|
_("Downloading thumbnail..."));
|
|
for( y = 0 ; y < 60 ; y++ ) {
|
|
jamcam_fetch_memory( camera, file, line, position, bytes_to_read, context );
|
|
|
|
gp_context_progress_update (context, id, y);
|
|
if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) {
|
|
res = GP_ERROR_CANCEL;
|
|
break;
|
|
}
|
|
|
|
if ( jamcam_files[number].width == 600 ) {
|
|
for( x = 22; x < 578 ; x += 7 ) {
|
|
*(ptr++) = line[x];
|
|
}
|
|
position += 7 * 600;
|
|
} else {
|
|
for( x = 0; x < 320 ; ) {
|
|
*(ptr++) = line[x];
|
|
x += 3;
|
|
*(ptr++) = line[x];
|
|
x += 5;
|
|
}
|
|
|
|
if ( y % 2 ) {
|
|
position += 5 * 320;
|
|
} else {
|
|
position += 3 * 320;
|
|
}
|
|
}
|
|
}
|
|
gp_context_progress_stop (context, id);
|
|
|
|
/* this seems to reset the camera to a sane status */
|
|
if ( camera->port->type == GP_PORT_USB ) {
|
|
gp_port_usb_msg_write( camera->port,
|
|
0xa5,
|
|
0x0006,
|
|
0x0000,
|
|
NULL, 0 );
|
|
}
|
|
|
|
return( res );
|
|
}
|
|
|
|
int jamcam_write_packet (Camera *camera, char *packet, int length) {
|
|
int ret, r;
|
|
|
|
GP_DEBUG ("* jamcam_write_packet");
|
|
|
|
for (r = 0; r < RETRIES; r++) {
|
|
ret = gp_port_write (camera->port, packet, length);
|
|
if (ret == GP_ERROR_TIMEOUT)
|
|
continue;
|
|
|
|
return (ret);
|
|
}
|
|
|
|
return (GP_ERROR_TIMEOUT);
|
|
}
|
|
|
|
|
|
int jamcam_read_packet (Camera *camera, char *packet, int length) {
|
|
int r = 0;
|
|
int bytes_read;
|
|
|
|
GP_DEBUG ("* jamcam_read_packet");
|
|
GP_DEBUG ("*** length: %d (0x%x)",
|
|
length, length);
|
|
|
|
for (r = 0; r < RETRIES; r++) {
|
|
bytes_read = gp_port_read (camera->port, packet, length);
|
|
if (bytes_read == GP_ERROR_TIMEOUT)
|
|
continue;
|
|
if (bytes_read < 0)
|
|
return (bytes_read);
|
|
|
|
if ( bytes_read == length ) {
|
|
return( GP_OK );
|
|
}
|
|
}
|
|
|
|
return (GP_ERROR_TIMEOUT);
|
|
}
|
|
|
|
|
|
int jamcam_enq (Camera *camera)
|
|
{
|
|
int ret, r = 0;
|
|
unsigned char buf[16];
|
|
|
|
GP_DEBUG ("* jamcam_enq");
|
|
|
|
memset( buf, 0, 16 );
|
|
|
|
switch( camera->port->type ) {
|
|
default:
|
|
case GP_PORT_SERIAL:
|
|
for (r = 0; r < RETRIES; r++) {
|
|
strcpy((char *)buf, "KB99" );
|
|
|
|
ret = jamcam_write_packet (camera, (char *)buf, 4);
|
|
if (ret == GP_ERROR_TIMEOUT)
|
|
continue;
|
|
if (ret != GP_OK)
|
|
return (ret);
|
|
|
|
ret = jamcam_read_packet (camera, (char *)buf, 4);
|
|
if (ret == GP_ERROR_TIMEOUT)
|
|
continue;
|
|
if (ret != GP_OK)
|
|
return (ret);
|
|
|
|
if ( !strncmp( (char *)buf, "KIDB", 4 )) {
|
|
return (GP_OK);
|
|
}
|
|
}
|
|
return (GP_ERROR_CORRUPTED_DATA);
|
|
break;
|
|
|
|
case GP_PORT_USB:
|
|
for (r = 0; r < RETRIES; r++) {
|
|
gp_port_usb_msg_write( camera->port,
|
|
0xa5,
|
|
0x0004,
|
|
0x0000,
|
|
NULL, 0 );
|
|
jamcam_set_usb_mem_pointer( camera, 0x0000 );
|
|
|
|
CHECK( gp_port_read( camera->port, (char *)buf, 0x0c ));
|
|
|
|
if (( !strncmp( (char *)buf, "KB00", 4 )) ||
|
|
(( buf[0] == 0xff ) && ( buf[1] == 0xff ) &&
|
|
( buf[2] == 0xff ) && ( buf[3] == 0xff ) &&
|
|
( buf[4] == 0xff ) && ( buf[5] == 0xff ) &&
|
|
( buf[6] == 0xff ) && ( buf[7] == 0xff ))) {
|
|
/* found a JamCam v3 camera */
|
|
/* reply contains 4-bytes with MMC card size if present */
|
|
/* set to 0 if none */
|
|
jamcam_mmc_card_size = jamcam_get_int_at_pos( buf, 8 );
|
|
|
|
if ( jamcam_mmc_card_size ) {
|
|
GP_DEBUG ( "* jamcam_enq, MMC card size = %d",
|
|
jamcam_mmc_card_size );
|
|
}
|
|
|
|
return (GP_OK);
|
|
} else if ( !strncmp( (char *)buf + 8, "KB00", 4 )) {
|
|
/* found a JamCam v2 camera */
|
|
/* JamCam v2 doesn't support MMC card so no need to check */
|
|
return (GP_OK);
|
|
} else if (( buf[0] == 0xf0 ) &&
|
|
( buf[1] == 0xfd ) &&
|
|
( buf[2] == 0x03 )) {
|
|
return( GP_OK );
|
|
}
|
|
}
|
|
return (GP_ERROR_CORRUPTED_DATA);
|
|
break;
|
|
}
|
|
|
|
return (GP_ERROR_TIMEOUT);
|
|
}
|
|
|
|
int jamcam_query_mmc_card (Camera *camera)
|
|
{
|
|
int ret, r = 0;
|
|
char buf[16];
|
|
|
|
GP_DEBUG ("* jamcam_query_mmc_card");
|
|
|
|
/* usb port doesn't need this packet, this info found in enquiry reply */
|
|
if ( camera->port->type == GP_PORT_USB ) {
|
|
return( GP_OK );
|
|
}
|
|
|
|
strcpy( buf, "KB04" );
|
|
|
|
for (r = 0; r < RETRIES; r++) {
|
|
|
|
ret = jamcam_write_packet (camera, buf, 4);
|
|
if (ret == GP_ERROR_TIMEOUT)
|
|
continue;
|
|
if (ret != GP_OK)
|
|
return (ret);
|
|
|
|
ret = jamcam_read_packet (camera, buf, 4);
|
|
if (ret == GP_ERROR_TIMEOUT)
|
|
continue;
|
|
if (ret != GP_OK)
|
|
return (ret);
|
|
|
|
/* reply is 4-byte int showing length of MMC card if any, 0 if none */
|
|
jamcam_mmc_card_size = jamcam_get_int_at_pos( buf, 0 );
|
|
|
|
if ( jamcam_mmc_card_size ) {
|
|
GP_DEBUG ("* jamcam_query_mmc_card, MMC card size = %d",
|
|
jamcam_mmc_card_size );
|
|
}
|
|
|
|
return (GP_OK);
|
|
}
|
|
return (GP_ERROR_TIMEOUT);
|
|
}
|
|
|