summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--INSTALL17
-rw-r--r--logs/mtp-detect-cowon-iaudio-u3.txt260
-rw-r--r--src/libmtp.c20
-rw-r--r--src/libusb-glue.c6
-rw-r--r--src/libusb-glue.h9
-rw-r--r--src/unicode.c30
-rw-r--r--src/unicode.h1
8 files changed, 350 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index bec5e9d..0c36f0a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2007-08-24 Linus Walleij <triad@df.lth.se>
+
+ * src/libusb-glue.h: new device flag to strip all non-7bit chars from
+ filenames on some lame devices.
+ * src/libusb-glue.c: tag the Philips Shoqbox with this flag.
+ * src/libmtp.c: strip the non-7bit chars from filenames if that
+ flag is set.
+ * src/unicode.h: introduce a 7bit-strip helper function.
+ * src/unicode.c: dito.
+
2007-08-22 Linus Walleij <triad@df.lth.se>
* src/libmtp.c: deal with setting of metadata sets for u16/u32:s that
diff --git a/INSTALL b/INSTALL
index 55b492e..f777aba 100644
--- a/INSTALL
+++ b/INSTALL
@@ -168,3 +168,20 @@ has write access on /proc/bus/usb/*
You can find the Linux hotplug project at:
http://linux-hotplug.sourceforge.net/
+
+
+Compilation for embedded devices
+--------------------------------
+
+Problems with Autoconf complaining about a missing malloc() function
+during cross-compilation can be solved with this hack if you're using
+glibc:
+
+ % export ac_cv_func_malloc_0_nonnull=yes
+ % ./configure
+
+If you're using uclibc you may have to smack in a custom rpl_malloc()
+function in your program, see the Autoconf texinfo documentation.
+
+See further:
+http://wiki.buici.com/wiki/Autoconf_and_RPL_MALLOC \ No newline at end of file
diff --git a/logs/mtp-detect-cowon-iaudio-u3.txt b/logs/mtp-detect-cowon-iaudio-u3.txt
new file mode 100644
index 0000000..6ed4629
--- /dev/null
+++ b/logs/mtp-detect-cowon-iaudio-u3.txt
@@ -0,0 +1,260 @@
+libmtp version: 0.2.1
+
+Attempting to connect device(s)
+Detect: Successfully connected 1 devices
+USB low-level info:
+ Using kernel interface "usbfs"
+ bcdUSB: 512
+ bDeviceClass: 0
+ bDeviceSubClass: 0
+ bDeviceProtocol: 0
+ idVendor: 0e21
+ idProduct: 0701
+ IN endpoint maxpacket: 64 bytes
+ OUT endpoint maxpacket: 64 bytes
+ Device flags: 0x00000000
+Device info:
+ Manufacturer: COWON SYSTEMS, Inc.
+ Model: iAUDIO U3
+ Device version:
+ Serial number: 070709180728009DC10000E04CC34BD9
+ Vendor extension ID: 0x00000006
+ Vendor extension description: microsoft.com/WMDRMPD: 10.1;audible.com: 1.0;
+Supported operations:
+ 1001: get device info
+ 1002: Open session
+ 1003: Close session
+ 1004: Get storage IDs
+ 1005: Get storage info
+ 1006: Get number of objects
+ 1007: Get object handles
+ 1008: Get object info
+ 1009: Get object
+ 100b: Delete object
+ 100c: Send object info
+ 100d: Send object
+ 100f: Format storage
+ 1010: Reset device
+ 1014: Get device property description
+ 1015: Get device property value
+ 1016: Set device property value
+ 1017: Reset device property value
+ 9810: Get object references
+ 9811: Set object references
+ 9802: Get object property description
+ 9801: Get object properties supported
+ 9803: Get object property value
+ 9804: Set object property value
+ 9805: Get object property list
+ 9806: Set object property list
+ 101b: Get partial object
+ 9101: Get secure time challenge
+ 9102: Get secure time response
+ 9103: Set license response
+ 9104: Get sync list
+ 9105: Send meter challenge query
+ 9106: Get meter challenge
+ 9107: Get meter response
+ 9108: Clean data store
+ 9109: Get license state
+ 910a: Send WMDRM-PD Command
+ 910b: Send WMDRM-PD Request
+Events supported:
+ None.
+Device Properties Supported:
+ 0x5001: Battery Level
+ 0xd401: Synchronization Partner
+ 0xd402: Device Friendly Name
+ 0xd101: Secure Time
+ 0xd102: Device Certificate
+Playable File (Object) Types and Object Properties Supported:
+ 3009: MP3
+ dc97: EffectiveRating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc8a: Rating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc44: Name STRING data type GET/SET
+ dc01: StorageID UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc04: ObjectSize UINT64 data type READ ONLY
+ dc07: ObjectFileName STRING data type GET/SET
+ dc09: DateModified STRING data type GET/SET
+ dc4f: NonConsumable UINT8 data type enumeration: 0, 1, GET/SET
+ dc02: ObjectFormat UINT16 data type ANY 16BIT VALUE form READ ONLY
+ dc0b: ParentObject UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc41: PersistantUniqueObjectIdentifier UINT128 data type READ ONLY
+ dc03: ProtectionStatus UINT16 data type enumeration: 0, 1, READ ONLY
+ dc8b: Track UINT16 data type ANY 16BIT VALUE form GET/SET
+ de9a: AudioBitRate UINT32 data type range: MIN 8000, MAX 320000, STEP 1 READ ONLY
+ dc46: Artist STRING data type GET/SET
+ dc8c: Genre STRING data type GET/SET
+ de93: SampleRate UINT32 data type range: MIN 8000, MAX 48000, STEP 50 READ ONLY
+ de94: NumberOfChannels UINT16 data type enumeration: 1, 2, READ ONLY
+ dc9a: AlbumName STRING data type GET/SET
+ dc89: Duration UINT32 data type ANY 32BIT VALUE form GET/SET
+ de99: AudioWAVECodec UINT32 data type enumeration: 0, 1, 2, 3, 8, 9, 11, 49, 50, 80, 85, 352, 353, 354, 355, 356, 41222, GET/SET
+ dc99: OriginalReleaseDate STRING data type GET/SET
+ b901: WMA
+ dc97: EffectiveRating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc8a: Rating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc44: Name STRING data type GET/SET
+ dc01: StorageID UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc04: ObjectSize UINT64 data type READ ONLY
+ dc07: ObjectFileName STRING data type GET/SET
+ dc09: DateModified STRING data type GET/SET
+ dc4f: NonConsumable UINT8 data type enumeration: 0, 1, GET/SET
+ dc02: ObjectFormat UINT16 data type ANY 16BIT VALUE form READ ONLY
+ dc0b: ParentObject UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc41: PersistantUniqueObjectIdentifier UINT128 data type READ ONLY
+ dc03: ProtectionStatus UINT16 data type enumeration: 0, 1, READ ONLY
+ dc8b: Track UINT16 data type ANY 16BIT VALUE form GET/SET
+ de9a: AudioBitRate UINT32 data type range: MIN 5000, MAX 320000, STEP 1 READ ONLY
+ dc46: Artist STRING data type GET/SET
+ dc8c: Genre STRING data type GET/SET
+ de93: SampleRate UINT32 data type range: MIN 8000, MAX 48000, STEP 50 READ ONLY
+ de94: NumberOfChannels UINT16 data type enumeration: 1, 2, READ ONLY
+ dc9a: AlbumName STRING data type GET/SET
+ dc89: Duration UINT32 data type ANY 32BIT VALUE form GET/SET
+ de99: AudioWAVECodec UINT32 data type enumeration: 0, 1, 2, 3, 8, 9, 11, 49, 50, 80, 85, 352, 353, 354, 355, 356, 41222, GET/SET
+ dc99: OriginalReleaseDate STRING data type GET/SET
+ 3801: JPEG
+ dc97: EffectiveRating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc8a: Rating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc44: Name STRING data type GET/SET
+ dc01: StorageID UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc04: ObjectSize UINT64 data type READ ONLY
+ dc07: ObjectFileName STRING data type GET/SET
+ dc09: DateModified STRING data type GET/SET
+ dc4f: NonConsumable UINT8 data type enumeration: 0, 1, GET/SET
+ dc02: ObjectFormat UINT16 data type ANY 16BIT VALUE form READ ONLY
+ dc0b: ParentObject UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc41: PersistantUniqueObjectIdentifier UINT128 data type READ ONLY
+ dc03: ProtectionStatus UINT16 data type enumeration: 0, 1, READ ONLY
+ 300a: MS AVI
+ dc97: EffectiveRating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc8a: Rating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc44: Name STRING data type GET/SET
+ dc01: StorageID UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc04: ObjectSize UINT64 data type READ ONLY
+ dc07: ObjectFileName STRING data type GET/SET
+ dc09: DateModified STRING data type GET/SET
+ dc4f: NonConsumable UINT8 data type enumeration: 0, 1, GET/SET
+ dc02: ObjectFormat UINT16 data type ANY 16BIT VALUE form READ ONLY
+ dc0b: ParentObject UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc41: PersistantUniqueObjectIdentifier UINT128 data type READ ONLY
+ dc03: ProtectionStatus UINT16 data type enumeration: 0, 1, READ ONLY
+ 3001: Association/Directory
+ dc97: EffectiveRating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc8a: Rating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc44: Name STRING data type GET/SET
+ dc01: StorageID UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc04: ObjectSize UINT64 data type READ ONLY
+ dc07: ObjectFileName STRING data type GET/SET
+ dc09: DateModified STRING data type GET/SET
+ dc4f: NonConsumable UINT8 data type enumeration: 0, 1, GET/SET
+ dc02: ObjectFormat UINT16 data type ANY 16BIT VALUE form READ ONLY
+ dc0b: ParentObject UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc41: PersistantUniqueObjectIdentifier UINT128 data type READ ONLY
+ dc03: ProtectionStatus UINT16 data type enumeration: 0, 1, READ ONLY
+ ba05: Abstract Audio Video Playlist
+ dc97: EffectiveRating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc8a: Rating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc44: Name STRING data type GET/SET
+ dc01: StorageID UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc04: ObjectSize UINT64 data type READ ONLY
+ dc07: ObjectFileName STRING data type GET/SET
+ dc09: DateModified STRING data type GET/SET
+ dc4f: NonConsumable UINT8 data type enumeration: 0, 1, GET/SET
+ dc02: ObjectFormat UINT16 data type ANY 16BIT VALUE form READ ONLY
+ dc0b: ParentObject UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc41: PersistantUniqueObjectIdentifier UINT128 data type READ ONLY
+ dc03: ProtectionStatus UINT16 data type enumeration: 0, 1, READ ONLY
+ 3000: Undefined Type
+ dc97: EffectiveRating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc8a: Rating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc44: Name STRING data type GET/SET
+ dc01: StorageID UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc04: ObjectSize UINT64 data type READ ONLY
+ dc07: ObjectFileName STRING data type GET/SET
+ dc09: DateModified STRING data type GET/SET
+ dc4f: NonConsumable UINT8 data type enumeration: 0, 1, GET/SET
+ dc02: ObjectFormat UINT16 data type ANY 16BIT VALUE form READ ONLY
+ dc0b: ParentObject UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc41: PersistantUniqueObjectIdentifier UINT128 data type READ ONLY
+ dc03: ProtectionStatus UINT16 data type enumeration: 0, 1, READ ONLY
+ b802: Firmware
+ dc97: EffectiveRating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc8a: Rating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc44: Name STRING data type GET/SET
+ dc01: StorageID UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc04: ObjectSize UINT64 data type READ ONLY
+ dc07: ObjectFileName STRING data type GET/SET
+ dc09: DateModified STRING data type GET/SET
+ dc4f: NonConsumable UINT8 data type enumeration: 0, 1, GET/SET
+ dc02: ObjectFormat UINT16 data type ANY 16BIT VALUE form READ ONLY
+ dc0b: ParentObject UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc41: PersistantUniqueObjectIdentifier UINT128 data type READ ONLY
+ dc03: ProtectionStatus UINT16 data type enumeration: 0, 1, READ ONLY
+ ba03: Abstract Audio Album
+ dc97: EffectiveRating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc8a: Rating UINT16 data type range: MIN 0, MAX 100, STEP 1 GET/SET
+ dc44: Name STRING data type GET/SET
+ dc01: StorageID UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc04: ObjectSize UINT64 data type READ ONLY
+ dc07: ObjectFileName STRING data type GET/SET
+ dc09: DateModified STRING data type GET/SET
+ dc4f: NonConsumable UINT8 data type enumeration: 0, 1, GET/SET
+ dc02: ObjectFormat UINT16 data type ANY 16BIT VALUE form READ ONLY
+ dc0b: ParentObject UINT32 data type ANY 32BIT VALUE form READ ONLY
+ dc41: PersistantUniqueObjectIdentifier UINT128 data type READ ONLY
+ dc03: ProtectionStatus UINT16 data type enumeration: 0, 1, READ ONLY
+ dc86: RepresentativeSampleData array of UINT8 data type ANY 8BIT VALUE form GET/SET
+ dc81: RepresentativeSampleFormat UINT16 data type enumeration: 14337, READ ONLY
+ dc83: RepresentativeSampleHeight UINT32 data type range: MIN 0, MAX 1000000, STEP 1 READ ONLY
+ dc84: RepresentativeSampleWidth UINT32 data type range: MIN 0, MAX 1000000, STEP 1 READ ONLY
+ dc46: Artist STRING data type GET/SET
+ dc8c: Genre STRING data type GET/SET
+Storage Devices:
+ StorageID: 0x00010001
+ StorageType: 0x0003
+ FilesystemType: 0x0002
+ AccessCapability: 0x0000
+ MaxCapacity: 1998856192
+ FreeSpaceInBytes: 1909501789
+ FreeSpaceInObjects: 3463
+ StorageDescription: Internal Storage
+ VolumeIdentifier: 070709180728009DC10000E04CC34BD9
+Special directories:
+ Default music folder: 0x00000000
+ Default playlist folder: 0x00000000
+ Default picture folder: 0x00000000
+ Default video folder: 0x00000000
+ Default organizer folder: 0x00000000
+ Default zencast folder: 0x00000000
+ Default album folder: 0x00000000
+ Default text folder: 0x00000000
+MTP-specific device properties:
+ Friendly name: iAUDIO U3
+ Synchronization partner: Longhorn Sync Engine
+ Battery level 100 of 100 (100%)
+libmtp supported (playable) filetypes:
+ ISO MPEG-1 Audio Layer 3
+ Microsoft Windows Media Audio
+ JPEG file
+ Audio Video Interleave
+ Firmware file
+
+Secure Time:
+<DRMCLOCK type="status"><VALUE>#20050214
+21:55:58Z#</VALUE><FLAG>DRM_CLK_NEEDS_REFRESH</FLAG></DRMCLOCK>AG></DRMCLOCK>
+
+Device Certificate:
+<DEVCERT version="1.0"><CERTIFICATE type="DEVICE"><DATA><UNIQUEID
+private="1">BwcJGAcoAJ3BAADgTMNL2QAAAAA=</UNIQUEID><PUBLICKEY
+private="1">vfDhBXaNQlRRG9V5abU1/R9SpHrjc86jupyGALap5seg4jzOPxGVUw==</PUBLICKEY><KEYDATA>1vX7YOqtS1Lk9Wlmmf/wqZGHtFc=</KEYDATA></DATA><MSDRM_SIGNATURE_VALUE>pbyIv5wY9kKwgq4FwJfu+7DEelOM3PTbAe62illRcG+gR7ak+xKVGQ==</MSDRM_SIGNATURE_VALUE><SYMSIGNATURE>DexHP/w29hVmYtDW4IsxKRLiMNk=</SYMSIGNATURE></CERTIFICATE><FALLBACK><SECURITYVERSION>2.4.102.169</SECURITYVERSION><CERTIFICATE
+private="1">vfDhBXaNQlRRG9V5abU1/R9SpHrjc86jupyGALap5seg4jzOPxGVUwIEZqlU4PbfqA5uknmVVe6QWGzKbu9KXKnl+lLy5PzubzdMQB+1Q7gVEB5K</CERTIFICATE></FALLBACK><CERTIFICATE
+type="GROUP"><DATA><NAME>iAudio U3 MTP</NAME><MANUFACTURER>COWON
+Systems, Inc.</MANUFACTURER><MAKE>COWON Systems,
+Inc.</MAKE><DISTRIBUTOR>COWON Systems, Inc.</DISTRIBUTOR><MODEL>iAudio
+U3</MODEL><SECURITYLEVEL>2000</SECURITYLEVEL><HARDWARE_VER_MAJOR>1</HARDWARE_VER_MAJOR><HARDWARE_VER_MINOR>3</HARDWARE_VER_MINOR><FIRMWARE_VER_MAJOR>1</FIRMWARE_VER_MAJOR><FIRMWARE_VER_MINOR>2</FIRMWARE_VER_MINOR><FEATURES><CLOCK>2</CLOCK><SECURECLOCK><URL>http://go.microsoft.com/fwlink/?LinkId=25817</URL><PUBLICKEY>!CNhvvz1WaNV1AFUmetxkvm9iD4UrE9cnGUi!qcqdxMiXmD1*ikYGA==</PUBLICKEY></SECURECLOCK><METERING>1</METERING><LICENSE_ACQ>1</LICENSE_ACQ><LICENSE_SYNC>1</LICENSE_SYNC><ENCRYPTION>1</ENCRYPTION><SYMMETRIC_OPT>1</SYMMETRIC_OPT></FEATURES><LIMITS><MAXCHAINDEPTH>2</MAXCHAINDEPTH><MAXLICENSESIZE>10240</MAXLICENSESIZE><MAXHEADERSIZE>5120</MAXHEADERSIZE></LIMITS><PUBLICKEY>Ap4rKQEBTuHQZBBcYMqOgcraBkqKHTUXl8pbRIx+quIq0aLccpXZXA==</PUBLICKEY></DATA><MSDRM_SIGNATURE_VALUE>hUe6hoIHQ8Ub6S10Sf7QJQxBfxwWbatdyxZADUvnav5ghZLNv4J9Rg==</MSDRM_SIGNATURE_VALUE></CERTIFICATE><CERTIFICATE
+type="AUTHORIZATION"><DATA><SECURITYLEVEL>2000</SECURITYLEVEL><AUTH_ID>525</AUTH_ID><PUBLICKEY>+hVWeQQEOLQH8QxQghdd5Cnb1zcHSQR2HLVlTTInXNFKBkSn9bC4Mg==</PUBLICKEY></DATA><MSDRM_SIGNATURE_VALUE>cXGlAjnUI7m/AFKFGx/zGf8SYyge+bGSW2S5NwkuBnCRJkDUcpY5XQ==</MSDRM_SIGNATURE_VALUE></CERTIFICATE><CERTIFICATE
+type="AUTHORIZATION_ROOT"><DATA><AUTH_ID>1</AUTH_ID><PUBLICKEY>a1t3hxrg!qbOgktnbYaEEi4teCse!gz6RvTPuC!zizKJlpU7xoduSw==</PUBLICKEY></DATA><MSDRM_SIGNATURE_VALUE>y7C+qgiwu/FP5YRSXzf6vJAv4Tb06hv+Y8IC9z2tnA362aLhpY9MSQ==</MSDRM_SIGNATURE_VALUE></CERTIFICATE></DEVCERT>
+WMPInfo.xml Does not exist on this device
+OK.
diff --git a/src/libmtp.c b/src/libmtp.c
index 96106e7..40af5c6 100644
--- a/src/libmtp.c
+++ b/src/libmtp.c
@@ -3946,8 +3946,12 @@ int LIBMTP_Send_File_From_File_Descriptor(LIBMTP_mtpdevice_t *device,
prop->ObjectHandle = filedata->item_id;
prop->property = PTP_OPC_ObjectFileName;
prop->datatype = PTP_DTC_STR;
- if (filedata->filename != NULL)
+ if (filedata->filename != NULL) {
prop->propval.str = strdup(filedata->filename);
+ if (ptp_usb->device_flags & DEVICE_FLAG_ONLY_7BIT_FILENAMES) {
+ strip_7bit_from_utf8(prop->propval.str);
+ }
+ }
proplist = add_mtp_prop_to_proplist(proplist, prop);
break;
case PTP_OPC_ProtectionStatus:
@@ -4001,6 +4005,9 @@ int LIBMTP_Send_File_From_File_Descriptor(LIBMTP_mtpdevice_t *device,
memset(&new_file, 0, sizeof(PTPObjectInfo));
new_file.Filename = filedata->filename;
+ if (ptp_usb->device_flags & DEVICE_FLAG_ONLY_7BIT_FILENAMES) {
+ strip_7bit_from_utf8(new_file.Filename);
+ }
if (filedata->filesize == (uint64_t) -1) {
// This is a stream. Set a dummy length...
new_file.ObjectCompressedSize = 1;
@@ -4691,6 +4698,7 @@ LIBMTP_folder_t *LIBMTP_Get_Folder_List(LIBMTP_mtpdevice_t *device)
uint32_t LIBMTP_Create_Folder(LIBMTP_mtpdevice_t *device, char *name, uint32_t parent_id)
{
PTPParams *params = (PTPParams *) device->params;
+ PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo;
uint32_t parenthandle = 0;
uint32_t store = get_first_storageid(device);
PTPObjectInfo new_folder;
@@ -4699,6 +4707,9 @@ uint32_t LIBMTP_Create_Folder(LIBMTP_mtpdevice_t *device, char *name, uint32_t p
memset(&new_folder, 0, sizeof(new_folder));
new_folder.Filename = name;
+ if (ptp_usb->device_flags & DEVICE_FLAG_ONLY_7BIT_FILENAMES) {
+ strip_7bit_from_utf8(new_folder.Filename);
+ }
new_folder.ObjectCompressedSize = 1;
new_folder.ObjectFormat = PTP_OFC_Association;
new_folder.ParentObject = parent_id;
@@ -4935,6 +4946,7 @@ static int create_new_abstract_list(LIBMTP_mtpdevice_t *device,
uint32_t localph = parenthandle;
uint8_t nonconsumable = 0x00U; /* By default it is consumable */
PTPParams *params = (PTPParams *) device->params;
+ PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo;
char fname[256];
uint8_t data[2];
@@ -4991,6 +5003,9 @@ static int create_new_abstract_list(LIBMTP_mtpdevice_t *device,
prop->property = PTP_OPC_ObjectFileName;
prop->datatype = PTP_DTC_STR;
prop->propval.str = strdup(fname);
+ if (ptp_usb->device_flags & DEVICE_FLAG_ONLY_7BIT_FILENAMES) {
+ strip_7bit_from_utf8(prop->propval.str);
+ }
proplist = add_mtp_prop_to_proplist(proplist, prop);
break;
case PTP_OPC_ProtectionStatus:
@@ -5070,6 +5085,9 @@ static int create_new_abstract_list(LIBMTP_mtpdevice_t *device,
PTPObjectInfo new_object;
new_object.Filename = fname;
+ if (ptp_usb->device_flags & DEVICE_FLAG_ONLY_7BIT_FILENAMES) {
+ strip_7bit_from_utf8(new_object.Filename);
+ }
new_object.ObjectCompressedSize = 1;
new_object.ObjectFormat = objectformat;
diff --git a/src/libusb-glue.c b/src/libusb-glue.c
index 3565f1c..0d7af3e 100644
--- a/src/libusb-glue.c
+++ b/src/libusb-glue.c
@@ -162,7 +162,7 @@ static const LIBMTP_device_entry_t mtp_device_table[] = {
// From Gerhard Mekenkamp
{ "Philips GoGear Audio", 0x0471, 0x0165, DEVICE_FLAG_NONE },
// from David Holm <wormie@alberg.dk>
- { "Philips Shoqbox", 0x0471, 0x0172, DEVICE_FLAG_NONE },
+ { "Philips Shoqbox", 0x0471, 0x0172, DEVICE_FLAG_ONLY_7BIT_FILENAMES },
// from npedrosa
{ "Philips PSA610", 0x0471, 0x0181, DEVICE_FLAG_NONE },
// From libgphoto2 source
@@ -390,10 +390,12 @@ static const LIBMTP_device_entry_t mtp_device_table[] = {
* Cowon Systems, Inc.
* The iAudio audiophile devices don't encourage the use of MTP.
*/
+ // Reported by Patrik Johansson <Patrik.Johansson@qivalue.com>
+ {"Cowon iAudio U3 (MTP mode)", 0x0e21, 0x0701, DEVICE_FLAG_NONE },
// Reported by Roberth Karman
{"Cowon iAudio 7 (MTP mode)", 0x0e21, 0x0751, DEVICE_FLAG_NONE },
// Reported by TJ Something <tjbk_tjb@users.sourceforge.net>
- {"Cowon D2 (MTP mode)", 0x0e21, 0x0801, DEVICE_FLAG_NONE },
+ {"Cowon iAudio D2 (MTP mode)", 0x0e21, 0x0801, DEVICE_FLAG_NONE },
/*
* Insignia, dual-mode.
diff --git a/src/libusb-glue.h b/src/libusb-glue.h
index abf43c6..7a77d04 100644
--- a/src/libusb-glue.h
+++ b/src/libusb-glue.h
@@ -98,6 +98,15 @@
* filename extension will be done for files of "unknown" type.
*/
#define DEVICE_FLAG_IRIVER_OGG_ALZHEIMER 0x00000010
+/**
+ * This flag indicates a limitation in the filenames a device
+ * can accept - they must be 7 bit (all chars <= 127/0x7F).
+ * It was found first on the Philips Shoqbox, and is a deviation
+ * from the PTP standard which mandates that any unicode chars
+ * may be used for filenames. I guess this is caused by a 7bit-only
+ * filesystem being used intrinsically on the device.
+ */
+#define DEVICE_FLAG_ONLY_7BIT_FILENAMES 0x00000020
/**
* Internal USB struct.
diff --git a/src/unicode.c b/src/unicode.c
index 8b87c70..c1859ba 100644
--- a/src/unicode.c
+++ b/src/unicode.c
@@ -94,3 +94,33 @@ char *utf16_to_utf8(LIBMTP_mtpdevice_t *device, const uint16_t *unicstr)
}
return strdup(loclstr);
}
+
+/**
+ * This helper function simply removes any consecutive chars
+ * > 0x7F and replace then with an underscore. In UTF-8
+ * consequtive chars > 0x7F represent one single character so
+ * it has to be done like this (and it's elegant). It will only
+ * shrink the string in size so no copying is needed.
+ */
+void strip_7bit_from_utf8(char *str)
+{
+ int i,j,k;
+ i = 0;
+ j = 0;
+ k = strlen(str);
+ while (i < k) {
+ if ((uint8_t) str[i] > 0x7FU) {
+ str[j] = '_';
+ // Skip over any consequtive > 0x7F chars.
+ while((uint8_t) str[i] > 0x7FU) {
+ i++;
+ }
+ } else {
+ str[j] = str[i];
+ i++;
+ }
+ j++;
+ }
+ // Terminate stripped string...
+ str[j] = '\0';
+}
diff --git a/src/unicode.h b/src/unicode.h
index 1655c76..30e98ba 100644
--- a/src/unicode.h
+++ b/src/unicode.h
@@ -36,5 +36,6 @@
int ucs2_strlen(uint16_t const * const);
char *utf16_to_utf8(LIBMTP_mtpdevice_t*,const uint16_t*);
+void strip_7bit_from_utf8(char *str);
#endif /* __MTP__UNICODE__H */