From b458e2be7d266a2fefbb76a15391f096bb148132 Mon Sep 17 00:00:00 2001 From: Marcus Meissner Date: Mon, 4 Dec 2006 09:21:45 +0000 Subject: [PATCH] fixed response-packet in data-phase problem for the broken MTP device git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@9499 67ed7778-7388-44ab-90cf-0a291f65f57c --- camlibs/ptp2/ChangeLog | 5 ++++ camlibs/ptp2/ptp.c | 56 ++++++++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/camlibs/ptp2/ChangeLog b/camlibs/ptp2/ChangeLog index a4407b5f1..98884caac 100644 --- a/camlibs/ptp2/ChangeLog +++ b/camlibs/ptp2/ChangeLog @@ -1,3 +1,8 @@ +2006-12-04 Marcus Meissner + + * ptp.c: Fixed the response packet in-data-phase + handling to actually work. From libmtp folks. + 2006-12-02 Marcus Meissner * library.c: Added Canon PowerShot SD600, HP Photosmart C500. diff --git a/camlibs/ptp2/ptp.c b/camlibs/ptp2/ptp.c index 52bf47909..fa572724d 100644 --- a/camlibs/ptp2/ptp.c +++ b/camlibs/ptp2/ptp.c @@ -208,6 +208,25 @@ ptp_usb_senddata (PTPParams* params, PTPContainer* ptp, return ret; } +static uint16_t ptp_usb_getpacket(PTPParams *params, + PTPUSBBulkContainer *packet, unsigned int *rlen) +{ + /* read the header and potentially the first data */ + if (params->response_packet_size > 0) { + /* If there is a buffered packet, just use it. */ + memcpy(packet, params->response_packet, params->response_packet_size); + *rlen = params->response_packet_size; + free(params->response_packet); + params->response_packet = NULL; + params->response_packet_size = 0; + /* Here this signifies a "virtual read" */ + return PTP_RC_OK; + } else { + return params->read_func((unsigned char *)packet, + sizeof(*packet), params->data, rlen); + } +} + uint16_t ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, unsigned char **data, unsigned int *readlen, @@ -224,20 +243,7 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, do { unsigned int len, rlen; - /* read the header and potentially the first data */ - if (params->response_packet_size > 0) { - /* If there is a buffered packet, just use it. */ - memcpy((unsigned char *)&usbdata, params->response_packet, params->response_packet_size); - rlen = params->response_packet_size; - free(params->response_packet); - params->response_packet = NULL; - params->response_packet_size = 0; - /* Here this signifies a "virtual read" */ - ret = PTP_RC_OK; - } else { - ret=params->read_func((unsigned char *)&usbdata, - sizeof(usbdata), params->data, &rlen); - } + ret = ptp_usb_getpacket(params, &usbdata, &rlen); if (ret!=PTP_RC_OK) { ret = PTP_ERROR_IO; break; @@ -281,21 +287,24 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, } if (rlen > dtoh32(usbdata.length)) { /* - * Buffer the surplus response packet if it is >= PTP_USB_BULK_HDR_LEN + * Buffer the surplus response packet if it is >= + * PTP_USB_BULK_HDR_LEN * (i.e. it is probably an entire package) - * else discard it as erroneous surplus data. This will even - * work if more than 2 packets appear in the same transaction, - * they will just be iteratively handled. + * else discard it as erroneous surplus data. + * This will even work if more than 2 packets appear + * in the same transaction, they will just be handled + * iteratively. * - * Marcus observed stray bytes on iRiver devices, these are - * still discarded. + * Marcus observed stray bytes on iRiver devices; + * these are still discarded. */ unsigned int packlen = dtoh32(usbdata.length); unsigned int surplen = rlen - packlen; if (surplen >= PTP_USB_BULK_HDR_LEN) { - params->response_packet = (uint8_t *) malloc(surplen); - memcpy(params->response_packet, (uint8_t *) (&usbdata + packlen), surplen); + params->response_packet = malloc(surplen); + memcpy(params->response_packet, + (uint8_t *) &usbdata + packlen, surplen); params->response_packet_size = surplen; } else { ptp_debug (params, "ptp2/ptp_usb_getdata: read %d bytes too much, expect problems!", rlen - dtoh32(usbdata.length)); @@ -412,8 +421,7 @@ ptp_usb_getresp (PTPParams* params, PTPContainer* resp) PTP_CNT_INIT(usbresp); /* read response, it should never be longer than sizeof(usbresp) */ - ret=params->read_func((unsigned char *)&usbresp, - sizeof(usbresp), params->data, &rlen); + ret = ptp_usb_getpacket(params, &usbresp, &rlen); if (ret!=PTP_RC_OK) { ret = PTP_ERROR_IO;