diff options
author | Marcus Meissner <marcus@jet.franken.de> | 2018-04-15 09:38:50 +0200 |
---|---|---|
committer | Marcus Meissner <marcus@jet.franken.de> | 2018-04-15 09:38:50 +0200 |
commit | e3904f32b88248c60a3b968dceebeb973569df20 (patch) | |
tree | d0168049bd4e14b91e0a131a15b92018d17a0a26 | |
parent | e9e3b5301058cac332fbf8824703a72a8f80f35d (diff) | |
parent | bcc69828e2e94ffd3e01975f189ebb77f3ee68c3 (diff) | |
download | libmtp-e3904f32b88248c60a3b968dceebeb973569df20.tar.gz |
Merge remote-tracking branch 'github/master'
-rw-r--r-- | src/device-flags.h | 9 | ||||
-rw-r--r-- | src/libmtp.c | 15 | ||||
-rw-r--r-- | src/music-players.h | 3 |
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 |