summaryrefslogtreecommitdiff
path: root/camlibs/ptp2/usb.c
diff options
context:
space:
mode:
authorMarcus Meissner <marcus@jet.franken.de>2018-11-03 19:29:07 +0100
committerMarcus Meissner <marcus@jet.franken.de>2018-11-03 19:29:07 +0100
commit1ecb6c3132f6d87e4c7848f99c0522abaa01bd37 (patch)
tree0b5f7b46f7e3f2c283282abe8807fa2e188b2ab6 /camlibs/ptp2/usb.c
parent4cdb5c4fae872bb0ac8e79e1425c424f9250b569 (diff)
downloadlibgphoto2-1ecb6c3132f6d87e4c7848f99c0522abaa01bd37.tar.gz
try to drain invalid packet data to be able to recover
Diffstat (limited to 'camlibs/ptp2/usb.c')
-rw-r--r--camlibs/ptp2/usb.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/camlibs/ptp2/usb.c b/camlibs/ptp2/usb.c
index 65bab6eed..403fd6491 100644
--- a/camlibs/ptp2/usb.c
+++ b/camlibs/ptp2/usb.c
@@ -318,7 +318,38 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler)
} else {
GP_LOG_E ("Read broken PTP header (Code is %04x vs %04x).",
dtoh16(usbdata.code), ptp->Code );
+
ret = PTP_ERROR_IO;
+
+ /* if this is a valid packet that came late, drain it to allow reestablishing */
+
+ if (bytes_read >= dtoh32(usbdata.length))
+ goto exit;
+
+ bytes_to_read = dtoh32(usbdata.length) - bytes_read;
+ bytes_read -= PTP_USB_BULK_HDR_LEN;
+
+ data = malloc(READLEN);
+ if (!data) goto exit;
+ while (bytes_to_read > 0) {
+ unsigned long chunk_to_read = bytes_to_read;
+
+ /* if in read-until-short-packet mode, read one packet at a time */
+ /* else read in large blobs */
+ /* else read all but the last short packet depending on EP packetsize. */
+ if (chunk_to_read > READLEN)
+ chunk_to_read = READLEN;
+ else if (chunk_to_read > params->maxpacketsize)
+ chunk_to_read = chunk_to_read - (chunk_to_read % params->maxpacketsize);
+ res = gp_port_read (camera->port, (char*)data, chunk_to_read);
+ if (res == GP_ERROR_IO_READ)
+ break;
+ if (res <= 0)
+ break;
+ bytes_to_read -= res;
+ bytes_read += res;
+ }
+ free (data);
goto exit;
}
}