summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Meissner <marcus@jet.franken.de>2018-04-15 09:38:50 +0200
committerMarcus Meissner <marcus@jet.franken.de>2018-04-15 09:38:50 +0200
commite3904f32b88248c60a3b968dceebeb973569df20 (patch)
treed0168049bd4e14b91e0a131a15b92018d17a0a26
parente9e3b5301058cac332fbf8824703a72a8f80f35d (diff)
parentbcc69828e2e94ffd3e01975f189ebb77f3ee68c3 (diff)
downloadlibmtp-e3904f32b88248c60a3b968dceebeb973569df20.tar.gz
Merge remote-tracking branch 'github/master'
-rw-r--r--src/device-flags.h9
-rw-r--r--src/libmtp.c15
-rw-r--r--src/music-players.h3
3 files changed, 27 insertions, 0 deletions
diff --git a/src/device-flags.h b/src/device-flags.h
index ba3f22b..0a9d8a3 100644
--- a/src/device-flags.h
+++ b/src/device-flags.h
@@ -288,6 +288,15 @@
* 32 bit.
*/
#define DEVICE_FLAG_PROPLIST_OVERRIDES_OI 0x40000000
+/**
+ * The MTP stack of Samsung Galaxy devices has a mysterious bug in
+ * GetPartialObject. When GetPartialObject is invoked to read the last
+ * bytes of a file and the amount of data to read is such that the
+ * last USB packet sent in the reply matches exactly the USB 2.0
+ * packet size, then the Samsung Galaxy device hangs, resulting in a
+ * timeout error.
+ */
+#define DEVICE_FLAG_SAMSUNG_OFFSET_BUG 0x80000000
/**
* All these bug flags need to be set on SONY NWZ Walkman
diff --git a/src/libmtp.c b/src/libmtp.c
index 0f09138..02431c1 100644
--- a/src/libmtp.c
+++ b/src/libmtp.c
@@ -9086,6 +9086,21 @@ int LIBMTP_GetPartialObject(LIBMTP_mtpdevice_t *device, uint32_t const id,
if (offset + maxbytes > mtpfile->filesize) {
maxbytes = mtpfile->filesize - offset;
}
+ /* The MTP stack of Samsung Galaxy devices has a mysterious bug in
+ * GetPartialObject. When GetPartialObject is invoked to read the
+ * last bytes of a file and the amount of data to read is such that
+ * the last USB packet sent in the reply matches exactly the USB 2.0
+ * packet size, then the Samsung Galaxy device hangs, resulting in a
+ * timeout error.
+ * As a workaround, we read one less byte instead of reaching the
+ * end of the file, forcing the caller to perform an additional read
+ * to get the last byte (i.e. the final read that would fail is
+ * replaced with two partial reads that succeed).
+ */
+ if ((params->device_flags & DEVICE_FLAG_SAMSUNG_OFFSET_BUG) &&
+ (maxbytes % PTP_USB_BULK_HS_MAX_PACKET_LEN_READ) == (PTP_USB_BULK_HS_MAX_PACKET_LEN_READ - PTP_USB_BULK_HDR_LEN)) {
+ maxbytes--;
+ }
if (!ptp_operation_issupported(params, PTP_OC_ANDROID_GetPartialObject64)) {
if (!ptp_operation_issupported(params, PTP_OC_GetPartialObject)) {
diff --git a/src/music-players.h b/src/music-players.h
index 9315307..837a161 100644
--- a/src/music-players.h
+++ b/src/music-players.h
@@ -382,6 +382,7 @@
DEVICE_FLAG_UNLOAD_DRIVER |
DEVICE_FLAG_LONG_TIMEOUT |
DEVICE_FLAG_PROPLIST_OVERRIDES_OI |
+ DEVICE_FLAG_SAMSUNG_OFFSET_BUG |
DEVICE_FLAG_OGG_IS_UNKNOWN |
DEVICE_FLAG_FLAC_IS_UNKNOWN },
{ "Samsung", 0x04e8,
@@ -391,6 +392,7 @@
DEVICE_FLAG_UNLOAD_DRIVER |
DEVICE_FLAG_LONG_TIMEOUT |
DEVICE_FLAG_PROPLIST_OVERRIDES_OI |
+ DEVICE_FLAG_SAMSUNG_OFFSET_BUG |
DEVICE_FLAG_OGG_IS_UNKNOWN |
DEVICE_FLAG_FLAC_IS_UNKNOWN },
// From: Erik Berglund <erikjber@users.sourceforge.net>
@@ -404,6 +406,7 @@
DEVICE_FLAG_UNLOAD_DRIVER |
DEVICE_FLAG_LONG_TIMEOUT |
DEVICE_FLAG_PROPLIST_OVERRIDES_OI |
+ DEVICE_FLAG_SAMSUNG_OFFSET_BUG |
DEVICE_FLAG_OGG_IS_UNKNOWN |
DEVICE_FLAG_FLAC_IS_UNKNOWN },
// From: John Gorkos <ab0oo@users.sourceforge.net> and