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
This commit is contained in:
Marcus Meissner
2006-12-04 09:21:45 +00:00
parent 25eadaa28a
commit b458e2be7d
2 changed files with 37 additions and 24 deletions

View File

@@ -1,3 +1,8 @@
2006-12-04 Marcus Meissner <marcus@jet.franken.de>
* ptp.c: Fixed the response packet in-data-phase
handling to actually work. From libmtp folks.
2006-12-02 Marcus Meissner <marcus@jet.franken.de>
* library.c: Added Canon PowerShot SD600, HP Photosmart C500.

View File

@@ -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;