diff options
author | Philip Langdale <philipl@overt.org> | 2013-04-14 21:57:27 -0700 |
---|---|---|
committer | Linus Walleij <triad@df.lth.se> | 2013-04-18 22:13:12 +0200 |
commit | e6f7703dd1749504ed9060e1bc55f82ecc456af6 (patch) | |
tree | 2f68227efe0df9af4bfc526bb51fdb413ca9ca13 | |
parent | abdd59de34e74dec76930a567679cde849bfbb94 (diff) | |
download | libmtp-e6f7703dd1749504ed9060e1bc55f82ecc456af6.tar.gz |
Support GetObject for large (>4GB) files.
In general, GetObject for large files is much like SendObject; you
keep trying to transfer data until the sender stops. The existing
code does almost everything you need, except it doesn't use a
sufficient condition to detect the case.
While you might think that a large transfer would be signaled with
a containerLength of 0xFFFFFFFF - this has not proven the case in
my testing; what I see is the file size truncated to 32bits. This
makes the existing condition ineffectual.
An alternative condition, suggested by Han-Wen, is to simply always
use the sender-limited transfer pattern if the transfer is larger
than one packet. This means that the containerLength is ignored for
any transfer over 512 bytes, but it works, and it's really the only
way to handle the corner case where the large file size truncates
to a small value < 512.
Signed-off-by: Philip Langdale <philipl@overt.org>
Signed-off-by: Linus Walleij <triad@df.lth.se>
-rw-r--r-- | src/libopenusb1-glue.c | 6 | ||||
-rw-r--r-- | src/libusb-glue.c | 6 | ||||
-rw-r--r-- | src/libusb1-glue.c | 6 |
3 files changed, 9 insertions, 9 deletions
diff --git a/src/libopenusb1-glue.c b/src/libopenusb1-glue.c index 64f641c..55a4961 100644 --- a/src/libopenusb1-glue.c +++ b/src/libopenusb1-glue.c @@ -1336,7 +1336,7 @@ ptp_usb_getdata(PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler) { break; } } - if (usbdata.length == 0xffffffffU) { + if (rlen == PTP_USB_BULK_HS_MAX_PACKET_LEN_READ) { /* Copy first part of data to 'data' */ putfunc_ret = handler->putfunc( @@ -1352,7 +1352,7 @@ ptp_usb_getdata(PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler) { uint16_t xret; xret = ptp_read_func( - PTP_USB_BULK_HS_MAX_PACKET_LEN_READ, + 0x20000000, handler, params->data, &readdata, @@ -1360,7 +1360,7 @@ ptp_usb_getdata(PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler) { ); if (xret != PTP_RC_OK) return xret; - if (readdata < PTP_USB_BULK_HS_MAX_PACKET_LEN_READ) + if (readdata < 0x20000000) break; } return PTP_RC_OK; diff --git a/src/libusb-glue.c b/src/libusb-glue.c index 580cdb8..f9d3a26 100644 --- a/src/libusb-glue.c +++ b/src/libusb-glue.c @@ -1323,7 +1323,7 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler) break; } } - if (usbdata.length == 0xffffffffU) { + if (rlen == PTP_USB_BULK_HS_MAX_PACKET_LEN_READ) { /* Copy first part of data to 'data' */ putfunc_ret = handler->putfunc( @@ -1339,7 +1339,7 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler) uint16_t xret; xret = ptp_read_func( - PTP_USB_BULK_HS_MAX_PACKET_LEN_READ, + 0x20000000, handler, params->data, &readdata, @@ -1347,7 +1347,7 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler) ); if (xret != PTP_RC_OK) return xret; - if (readdata < PTP_USB_BULK_HS_MAX_PACKET_LEN_READ) + if (readdata < 0x20000000) break; } return PTP_RC_OK; diff --git a/src/libusb1-glue.c b/src/libusb1-glue.c index c59a933..404d684 100644 --- a/src/libusb1-glue.c +++ b/src/libusb1-glue.c @@ -1336,7 +1336,7 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler) break; } } - if (usbdata.length == 0xffffffffU) { + if (rlen == PTP_USB_BULK_HS_MAX_PACKET_LEN_READ) { /* Copy first part of data to 'data' */ putfunc_ret = handler->putfunc( @@ -1352,7 +1352,7 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler) uint16_t xret; xret = ptp_read_func( - PTP_USB_BULK_HS_MAX_PACKET_LEN_READ, + 0x20000000, handler, params->data, &readdata, @@ -1360,7 +1360,7 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler) ); if (xret != PTP_RC_OK) return xret; - if (readdata < PTP_USB_BULK_HS_MAX_PACKET_LEN_READ) + if (readdata < 0x20000000) break; } return PTP_RC_OK; |