[-]
[+]
|
Changed |
libmtp.spec
|
|
|
Added |
libmtp-0.2.6.1.tar.gz
^
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/AUTHORS
^
|
@@ -29,3 +29,4 @@
Sean Kellogg <skellogg@gmail.com>
Tero Saarni <tero.saarni@gmail.com>
Jeff Mitchell <kde-dev@emailgoeshere.com>
+Johannes Huber <johub1180@gmx.at>
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/ChangeLog
^
|
@@ -1,3 +1,327 @@
+2008-06-24 Linus Walleij <triad@df.lth.se>
+
+ * TODO: updates.
+ * src/Makefile.am: bump interface to libmtp.so.8.0.0.
+ It's NOT compatible!
+ * RELEASE libmtp 0.3.0 and let the apps developers have
+ their apps fixed!
+
+2008-06-22 Linus Walleij <triad@df.lth.se>
+
+ * src/libmtp.h.in: removed the parenthandle argument from
+ LIBMTP_Send_File_From_File(),
+ LIBMTP_Send_File_From_File_Descriptor(),
+ LIBMTP_Send_Track_From_File(),
+ LIBMTP_Send_Track_From_File_Descriptor(),
+ LIBMTP_Create_New_Playlist() and
+ LIBMTP_Create_New_Album()
+ Now you must pass in parent ID from a metadata or
+ filedata set. Use the respective field of the
+ file, track, playlist or album struct to pass in
+ a parent handle when calling these functions from
+ now on. The bonus for changing your code is that you
+ can now also pass in a storage_id with any metadata
+ set! Consequently LIBMTP_Create_Folder() was
+ altered to accept THREE metadata arguments: name,
+ parent_id and storage_id. All calls to any of these
+ functions in any referring code need to be altered to
+ use this scheme. It should be quite self-evident for
+ most code and easy to perform.
+ * src/libmtp.c: changed outlined above were implemented.
+ * examples/newfolder.c: consequental changes.
+ * examples/sendfile.c: consequental changes.
+ * examples/sendtr.c: consequental changes.
+ * examples/albumart.c: consequental changes.
+ * examples/newplaylist.c: consequental changes.
+ * examples/files.c: consequental changes.
+ * examples/tracks.c: correct misleading strings.
+
+2008-06-15 Linus Walleij <triad@df.lth.se>
+
+ * src/libmtp.c: only look for default folders in the
+ root folder on the primary storage, even.
+
+2008-06-14 Linus Walleij <triad@df.lth.se>
+
+ * src/libmtp.c: only look for default folders in the
+ primary storage, and only try to put files there
+ if they are targetting the primary storage.
+
+2008-06-08 Linus Walleij <triad@df.lth.se>
+
+ * configure.ac: check for the langinfo.h header.
+ * examples/connect.c: check charset properly.
+ * examples/sendtr.c: dito.
+ * src/music-players.h: new devices galore.
+
+2008-06-03 Linus Walleij <triad@df.lth.se>
+
+ * src/device-flags.h: new device flag for devices that
+ always need to have their device descriptor probed.
+ * src/music-players.h: generously add this flag to all
+ SanDisk devices. The e280v2 and Fuze are known to be
+ especially problematic.
+ * src/libusb-glue.h: helper macro.
+ * src/libusb-glue.c: massage "OS Descriptor" on demand
+ when opening the device.
+ * src/music-players.h: detailed info and flags for the
+ SanDisk Sansa players. More to be done, probably.
+
+2008-06-02 Linus Walleij <triad@df.lth.se>
+
+ * src/libusb-glue.c: refactor PTP_USB to use the raw
+ device and its contained deviceinfo to store and
+ retrieve the device flags. (This is starting to look
+ object oriented...)
+ * src/libusb-glue.h: accessor functions to simplify
+ switching on the device flags and increase the code
+ readability.
+ * src/libmtp.c: use the new accessor functions.
+
+2008-06-01 Linus Walleij <triad@df.lth.se>
+
+ * src/libmtp.c: use LIBMTP_Detect_Raw_Devices() and
+ LIBMTP_Open_Raw_Device() inside
+ LIBMTP_Get_First_Device() refactoring. Move
+ params creation into this file.
+ * src/libusb-glue.c: move params creation away
+ from here.
+
+2008-05-30 Linus Walleij <triad@df.lth.se>
+
+ * src/libusb-glue.c: unused variable.
+ * examples/detect.c: switch to using raw device
+ interface for opening devices.
+
+2008-05-28 Linus Walleij <triad@df.lth.se>
+
+ * src/libmtp.c: internally using the raw devices to
+ get a list of devices.
+ * src/ptp.c: sync to upstream.
+ * src/ptp.h: dito.
+ * src/ptp-pack.c: dito.
+ * src/libmtp.h.in: move raw device detection to use
+ error codes. Add interface to open a raw device!
+ * src/libusb-glue.h: make the old device list internal,
+ use raw device in interface for configuring USB.
+ * src/libusb-glue.c: fix up error messages. Move the
+ raw device detection interface to use error codes.
+ * examples/detect.c: fix up error messages. Use error
+ codes for raw devices.
+
+2008-05-23 Linus Walleij <triad@df.lth.se>
+
+ * src/libmtp.c: after sending a file, look up the
+ resulting file metadata from the cache to make sure
+ that parent_id is identical to that the file actually
+ gets on the device. If root folder (0) is selected, we
+ hardcode thing to 0xffffffffu to be used as parent,
+ but it will probably end up being 0 for example.
+ Also fix an issue with ptp_mtp_getobjectproplist()
+ sometimes returning a NULL pointer while still
+ claiming there are props in the list.
+ * src/libusb-glue.h: add a function to get the preferred
+ playlist extension.
+ * src/libusb-glue.c: "written" variable in
+ ptp_usb_sendreq() may end up uninitialized if
+ ptp_write_func() fails. Initialize it to 0.
+ Get the prefered playlist extension.
+
+2008-05-18 Richard Low <richard@wentnet.com>
+
+ * src/device-flags.h: added
+ DEVICE_FLAG_BROKEN_SET_SAMPLE_DIMENSIONS device flag
+ * src/music-players.h: ditto. Also set Samsung YH-999 to
+ DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL based on users
+ experience.
+ * src/libmtp.c: added
+ DEVICE_FLAG_BROKEN_SET_SAMPLE_DIMENSIONS device flag
+
+2008-05-05 Linus Walleij <triad@df.lth.se>
+
+ * src/libusb-glue.c: assign device name and flags to
+ detected raw devices, slowly preparing to move to
+ using the raw device detection internally as well.
+
+2008-05-04 Linus Walleij <triad@df.lth.se>
+
+ * src/libmtp.h.in: move useful filetype macros here so
+ external programs can use them.
+ * src/libmtp.c: consequental changes.
+ * examples/sendtr.c: use the new macro to detect track
+ content.
+
+2008-05-03 Johannes Huber <johub1180@gmx.at>
+
+ * src/libmtp.h.in: add interface for setting album composer,
+ needed for classical albums, on abstract albums.
+ * src/libmtp.c: implement it.
+ * examples/albums.c: consequental changes.
+ * examples/connect.c: dito.
+ * examples/sendtr.c: dito.
+ * examples/tracks.c: dito.
+ * AUTHORS: new contributor.
+
+2008-04-27 Linus Walleij <triad@df.lth.se>
+
+ * src/libmtp.c: recognize audio files as tracks, since this
+ is what WMP does. (e.g. it sets playlength on movies
+ to enable skip bar) also define macros for audio/video/both
+ types and tidy up a bit.
+
+2008-04-24 Linus Walleij <triad@df.lth.se>
+
+ * src/libmtp.h.in: added preliminary interface for getting
+ raw devices.
+ * src/libusb-glue.c: the implementation is all here!
+ * src/libusb-glue.h: add some bus and device fields to the
+ internal device list.
+ * examples/detect.c: exercise the raw device detection code.
+
+2008-03-26 Linus Walleij <triad@df.lth.se>
+
+ * examples/pathutils.c: fix a folder identification bug,
+ courtesy of Dr Nicholas Jacobs.
+
+2008-03-12 Linus Walleij <triad@df.lth.se>
+
+ * configure.ac: bad mailing list address. (Marcus) Bump to
+ version 0.3.0.
+ * examples/hotplug.c: switch from using "info.bus" to
+ using "info.subsystem" to identify USB events. (Marcus).
+ * src/libmtp.c: add parent_id to albums and playlists,
+ based on a patch by Ali Shah.
+ * src/libmtp.h.in: dito.
+ * examples/playlists.c: consequental changes.
+ * examples/albums.c: consequental changes.
+ * This will be a new major revision of the API/ABI no
+ matter what.
+
+2008-03-08 Linus Walleij <triad@df.lth.se>
+
+ * src/libusb-glue.c: left debug prints on :-(
+ * configure.ac: set to 0.2.6.1
+ * Release as 0.2.6.1
+
+2008-03-02 Linus Walleij <triad@df.lth.se>
+
+ * configure.ac: prepare 0.2.6 release.
+ * src/Makefile.am: bump to compatible interface,
+ * src/ptp.c: sync in upstream, a Sansa fix!
+ * src/ptp.h: sync in upstream.
+ * doc/Doxyfile.in: retire obsoleted parameters.
+ * Release this as 0.2.6!
+
+2008-02-24 Richard Low <richard@wentnet.com>
+
+ * src/music-players.h: add DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL
+ for a broken Philips player.
+
+2008-02-18 Linus Walleij <triad@df.lth.se>
+
+ * examples/pathutils.c: fix up item ID typing to uint32_t,
+ handle file names passed in as arguments at suggestion from
+ anonymous mail list user.
+ * examples/pathutils.h: move a function static.
+
+2008-02-12 Nicolas Pennequin <nicolas.pennequin@free.fr>
+
+ * examples/sendtr.c: add transferred tracks to albums if possible.
+
+2008-02-10 Scott Snyder <snyder@fnal.gov>
+
+ * src/libusb-glue.c: finally fix up the short header detection
+ to skip over zero packets when encountered.
+ * examples/pathutils.c: fix a problem where all files sent has
+ to include a "." (period).
+
+2008-02-06 Linus Walleij <triad@df.lth.se>
+
+ * src/libusb-glue.c: wait for response > 0 instead of > 2.
+
+2008-01-28 Linus Walleij <triad@df.lth.se>
+
+ * src/libmtp.c: LIBMTP_Get_Filemetadata() return metadata for
+ folders (associations) too. There is really no reason why it
+ shouldn't and it's good for use internally.
+ LIBMTP_Get_Filelisting_With_Callback() will still not return
+ any associations however. We want to use the folder functions
+ for that.
+
+2008-01-28 Linus Walleij <triad@df.lth.se>
+
+ * src/libmtp.h.in: withdraw LIBMTP_Set_Object_Parent() function,
+ no known devices will support this.
+ * src/libmtp.c: dito. Fix up some problems with the
+ LIBMTP_Set_Object_Filename() function.
+
+2008-01-27 Linus Walleij <triad@df.lth.se>
+
+ * src/libmtp.c: fix up some minor things and documentation on
+ the object handling functions.
+
+2008-01-27 Florent Mertens <flomertens@gmail.com>
+
+ * src/libmtp.h.in: new functions to rename object filenames
+ and change object parents. Good when modifying the device
+ as a file system, LIBMTP_Set_Object_Filename(),
+ LIBMTP_Set_Object_Parent().
+ * src/libmtp.c: implementation.
+
+2008-01-27 Linus Walleij <triad@df.lth.se>
+
+ * src/libusb-glue.c: re-read response from device until
+ it atleast exceeds two bytes. This fixes a problem with
+ the Samsung YP-U3 when populated with many, many songs.
+
+2008-01-21 Richard Low <richard@wentnet.com>
+
+ * src/music-players.h: add Thomson Lyrca HC308A, remove
+ incorrect ID for Creative Zen 8GB
+
+2008-01-20 Richard Low <richard@wentnet.com>
+
+ * src/libmtp.c: add LIBMTP_Get_Representative_Sample()
+ * src/libmtp.h.in: ditto
+
+2008-01-14 Linus Walleij <triad@df.lth.se>
+
+ * src/libmtp.c: add LIBMTP_Get_Manufacturername(). Remember
+ to bump soname (compatible) in 0.2.6 (or whatever we name it).
+ 0.3.0 perhaps?
+ * src/libmtp.h.in: dito.
+ * src/libmtp.c: detect default folders named "Datacasts" and
+ "Texts".
+
+2008-01-11 Linus Walleij <triad@df.lth.se>
+
+ * examples/pathutils.c: recognize .bin files as firmware,
+ used by e.g. RockBox developers. Doesn't cost anything to
+ add.
+
+2008-01-08 Linus Walleij <triad@df.lth.se>
+
+ * configure.ac: bump to 0.2.5.
+ * src/Makefile.am: interface to libmtp.so.7.0.2
+ (compatible).
+ * Release as libmtp 0.2.5. Why not?
+
+2007-12-28 Linus Walleij <triad@df.lth.se>
+
+ * src/libmtp.c: make libmtp use PTP_OPC_AlbumArtist on albums,
+ instead of the (seldom present) PTP_OPC_Artist tag. Use both
+ if both are supported. We're not setting AlbumArtist on regular
+ tracks though, what's the point, and what does it mean if this
+ differs from Artist??
+
+2007-11-30 Linus Walleij <triad@df.lth.se>
+
+ * src/music-players.h: new flag for the YP-T10.
+ * src/device-flags.h: define the new flag, that is needed
+ to support Ogg files on these devices.
+ * src/libmtp.c: recognize and report Ogg support, set type
+ to unknown when transferring.
+
2007-11-22 Linus Walleij <triad@df.lth.se>
* configure.ac: bump to 0.2.4.
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/Makefile.in
^
|
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -364,8 +364,8 @@
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
@@ -390,8 +390,8 @@
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -401,13 +401,12 @@
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
- here=`pwd`; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
@@ -478,6 +477,10 @@
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
$(am__remove_distdir)
+dist-lzma: distdir
+ tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+ $(am__remove_distdir)
+
dist-tarZ: distdir
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__remove_distdir)
@@ -504,6 +507,8 @@
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lzma*) \
+ unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
@@ -659,8 +664,8 @@
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
all all-am am--refresh check check-am clean clean-generic \
clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \
- dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \
- distclean-generic distclean-hdr distclean-libtool \
+ dist-gzip dist-lzma dist-shar dist-tarZ dist-zip distcheck \
+ distclean distclean-generic distclean-hdr distclean-libtool \
distclean-tags distcleancheck distdir distuninstallcheck dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/README
^
|
@@ -243,7 +243,7 @@
at the USB mass storage interface AGAIN because it
enumerates.)
-Try this, if you have a recent 2.6.x Linux kernel,
+Linux: Try this, if you have a recent 2.6.x Linux kernel,
run (as root) something like:
> rmmod usb_storage ; mtp-detect
@@ -277,6 +277,25 @@
the device is already configured for USB mass storage when
udev is called.
+On Mac OS there is another ugly hack:
+
+1. Open up a terminal window
+2. Type:
+sudo mv /System/Library/Extensions/IOUSBMassStorageClass.kext
+/System/Library/Extensions/IOUSBMassStorageClass.kext.disabled
+
+and when prompted enter your password.
+
+3. Restart.
+
+To reverse this change, just reverse the filenames:
+
+sudo mv /System/Library/Extensions/
+IOUSBMassStorageClass.kext.disabled /System/Library/Extensions/
+IOUSBMassStorageClass.kext
+
+and restart.
+
Calendar and contact support:
-----------------------------
@@ -323,6 +342,46 @@
these whenever we can, sometimes we cannot work around it or we
cannot test your solution.
+* Generic MTP/PTP disconnect misbehaviour: we have noticed that
+ Windows Media Player apparently never close the session to an MTP
+ device. There is a daemon in Windows that "hooks" the device
+ by opening a PTP session to any MTP device, whenever it is
+ plugged in. This daemon proxies any subsequent transactions
+ to/from the device and will never close the session, thus
+ Windows simply does not close sessions at all.
+
+ This means that device manufacturers doesn't notice any problems
+ with devices that do not correctly handle closing PTP/MTP
+ sessions, since Windows never do it. The proper way of closing
+ a session in Windows is to unplug the device, simply put.
+
+ Since libmtp actually tries to close sessions, some devices
+ may fail since the close session functionality has never been
+ properly tested, and "it works with Windows" is sort of the
+ testing criteria at some companies.
+
+ You can get Windows-like behaviour on Linux by running a HAL-aware
+ libmtp GUI client like Rhythmbox or Gnomad2, which will "hook"
+ the device when you plug it in, and "release" it if you unplug
+ it.
+
+ If this bug in your device annoys you, contact your device
+ manufacturer and ask them to test their product with some libmtp
+ program.
+
+* Generic USB misbehaviour: some devices behave badly under MTP
+ and USB mass storage alike, even down to the lowest layers
+ of USB. You can always discuss such issues at the linux-usb
+ mailing list if you're using Linux:
+ http://www.linux-usb.org/mailing.html
+
+ If you have a problem specific to USB mass storage mode, there
+ is a list of strange behaving devices in the Linux kernel:
+ http://lxr.linux.no/linux/drivers/usb/storage/unusual_devs.h
+ You can discuss this too on the mentioned list, for understanding
+ the quirks, see:
+ http://www2.one-eyed-alien.net/~mdharm/linux-usb/target_offenses.txt
+
* The Zen Vision:M (possibly more Creative Zens) has a firmware bug
that makes it drop the last two characters off a playlist name.
It is fixed in later firmware.
@@ -362,6 +421,13 @@
problematic. Please upgrade to as new firmware as you can get.
(Yes this requires some kind of Windows Installation I think.)
+* Philips HDD 1630/16 or 1630/17 etc may lock themselves up,
+ turning inresponsive due to internal corruption. This typically
+ gives an error in opening the PTP session. Apparently you can
+ do a "repair" with the firmware utility (Windows only) which
+ will often fix this problem and make the device responsive
+ again.
+
* Some devices that implement GetObjectPropList (0x9805) will
not return the entire object list if you request a list for object
0xffffffffu. (But they should.) So they may need the special
@@ -378,6 +444,14 @@
an abstract album (created with the album interface) with
the exact same name.
+* The Zen Vision:M has an older firmware which is very corrupt,
+ it is incompatible with the Linux USB stack altogether. The
+ kernel dmesg will look something like this, and you have to
+ upgrade the firmware using Windows:
+ usb 4-5: new high speed USB device using ehci_hcd and address 5
+ usb 4-5: configuration #1 chosen from 1 choice
+ usb 4-5: can't set config #1, error -110
+
Lost symbols
------------
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/TODO
^
|
@@ -11,7 +11,9 @@
the Windows kernel driver apparently does it the other way around,
trying the MTP mode first and then not fall back on mass storage if
MTP is available. (For some more explanations se src/libusb-glue.h.)
- This may involve kernel modifications.
+ This may involve kernel modifications. Perhaps it is only necessary
+ to tweak the udev config not to load USB mass storage support for
+ these devices. Dunno.
2. COMPATIBILITY: several devices tend to "hang" after disconnect,
needing to be unplugged and replugged before they can be used again.
@@ -20,20 +22,15 @@
avoiding to release the USB interface after closing the PTP/MTP
session solves this, and might be a hint at how the Windows MTP stack
works: perhaps the Windows MTP daemon grabs the interface once the
- device is plugged in and NEVER release it. (Though it opens new
- sessions PTP/MTP sessions.) This behaviour can be emulated by
- DEVICE_FLAG_NO_RELEASE_INTERFACE but is it really desireable to have
+ device is plugged in, created a session and NEVER release it.
+ Thus only unplug or shutdown ends the session. This behaviour can be
+ emulated (sort of) by DEVICE_FLAG_NO_RELEASE_INTERFACE which will
+ make the device not release the USB low-level interface, though it'll
+ still close the session. But is it really desireable to have
as default? Not unless we run an MTP daemon as well, probably, and
the behaviour is questionable from an USB interoperability point
of view.
-3. COMPATIBILITY: get rid of the remaning "unknown OPFF type" warnings,
- we have seen OPFF 0x04 (PTP_OPFF_FixedLengthArray) and 0x06
- (PTP_OPFF_ByteArray) in the wild but we haven implemented anything
- but 0x01 (PTP_OPFF_Range) and 0x02 (PTP_OPFF_Enumeration). 0x01
- and 0x02 are the only types used by PTP for device property field
- formats.
-
SPEEDUP fixes:
@@ -50,23 +47,19 @@
2. FEATURE: Support relevant events. MTP devices seen in existance provide
events for "object added" and "object deleted". These should result in
- atleast a call to the flus_handles() function.
-
-3. FEATURE: Have libmtp "sendtr" sample optionally create a folder
- hierarchy such as /Album/Artist/Song.mp3 on the device. Currently
- it'll only put songs into some /Music or /My Music folder if one exists.
+ atleast a call to the cache update function.
-4. FEATURE: Mechanism to retrieve the device icon device property, else if not
+3. FEATURE: Mechanism to retrieve the device icon device property, else if not
present, look for DevIcon.fil (Windows ICO format) and
DevLogo.fil (PNG Format) images from the device (if available).
-5. FEATURE: Shared device access so that multiple client applications can have
+4. FEATURE: Shared device access so that multiple client applications can have
an open connection to the device at the same time via a handle. For example,
it should be somehow possible to run mtp-detect at the same time as amarok or
mtpfs is connected to a device. This would require some form of resource
sharing.
-6. FEATURE: Implement an OpenSync backend for devices which have
+5. FEATURE: Implement an OpenSync backend for devices which have
calendaring, contact etc support. http://opensync.org/
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/aclocal.m4
^
|
@@ -1,7 +1,7 @@
-# generated automatically by aclocal 1.10 -*- Autoconf -*-
+# generated automatically by aclocal 1.10.1 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006 Free Software Foundation, Inc.
+# 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -11,10 +11,13 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
-m4_if(m4_PACKAGE_VERSION, [2.61],,
-[m4_fatal([this file was generated for autoconf 2.61.
-You have another version of autoconf. If you want to use that,
-you should regenerate the build system entirely.], [63])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(AC_AUTOCONF_VERSION, [2.61],,
+[m4_warning([this file was generated for autoconf 2.61.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
@@ -6584,7 +6587,7 @@
AC_MSG_RESULT([$SED])
])
-# Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
+# Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -6599,7 +6602,7 @@
[am__api_version='1.10'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.10], [],
+m4_if([$1], [1.10.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -6615,8 +6618,10 @@
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.10])dnl
-_AM_AUTOCONF_VERSION(m4_PACKAGE_VERSION)])
+[AM_AUTOMAKE_VERSION([1.10.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(AC_AUTOCONF_VERSION)])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
@@ -6888,7 +6893,7 @@
# each Makefile.in and add a new line on top of each file to say so.
# Grep'ing the whole file is not good either: AIX grep has a line
# limit of 2048, but all sed's we know have understand at least 4000.
- if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
dirpart=`AS_DIRNAME("$mf")`
else
continue
@@ -6948,13 +6953,13 @@
# Do all the work for Automake. -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006 Free Software Foundation, Inc.
+# 2005, 2006, 2008 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 12
+# serial 13
# This macro actually does too much. Some checks are only needed if
# your package does certain things. But this isn't really a big deal.
@@ -7059,16 +7064,17 @@
# our stamp files there.
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
[# Compute $1's index in $config_headers.
+_am_arg=$1
_am_stamp_count=1
for _am_header in $config_headers :; do
case $_am_header in
- $1 | $1:* )
+ $_am_arg | $_am_arg:* )
break ;;
* )
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
esac
done
-echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
#
@@ -7340,7 +7346,7 @@
# _AM_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
-# Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in.
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
# This macro is traced by Automake.
AC_DEFUN([_AM_SUBST_NOTMAKE])
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/config.guess
^
|
@@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
-timestamp='2007-11-19'
+timestamp='2008-01-23'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -56,8 +56,8 @@
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -532,7 +532,7 @@
echo rs6000-ibm-aix3.2
fi
exit ;;
- *:AIX:*:[45])
+ *:AIX:*:[456])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@@ -799,6 +799,9 @@
EM64T | authenticamd)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
@@ -833,7 +836,14 @@
echo ${UNAME_MACHINE}-pc-minix
exit ;;
arm*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
@@ -1474,9 +1484,9 @@
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
and
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/config.h.in
^
|
@@ -24,6 +24,9 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
+/* Define to 1 if you have the <langinfo.h> header file. */
+#undef HAVE_LANGINFO_H
+
/* Define to 1 if you have the <libgen.h> header file. */
#undef HAVE_LIBGEN_H
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/config.sub
^
|
@@ -1,10 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
-timestamp='2007-11-19'
+timestamp='2008-01-16'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -72,8 +72,8 @@
version="\
GNU config.sub ($timestamp)
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -447,6 +447,14 @@
basic_machine=ns32k-sequent
os=-dynix
;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
c90)
basic_machine=c90-cray
os=-unicos
@@ -672,6 +680,14 @@
basic_machine=m68k-isi
os=-sysv
;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
m88k-omron*)
basic_machine=m88k-omron
;;
@@ -817,6 +833,14 @@
basic_machine=i860-intel
os=-osf
;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
pbd)
basic_machine=sparc-tti
;;
@@ -1025,6 +1049,10 @@
basic_machine=tic6x-unknown
os=-coff
;;
+ tile*)
+ basic_machine=tile-unknown
+ os=-linux-gnu
+ ;;
tx39)
basic_machine=mipstx39-unknown
;;
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/configure
^
|
@@ -1,8 +1,8 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for libmtp 0.2.4.
+# Generated by GNU Autoconf 2.61 for libmtp 0.3.0.
#
-# Report bugs to <libmtp-users@lists.sourceforge.net>.
+# Report bugs to <libmtp-discuss@lists.sourceforge.net>.
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
@@ -728,9 +728,9 @@
# Identity of this package.
PACKAGE_NAME='libmtp'
PACKAGE_TARNAME='libmtp'
-PACKAGE_VERSION='0.2.4'
-PACKAGE_STRING='libmtp 0.2.4'
-PACKAGE_BUGREPORT='libmtp-users@lists.sourceforge.net'
+PACKAGE_VERSION='0.3.0'
+PACKAGE_STRING='libmtp 0.3.0'
+PACKAGE_BUGREPORT='libmtp-discuss@lists.sourceforge.net'
ac_unique_file="src/libmtp.c"
# Factoring default headers for most tests.
@@ -1401,7 +1401,7 @@
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures libmtp 0.2.4 to adapt to many kinds of systems.
+\`configure' configures libmtp 0.3.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1471,7 +1471,7 @@
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of libmtp 0.2.4:";;
+ short | recursive ) echo "Configuration of libmtp 0.3.0:";;
esac
cat <<\_ACEOF
@@ -1512,7 +1512,7 @@
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
-Report bugs to <libmtp-users@lists.sourceforge.net>.
+Report bugs to <libmtp-discuss@lists.sourceforge.net>.
_ACEOF
ac_status=$?
fi
@@ -1573,7 +1573,7 @@
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-libmtp configure 0.2.4
+libmtp configure 0.3.0
generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1587,7 +1587,7 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by libmtp $as_me 0.2.4, which was
+It was created by libmtp $as_me 0.3.0, which was
generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@
@@ -2277,7 +2277,7 @@
# Define the identity of the package.
PACKAGE='libmtp'
- VERSION='0.2.4'
+ VERSION='0.3.0'
cat >>confdefs.h <<_ACEOF
@@ -5481,9 +5481,9 @@
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
( cat <<\_ASBOX
-## ------------------------------------------------- ##
-## Report this to libmtp-users@lists.sourceforge.net ##
-## ------------------------------------------------- ##
+## --------------------------------------------------- ##
+## Report this to libmtp-discuss@lists.sourceforge.net ##
+## --------------------------------------------------- ##
_ASBOX
) | sed "s/^/$as_me: WARNING: /" >&2
;;
@@ -20141,8 +20141,10 @@
+
for ac_header in ctype.h errno.h fcntl.h getopt.h libgen.h \
- limits.h stdio.h string.h sys/stat.h sys/time.h unistd.h iconv.h
+ limits.h stdio.h string.h sys/stat.h sys/time.h unistd.h \
+ iconv.h langinfo.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
@@ -20258,9 +20260,9 @@
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
( cat <<\_ASBOX
-## ------------------------------------------------- ##
-## Report this to libmtp-users@lists.sourceforge.net ##
-## ------------------------------------------------- ##
+## --------------------------------------------------- ##
+## Report this to libmtp-discuss@lists.sourceforge.net ##
+## --------------------------------------------------- ##
_ASBOX
) | sed "s/^/$as_me: WARNING: /" >&2
;;
@@ -20398,9 +20400,9 @@
{ echo "$as_me:$LINENO: WARNING: usb.h: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: usb.h: in the future, the compiler will take precedence" >&2;}
( cat <<\_ASBOX
-## ------------------------------------------------- ##
-## Report this to libmtp-users@lists.sourceforge.net ##
-## ------------------------------------------------- ##
+## --------------------------------------------------- ##
+## Report this to libmtp-discuss@lists.sourceforge.net ##
+## --------------------------------------------------- ##
_ASBOX
) | sed "s/^/$as_me: WARNING: /" >&2
;;
@@ -20948,9 +20950,9 @@
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
( cat <<\_ASBOX
-## ------------------------------------------------- ##
-## Report this to libmtp-users@lists.sourceforge.net ##
-## ------------------------------------------------- ##
+## --------------------------------------------------- ##
+## Report this to libmtp-discuss@lists.sourceforge.net ##
+## --------------------------------------------------- ##
_ASBOX
) | sed "s/^/$as_me: WARNING: /" >&2
;;
@@ -22856,7 +22858,7 @@
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by libmtp $as_me 0.2.4, which was
+This file was extended by libmtp $as_me 0.3.0, which was
generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -22909,7 +22911,7 @@
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-libmtp config.status 0.2.4
+libmtp config.status 0.3.0
configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
@@ -23654,21 +23656,22 @@
fi
rm -f "$tmp/out12"
# Compute $ac_file's index in $config_headers.
+_am_arg=$ac_file
_am_stamp_count=1
for _am_header in $config_headers :; do
case $_am_header in
- $ac_file | $ac_file:* )
+ $_am_arg | $_am_arg:* )
break ;;
* )
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
esac
done
-echo "timestamp for $ac_file" >`$as_dirname -- $ac_file ||
-$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X$ac_file : 'X\(//\)[^/]' \| \
- X$ac_file : 'X\(//\)$' \| \
- X$ac_file : 'X\(/\)' \| . 2>/dev/null ||
-echo X$ac_file |
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$_am_arg" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
@@ -23705,7 +23708,7 @@
# each Makefile.in and add a new line on top of each file to say so.
# Grep'ing the whole file is not good either: AIX grep has a line
# limit of 2048, but all sed's we know have understand at least 4000.
- if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
dirpart=`$as_dirname -- "$mf" ||
$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$mf" : 'X\(//\)[^/]' \| \
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/configure.ac
^
|
@@ -1,6 +1,6 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.52)
-AC_INIT([libmtp], [0.2.4], [libmtp-users@lists.sourceforge.net])
+AC_INIT([libmtp], [0.3.0], [libmtp-discuss@lists.sourceforge.net])
AM_INIT_AUTOMAKE([foreign])
AC_CONFIG_SRCDIR([src/libmtp.c])
AM_CONFIG_HEADER(config.h)
@@ -60,7 +60,8 @@
AC_HEADER_TIME
# zlib.h the day we need to decompress firmware
AC_CHECK_HEADERS([ctype.h errno.h fcntl.h getopt.h libgen.h \
- limits.h stdio.h string.h sys/stat.h sys/time.h unistd.h iconv.h])
+ limits.h stdio.h string.h sys/stat.h sys/time.h unistd.h \
+ iconv.h langinfo.h])
AC_CHECK_HEADER([usb.h],,
AC_MSG_ERROR([I can't find the libusb header file on your system.
You may need to set the CPPFLAGS environment variable to include
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/depcomp
^
|
@@ -1,9 +1,9 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
-scriptversion=2006-10-15.18
+scriptversion=2007-03-29.01
-# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software
# Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
@@ -215,34 +215,39 @@
# current directory. Also, the AIX compiler puts `$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
- stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
- tmpdepfile="$stripped.u"
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$base.u
+ tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$dir$base.u
+ tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
- if test -f "$tmpdepfile"; then :
- else
- stripped=`echo "$stripped" | sed 's,^.*/,,'`
- tmpdepfile="$stripped.u"
- fi
-
if test $stat -eq 0; then :
else
- rm -f "$tmpdepfile"
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
if test -f "$tmpdepfile"; then
- outname="$stripped.o"
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
- sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
- sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/doc/Doxyfile.in
^
|
@@ -54,16 +54,6 @@
OUTPUT_LANGUAGE = English
-# This tag can be used to specify the encoding used in the generated output.
-# The encoding is not always determined by the language that is chosen,
-# but also whether or not the output is meant for Windows or non-Windows users.
-# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
-# forces the Windows encoding (this is the default for the Windows binary),
-# whereas setting the tag to NO uses a Unix-style encoding (the default for
-# all platforms other than Windows).
-
-USE_WINDOWS_ENCODING = NO
-
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar to JavaDoc).
@@ -1120,22 +1110,6 @@
DOTFILE_DIRS =
-# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
-# large images.
-
-MAX_DOT_GRAPH_WIDTH = 1024
-
-# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
-# large images.
-
-MAX_DOT_GRAPH_HEIGHT = 1024
-
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
# graphs generated by dot. A depth value of 3 means that only nodes reachable
# from the root by following a path via at most 3 edges will be shown. Nodes that
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/doc/Makefile.in
^
|
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/examples/Makefile.in
^
|
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -117,7 +117,7 @@
trexist_OBJECTS = $(am_trexist_OBJECTS)
trexist_LDADD = $(LDADD)
trexist_DEPENDENCIES = ../src/libmtp.la
-DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -319,8 +319,8 @@
|| test -f $$p1 \
; then \
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
- echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
- $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
else :; fi; \
done
@@ -448,8 +448,8 @@
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
@@ -461,8 +461,8 @@
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -472,13 +472,12 @@
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
- here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/examples/albumart.c
^
|
@@ -125,7 +125,9 @@
album->name = albumname;
album->no_tracks = idcount;
album->tracks = ids;
- int ret = LIBMTP_Create_New_Album(device,album,0);
+ album->parent_id = 0;
+ album->storage_id = 0;
+ int ret = LIBMTP_Create_New_Album(device,album);
if (ret == 0) {
ret = LIBMTP_Send_Representative_Sample(device,album->album_id, albumart);
if (ret != 0) {
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/examples/albums.c
^
|
@@ -25,10 +25,12 @@
static void dump_albuminfo(LIBMTP_album_t *album)
{
printf("Album ID: %d\n",album->album_id);
+ printf(" Parent ID: %d\n",album->parent_id);
printf(" Name: %s\n",album->name);
printf(" Artist: %s\n", album->artist);
+ printf(" Composer: %s\n", album->composer);
printf(" Genre: %s\n", album->genre);
- printf(" Tracks: %d\n\n",album->no_tracks);
+ printf(" Tracks: %d\n\n",album->no_tracks);
}
int main () {
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/examples/connect.c
^
|
@@ -3,6 +3,7 @@
* Main programs implementing several utilities in one.
*
* Copyright (C) 2006 Chris A. Debenham <chris@adebenham.com>
+ * Copyright (C) 2008 Linus Walleij <triad@df.lth.se>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -24,6 +25,9 @@
#include "common.h"
#include "string.h"
#include "pathutils.h"
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
LIBMTP_folder_t *folders;
LIBMTP_file_t *files;
@@ -34,7 +38,7 @@
void delfile_function(char *);
void delfile_command(int, char **);
void delfile_usage(void);
-int sendtrack_function(char *, char *, char *, char *, char *, char *, uint16_t, uint16_t, uint16_t);
+int sendtrack_function(char *, char *, char *, char *, char *, char *, char *, char *, uint16_t, uint16_t, uint16_t);
void sendtrack_command (int, char **);
void sendtrack_usage(void);
void sendfile_function(char *,char *);
@@ -71,29 +75,39 @@
printf(" --newfolder [foldername]\n");
}
-int main (int argc, char **argv)
+static void checklang(void)
{
- if ( argc < 2 ) {
- usage ();
- return 1;
- }
+ char *langsuff = NULL;
+ char *lang = getenv("LANG");
+#ifdef HAVE_LANGINFO_H
+ langsuff = nl_langinfo(CODESET);
+#else
/*
* Check environment variables $LANG and $LC_CTYPE
* to see if we want to support UTF-8 unicode
*/
- char * lang = getenv("LANG");
if (lang != NULL) {
if (strlen(lang) > 5) {
- char *langsuff = &lang[strlen(lang)-5];
- if (strcmp(langsuff, "UTF-8")) {
- printf("Your system does not appear to have UTF-8 enabled ($LANG=\"%s\")\n", lang);
- printf("If you want to have support for diacritics and Unicode characters,\n");
- printf("please switch your locale to an UTF-8 locale, e.g. \"en_US.UTF-8\".\n");
- }
+ langsuff = &lang[strlen(lang)-5];
}
}
+#endif
+ if (strcmp(langsuff, "UTF-8")) {
+ printf("Your system does not appear to have UTF-8 enabled ($LANG=\"%s\")\n", lang);
+ printf("If you want to have support for diacritics and Unicode characters,\n");
+ printf("please switch your locale to an UTF-8 locale, e.g. \"en_US.UTF-8\".\n");
+ }
+}
+
+int main (int argc, char **argv)
+{
+ if ( argc < 2 ) {
+ usage ();
+ return 1;
+ }
+ checklang();
LIBMTP_Init();
@@ -160,7 +174,7 @@
case 't':
printf("Send track %s\n",optarg);
split_arg(optarg,&arg1,&arg2);
- sendtrack_function(arg1,arg2,NULL,NULL,NULL,NULL,0,0,0);
+ sendtrack_function(arg1,arg2,NULL,NULL,NULL,NULL,NULL,NULL,0,0,0);
break;
}
}
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/examples/delfile.c
^
|
@@ -2,7 +2,7 @@
* \file delfile.c
* Example program to delete a file off the device.
*
- * Copyright (C) 2005-2007 Linus Walleij <triad@df.lth.se>
+ * Copyright (C) 2005-2008 Linus Walleij <triad@df.lth.se>
* Copyright (C) 2006 Chris A. Debenham <chris@adebenham.com>
*
* This library is free software; you can redistribute it and/or
@@ -40,7 +40,8 @@
void
delfile_function(char * path)
{
- int id = parse_path (path,files,folders);
+ uint32_t id = parse_path (path,files,folders);
+
if (id > 0) {
printf("Deleting %s which has item_id:%d\n",path,id);
int ret = 1;
@@ -58,6 +59,8 @@
int FILENAME = 1;
int ITEMID = 2;
int field_type = 0;
+ int i;
+
if ( argc > 2 ) {
if (strncmp(argv[1],"-f",2) == 0) {
field_type = FILENAME;
@@ -73,10 +76,12 @@
delfile_usage();
return;
}
- int i;
+
for (i=1;i<argc;i++) {
- int id;
+ uint32_t id;
char *endptr;
+ int ret = 0;
+
if (field_type == ITEMID) {
// Sanity check song ID
id = strtoul(argv[i], &endptr, 10);
@@ -91,7 +96,6 @@
id = 0;
}
}
- int ret = 0;
if (id > 0 ) {
printf("Deleting %s\n",argv[i]);
ret = LIBMTP_Delete_Object(device, id);
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/examples/detect.c
^
|
@@ -2,7 +2,7 @@
* \file detect.c
* Example program to detect a device and list capabilities.
*
- * Copyright (C) 2005-2007 Linus Walleij <triad@df.lth.se>
+ * Copyright (C) 2005-2008 Linus Walleij <triad@df.lth.se>
* Copyright (C) 2007 Ted Bullock <tbullock@canada.com>
*
* This library is free software; you can redistribute it and/or
@@ -58,30 +58,20 @@
int main (int argc, char **argv)
{
- LIBMTP_mtpdevice_t *device, *iter;
- LIBMTP_file_t *files;
- uint32_t xmlfileid = 0;
- char *friendlyname;
- char *syncpartner;
- char *sectime;
- char *devcert;
- uint16_t *filetypes;
- uint16_t filetypes_len;
- uint8_t maxbattlevel;
- uint8_t currbattlevel;
- uint32_t numdevices;
- int ret;
- int probeonly = 0;
+ LIBMTP_raw_device_t * rawdevices;
+ int numrawdevices;
+ LIBMTP_error_number_t err;
+ int i;
LIBMTP_Init();
fprintf(stdout, "libmtp version: " LIBMTP_VERSION_STRING "\n\n");
- fprintf(stdout, "Attempting to connect device(s)\n");
- switch(LIBMTP_Get_Connected_Devices(&device))
- {
+ fprintf(stdout, "Listing raw device(s)\n");
+ err = LIBMTP_Detect_Raw_Devices(&rawdevices, &numrawdevices);
+ switch(err) {
case LIBMTP_ERROR_NO_DEVICE_ATTACHED:
- fprintf(stdout, "Detect: No Devices have been found\n");
+ fprintf(stdout, " No raw devices found.\n");
return 0;
case LIBMTP_ERROR_CONNECTING:
fprintf(stderr, "Detect: There has been an error connecting. Exiting\n");
@@ -89,164 +79,191 @@
case LIBMTP_ERROR_MEMORY_ALLOCATION:
fprintf(stderr, "Detect: Encountered a Memory Allocation Error. Exiting\n");
return 1;
-
- /* Unknown general errors - This should never execute */
+ case LIBMTP_ERROR_NONE:
+ {
+ int i;
+
+ fprintf(stdout, " Found %d device(s):\n", numrawdevices);
+ for (i = 0; i < numrawdevices; i++) {
+ if (rawdevices[i].device_entry.vendor != NULL ||
+ rawdevices[i].device_entry.product != NULL) {
+ fprintf(stdout, " %s: %s (%04x:%04x) @ bus %d, dev %d\n",
+ rawdevices[i].device_entry.vendor,
+ rawdevices[i].device_entry.product,
+ rawdevices[i].device_entry.vendor_id,
+ rawdevices[i].device_entry.product_id,
+ rawdevices[i].bus_location,
+ rawdevices[i].devnum);
+ } else {
+ fprintf(stdout, " %04x:%04x @ bus %d, dev %d\n",
+ rawdevices[i].device_entry.vendor_id,
+ rawdevices[i].device_entry.product_id,
+ rawdevices[i].bus_location,
+ rawdevices[i].devnum);
+ }
+ }
+ }
+ break;
case LIBMTP_ERROR_GENERAL:
default:
- fprintf(stderr, "Detect: There has been an unknown error, please report "
- "this to the libmtp developers\n");
- return 1;
-
- /* Successfully connected at least one device, so continue */
- case LIBMTP_ERROR_NONE:
- numdevices = LIBMTP_Number_Devices_In_List(device);
- fprintf(stdout, "Detect: Successfully connected %u devices\n", numdevices);
- }
-
- /* iterate through connected MTP devices */
- for(iter = device; iter != NULL; iter = iter->next)
- {
-
- LIBMTP_Dump_Errorstack(iter);
- LIBMTP_Clear_Errorstack(iter);
- LIBMTP_Dump_Device_Info(iter);
-
- printf("MTP-specific device properties:\n");
- // The friendly name
- friendlyname = LIBMTP_Get_Friendlyname(iter);
- if (friendlyname == NULL) {
- fprintf(stdout, " Friendly name: (NULL)\n");
- } else {
- fprintf(stdout, " Friendly name: %s\n", friendlyname);
- free(friendlyname);
- }
- syncpartner = LIBMTP_Get_Syncpartner(iter);
- if (syncpartner == NULL) {
- fprintf(stdout, " Synchronization partner: (NULL)\n");
- } else {
- fprintf(stdout, " Synchronization partner: %s\n", syncpartner);
- free(syncpartner);
+ fprintf(stderr, "Unknown connection error.\n");
+ return 1;
}
- // Some battery info
- ret = LIBMTP_Get_Batterylevel(iter, &maxbattlevel, &currbattlevel);
- if (ret == 0) {
- fprintf(stdout, " Battery level %d of %d (%d%%)\n",currbattlevel, maxbattlevel,
- (int) ((float) currbattlevel/ (float) maxbattlevel * 100.0));
- } else {
- // Silently ignore. Some devices does not support getting the
- // battery level.
- LIBMTP_Clear_Errorstack(iter);
- }
+ /* Iterate over connected MTP devices */
+ fprintf(stdout, "Attempting to connect device(s)\n");
+ for (i = 0; i < numrawdevices; i++) {
+ LIBMTP_mtpdevice_t *device;
+ LIBMTP_file_t *files;
+ uint32_t xmlfileid = 0;
+ char *friendlyname;
+ char *syncpartner;
+ char *sectime;
+ char *devcert;
+ uint16_t *filetypes;
+ uint16_t filetypes_len;
+ uint8_t maxbattlevel;
+ uint8_t currbattlevel;
+ int ret;
+
+ device = LIBMTP_Open_Raw_Device(&rawdevices[i]);
+ if (device == NULL) {
+ fprintf(stderr, "Unable to open raw device %d\n", i);
+ continue;
+ }
- ret = LIBMTP_Get_Supported_Filetypes(iter, &filetypes, &filetypes_len);
- if (ret == 0) {
- uint16_t i;
+ LIBMTP_Dump_Errorstack(device);
+ LIBMTP_Clear_Errorstack(device);
+ LIBMTP_Dump_Device_Info(device);
- printf("libmtp supported (playable) filetypes:\n");
- for (i = 0; i < filetypes_len; i++) {
- fprintf(stdout, " %s\n", LIBMTP_Get_Filetype_Description(filetypes[i]));
- }
- } else {
- LIBMTP_Dump_Errorstack(iter);
- LIBMTP_Clear_Errorstack(iter);
- }
-
- // Secure time XML fragment
- ret = LIBMTP_Get_Secure_Time(iter, §ime);
- if (ret == 0 && sectime != NULL) {
- fprintf(stdout, "\nSecure Time:\n%s\n", sectime);
- free(sectime);
- } else {
- // Silently ignore - there may be devices not supporting secure time.
- LIBMTP_Clear_Errorstack(iter);
- }
-
- // Device certificate XML fragment
- ret = LIBMTP_Get_Device_Certificate(iter, &devcert);
- if (ret == 0 && devcert != NULL) {
- fprintf(stdout, "\nDevice Certificate:\n%s\n", devcert);
- free(devcert);
- } else {
- fprintf(stdout, "Unable to acquire device certificate, perhaps this device "
- "does not support this\n");
- LIBMTP_Dump_Errorstack(iter);
- LIBMTP_Clear_Errorstack(iter);
- }
-
- // Try to get Media player device info XML file...
- files = LIBMTP_Get_Filelisting_With_Callback(iter, NULL, NULL);
- if (files != NULL) {
- LIBMTP_file_t *file, *tmp;
- file = files;
- while (file != NULL) {
- if (!strcmp(file->filename, "WMPInfo.xml") ||
- !strcmp(file->filename, "WMPinfo.xml"))
- {
- xmlfileid = file->item_id;
+ printf("MTP-specific device properties:\n");
+ // The friendly name
+ friendlyname = LIBMTP_Get_Friendlyname(device);
+ if (friendlyname == NULL) {
+ fprintf(stdout, " Friendly name: (NULL)\n");
+ } else {
+ fprintf(stdout, " Friendly name: %s\n", friendlyname);
+ free(friendlyname);
+ }
+ syncpartner = LIBMTP_Get_Syncpartner(device);
+ if (syncpartner == NULL) {
+ fprintf(stdout, " Synchronization partner: (NULL)\n");
+ } else {
+ fprintf(stdout, " Synchronization partner: %s\n", syncpartner);
+ free(syncpartner);
+ }
+
+ // Some battery info
+ ret = LIBMTP_Get_Batterylevel(device, &maxbattlevel, &currbattlevel);
+ if (ret == 0) {
+ fprintf(stdout, " Battery level %d of %d (%d%%)\n",currbattlevel, maxbattlevel,
+ (int) ((float) currbattlevel/ (float) maxbattlevel * 100.0));
+ } else {
+ // Silently ignore. Some devices does not support getting the
+ // battery level.
+ LIBMTP_Clear_Errorstack(device);
+ }
+
+ ret = LIBMTP_Get_Supported_Filetypes(device, &filetypes, &filetypes_len);
+ if (ret == 0) {
+ uint16_t i;
+
+ printf("libmtp supported (playable) filetypes:\n");
+ for (i = 0; i < filetypes_len; i++) {
+ fprintf(stdout, " %s\n", LIBMTP_Get_Filetype_Description(filetypes[i]));
}
- tmp = file;
- file = file->next;
- LIBMTP_destroy_file_t(tmp);
+ } else {
+ LIBMTP_Dump_Errorstack(device);
+ LIBMTP_Clear_Errorstack(device);
}
- }
- if (xmlfileid == 0)
- fprintf(stdout, "WMPInfo.xml Does not exist on this device\n");
- if (xmlfileid != 0)
- {
- FILE *xmltmp = tmpfile();
- int tmpfiledescriptor = fileno(xmltmp);
- if (tmpfiledescriptor != -1)
- {
- int ret = LIBMTP_Get_Track_To_File_Descriptor(iter,
- xmlfileid,
- tmpfiledescriptor,
- NULL,
- NULL);
- if (ret == 0)
- {
- uint8_t *buf = NULL;
- uint32_t readbytes;
-
- buf = malloc(XML_BUFSIZE);
- if (buf == NULL)
- {
- printf("Could not allocate %08x bytes...\n", XML_BUFSIZE);
- LIBMTP_Dump_Errorstack(iter);
- LIBMTP_Clear_Errorstack(iter);
- LIBMTP_Release_Device_List(device);
- return 1;
- }
-
- lseek(tmpfiledescriptor, 0, SEEK_SET);
- readbytes = read(tmpfiledescriptor, (void*) buf, XML_BUFSIZE);
-
- if (readbytes >= 2 && readbytes < XML_BUFSIZE)
- {
- fprintf(stdout, "\nDevice description WMPInfo.xml file:\n");
- dump_xml_fragment(buf, readbytes);
- }
- else
- {
- perror("Unable to read WMPInfo.xml");
- LIBMTP_Dump_Errorstack(iter);
- LIBMTP_Clear_Errorstack(iter);
- }
- free(buf);
+ // Secure time XML fragment
+ ret = LIBMTP_Get_Secure_Time(device, §ime);
+ if (ret == 0 && sectime != NULL) {
+ fprintf(stdout, "\nSecure Time:\n%s\n", sectime);
+ free(sectime);
+ } else {
+ // Silently ignore - there may be devices not supporting secure time.
+ LIBMTP_Clear_Errorstack(device);
+ }
+
+ // Device certificate XML fragment
+ ret = LIBMTP_Get_Device_Certificate(device, &devcert);
+ if (ret == 0 && devcert != NULL) {
+ fprintf(stdout, "\nDevice Certificate:\n%s\n", devcert);
+ free(devcert);
+ } else {
+ fprintf(stdout, "Unable to acquire device certificate, perhaps this device "
+ "does not support this\n");
+ LIBMTP_Dump_Errorstack(device);
+ LIBMTP_Clear_Errorstack(device);
+ }
+
+ // Try to get Media player device info XML file...
+ files = LIBMTP_Get_Filelisting_With_Callback(device, NULL, NULL);
+ if (files != NULL) {
+ LIBMTP_file_t *file, *tmp;
+ file = files;
+ while (file != NULL) {
+ if (!strcmp(file->filename, "WMPInfo.xml") ||
+ !strcmp(file->filename, "WMPinfo.xml"))
+ {
+ xmlfileid = file->item_id;
+ }
+ tmp = file;
+ file = file->next;
+ LIBMTP_destroy_file_t(tmp);
}
- else
- {
- LIBMTP_Dump_Errorstack(iter);
- LIBMTP_Clear_Errorstack(iter);
+ }
+ if (xmlfileid == 0)
+ fprintf(stdout, "WMPInfo.xml Does not exist on this device\n");
+ if (xmlfileid != 0) {
+ FILE *xmltmp = tmpfile();
+ int tmpfiledescriptor = fileno(xmltmp);
+
+ if (tmpfiledescriptor != -1) {
+ int ret = LIBMTP_Get_Track_To_File_Descriptor(device,
+ xmlfileid,
+ tmpfiledescriptor,
+ NULL,
+ NULL);
+ if (ret == 0) {
+ uint8_t *buf = NULL;
+ uint32_t readbytes;
+
+ buf = malloc(XML_BUFSIZE);
+ if (buf == NULL) {
+ printf("Could not allocate %08x bytes...\n", XML_BUFSIZE);
+ LIBMTP_Dump_Errorstack(device);
+ LIBMTP_Clear_Errorstack(device);
+ free(rawdevices);
+ return 1;
+ }
+
+ lseek(tmpfiledescriptor, 0, SEEK_SET);
+ readbytes = read(tmpfiledescriptor, (void*) buf, XML_BUFSIZE);
+
+ if (readbytes >= 2 && readbytes < XML_BUFSIZE) {
+ fprintf(stdout, "\nDevice description WMPInfo.xml file:\n");
+ dump_xml_fragment(buf, readbytes);
+ } else {
+ perror("Unable to read WMPInfo.xml");
+ LIBMTP_Dump_Errorstack(device);
+ LIBMTP_Clear_Errorstack(device);
+ }
+ free(buf);
+ } else {
+ LIBMTP_Dump_Errorstack(device);
+ LIBMTP_Clear_Errorstack(device);
+ }
+ fclose(xmltmp);
}
- fclose(xmltmp);
}
- }
-
+ LIBMTP_Release_Device(device);
} /* End For Loop */
- LIBMTP_Release_Device_List(device);
+ free(rawdevices);
+
printf("OK.\n");
return 0;
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/examples/files.c
^
|
@@ -35,10 +35,13 @@
#ifdef __WIN32__
printf(" File size %llu (0x%016I64X) bytes\n", file->filesize, file->filesize);
#else
- printf(" File size %llu (0x%016llX) bytes\n", file->filesize, file->filesize);
+ printf(" File size %llu (0x%016llX) bytes\n",
+ (long long unsigned int) file->filesize,
+ (long long unsigned int) file->filesize);
#endif
}
printf(" Parent ID: %u\n", file->parent_id);
+ printf(" Storage ID: 0x%08X\n", file->storage_id);
printf(" Filetype: %s\n", LIBMTP_Get_Filetype_Description(file->filetype));
}
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/examples/hotplug.c
^
|
@@ -3,7 +3,7 @@
* Example program to create hotplug scripts.
*
* Copyright (C) 2005-2007 Linus Walleij <triad@df.lth.se>
- * Copyright (C) 2006 Marcus Meissner <marcus@jet.franken.de>
+ * Copyright (C) 2006-2008 Marcus Meissner <marcus@jet.franken.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -105,7 +105,7 @@
printf("<!-- This file was generated by %s - - fdi -->\n", argv[0]);
printf("<deviceinfo version=\"0.2\">\n");
printf(" <device>\n");
- printf(" <match key=\"info.bus\" string=\"usb\">\n");
+ printf(" <match key=\"info.subsystem\" string=\"usb\">\n");
break;
case style_usbids:
printf("# usb.ids style device list from libmtp\n");
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/examples/newfolder.c
^
|
@@ -36,12 +36,13 @@
uint32_t newid;
if(argc != 3) {
- printf("Usage: newfolder name id\n");
- printf("(id = parent folder or 0 to create the new folder in the root dir)\n");
+ printf("Usage: newfolder name <parent> <storage>\n");
+ printf(" parent = parent folder or 0 to create the new folder in the root dir\n");
+ printf(" storage = storage id or 0 to create the new folder on the primary storage\n");
return;
}
- newid = LIBMTP_Create_Folder(device, argv[1], atol(argv[2]));
+ newid = LIBMTP_Create_Folder(device, argv[1], atol(argv[2]), atol(argv[3]));
if (newid == 0) {
printf("Folder creation failed.\n");
} else {
@@ -56,7 +57,7 @@
char * parent = dirname(path);
char * folder = basename(path);
int id = parse_path (parent,files,folders);
- int newid = LIBMTP_Create_Folder(device, folder, id);
+ int newid = LIBMTP_Create_Folder(device, folder, id, 0);
if (newid == 0) {
printf("Folder creation failed.\n");
LIBMTP_Dump_Errorstack(device);
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/examples/newplaylist.c
^
|
@@ -88,7 +88,9 @@
playlist->name = playlistname;
playlist->no_tracks = idcount;
playlist->tracks = ids;
- int ret = LIBMTP_Create_New_Playlist(device,playlist,0);
+ playlist->parent_id = 0;
+ playlist->storage_id = 0;
+ int ret = LIBMTP_Create_New_Playlist(device,playlist);
if (ret != 0) {
printf("Couldn't create playlist object\n");
LIBMTP_Dump_Errorstack(device);
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/examples/pathutils.c
^
|
@@ -1,7 +1,7 @@
/**
* \file pathutils.c
*
- * Copyright (C) 2005-2007 Linus Walleij <triad@df.lth.se>
+ * Copyright (C) 2005-2008 Linus Walleij <triad@df.lth.se>
* Copyright (C) 2006 Chris A. Debenham <chris@adebenham.com>
*
* This library is free software; you can redistribute it and/or
@@ -26,16 +26,20 @@
/* Find the folder_id of a given path
* Runs by walking through folders structure */
-int
+static uint32_t
lookup_folder_id (LIBMTP_folder_t * folder, char * path, char * parent)
{
+ char * current;
+ uint32_t ret = (uint32_t) -1;
+
if (strcmp(path,"/")==0)
return 0;
- int ret = -1;
+
if (folder == NULL) {
return ret;
}
- char * current = malloc (strlen(parent) + strlen(folder->name) + 2);
+
+ current = malloc (strlen(parent) + strlen(folder->name) + 2);
sprintf(current,"%s/%s",parent,folder->name);
if (strcasecmp (path, current) == 0) {
free (current);
@@ -45,7 +49,7 @@
ret = lookup_folder_id (folder->child, path, current);
}
free (current);
- if (ret >= 0) {
+ if (ret != (uint32_t) (-1)) {
return ret;
}
ret = lookup_folder_id (folder->sibling, path, parent);
@@ -57,41 +61,49 @@
parse_path (char * path, LIBMTP_file_t * files, LIBMTP_folder_t * folders)
{
char *rest;
+ uint32_t item_id;
+
// Check if path is an item_id
if (*path != '/') {
- int item_id = strtoul(path, &rest, 0);
+ item_id = strtoul(path, &rest, 0);
// really should check contents of "rest" here...
+ /* if not number, assume a file name */
+ if (item_id == 0) {
+ LIBMTP_file_t * file = files;
+
+ /* search for matching name */
+ while (file != NULL) {
+ if (strcasecmp (file->filename, path) == 0) {
+ return file->item_id;
+ }
+ file = file->next;
+ }
+ }
return item_id;
}
// Check if path is a folder
- int item_id = lookup_folder_id(folders,path,"");
- if (item_id == -1) {
+ item_id = lookup_folder_id(folders,path,"");
+ if (item_id == (uint32_t) -1) {
char * dirc = strdup(path);
char * basec = strdup(path);
char * parent = dirname(dirc);
char * filename = basename(basec);
-
- //int len = strlen(strrchr(path,'/'));
- //char * filename = malloc(len);
- //int index = strlen (path) - len;
- //filename = strncpy (filename, &path[index+1],len);
- //char * parent = malloc(index);
- //parent = strncpy(parent, path, index);
- //parent[index] = '\0';
- int parent_id = lookup_folder_id(folders,parent,"");
+ uint32_t parent_id = lookup_folder_id(folders,parent,"");
LIBMTP_file_t * file;
+
file = files;
while (file != NULL) {
if (file->parent_id == parent_id) {
if (strcasecmp (file->filename, filename) == 0) {
- int item_id = file->item_id;
- free(dirc); free(basec);
- return item_id;
+ free(dirc);
+ free(basec);
+ return file->item_id;
}
}
file = file->next;
}
- free(dirc); free(basec);
+ free(dirc);
+ free(basec);
} else {
return item_id;
}
@@ -116,8 +128,16 @@
find_filetype (const char * filename)
{
char *ptype;
- ptype = rindex(filename,'.')+1;
LIBMTP_filetype_t filetype;
+
+ ptype = rindex(filename,'.');
+ // This accounts for the case with a filename without any "." (period).
+ if (!ptype) {
+ ptype = "";
+ } else {
+ ++ptype;
+ }
+
/* This need to be kept constantly updated as new file types arrive. */
if (!strcasecmp (ptype, "wav")) {
filetype = LIBMTP_FILETYPE_WAV;
@@ -185,6 +205,8 @@
filetype = LIBMTP_FILETYPE_JP2;
} else if (!strcasecmp (ptype, "jpx")) {
filetype = LIBMTP_FILETYPE_JPX;
+ } else if (!strcasecmp (ptype, "bin")) {
+ filetype = LIBMTP_FILETYPE_FIRMWARE;
} else {
/* Tagging as unknown file type */
filetype = LIBMTP_FILETYPE_UNKNOWN;
@@ -197,6 +219,7 @@
#ifndef HAVE_LIBGEN_H
static char *basename(char *in) {
char *p;
+
if (in == NULL)
return NULL;
p = in + strlen(in) - 1;
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/examples/pathutils.h
^
|
@@ -20,7 +20,6 @@
*/
#ifndef PATHUTILS_H_INCLUSION_GUARD
#define PATHUTILS_H_INCLUSION_GUARD
-int lookup_folder_id (LIBMTP_folder_t *, char *, char *);
int parse_path (char *, LIBMTP_file_t *, LIBMTP_folder_t *);
LIBMTP_filetype_t find_filetype (const char *);
int progress (u_int64_t const, u_int64_t const, void const * const);
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/examples/playlists.c
^
|
@@ -28,6 +28,7 @@
printf("Playlist ID: %d\n", pl->playlist_id);
if (pl->name != NULL)
printf(" Name: %s\n", pl->name);
+ printf(" Parent ID: %d\n", pl->parent_id);
printf(" Tracks:\n");
for (i = 0; i < pl->no_tracks; i++) {
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/examples/sendfile.c
^
|
@@ -85,9 +85,11 @@
genfile->filesize = filesize;
genfile->filename = strdup(filename);
genfile->filetype = find_filetype (filename);
+ genfile->parent_id = 0;
+ genfile->storage_id = 0;
printf("Sending file...\n");
- ret = LIBMTP_Send_File_From_File(device, from_path, genfile, progress, NULL, parent_id);
+ ret = LIBMTP_Send_File_From_File(device, from_path, genfile, progress, NULL);
printf("\n");
if (ret != 0) {
printf("Error sending file.\n");
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/examples/sendtr.c
^
|
@@ -5,10 +5,11 @@
* based on Enrique Jorreto Ledesma's work on the original program by
* Shaun Jackman and Linus Walleij.
*
- * Copyright (C) 2003-2007 Linus Walleij <triad@df.lth.se>
+ * Copyright (C) 2003-2008 Linus Walleij <triad@df.lth.se>
* Copyright (C) 2003-2005 Shaun Jackman
* Copyright (C) 2003-2005 Enrique Jorrete Ledesma
* Copyright (C) 2006 Chris A. Debenham <chris@adebenham.com>
+ * Copyright (C) 2008 Nicolas Pennequin <nicolas.pennequin@free.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -28,12 +29,15 @@
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
+#include "common.h"
#include <string.h>
#include <libgen.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
-#include "common.h"
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
#include "libmtp.h"
#include "pathutils.h"
@@ -41,18 +45,44 @@
extern LIBMTP_file_t *files;
extern LIBMTP_mtpdevice_t *device;
-int sendtrack_function (char *, char *, char *, char *, char *, char *, uint16_t, uint16_t, uint16_t);
+int sendtrack_function (char *, char *, char *, char *, char *, char *, char *, char *, uint16_t, uint16_t, uint16_t);
void sendtrack_command (int, char **);
void sendtrack_usage (void);
void sendtrack_usage (void)
{
- fprintf(stderr, "usage: sendtr [ -D debuglvl ] [ -q ] -t <title> -a <artist> -l <album>\n");
- fprintf(stderr, " -c <codec> -g <genre> -n <track number> -y <year> \n");
+ fprintf(stderr, "usage: sendtr [ -D debuglvl ] [ -q ]\n");
+ fprintf(stderr, "-t <title> -a <artist> -A <Album artist> -w <writer or composer>\n");
+ fprintf(stderr, " -l <album> -c <codec> -g <genre> -n <track number> -y <year>\n");
fprintf(stderr, " -d <duration in seconds> <local path> <remote path>\n");
fprintf(stderr, "(-q means the program will not ask for missing information.)\n");
}
+static void checklang(void)
+{
+ char *langsuff = NULL;
+ char *lang = getenv("LANG");
+
+#ifdef HAVE_LANGINFO_H
+ langsuff = nl_langinfo(CODESET);
+#else
+ /*
+ * Check environment variables $LANG and $LC_CTYPE
+ * to see if we want to support UTF-8 unicode
+ */
+ if (lang != NULL) {
+ if (strlen(lang) > 5) {
+ langsuff = &lang[strlen(lang)-5];
+ }
+ }
+#endif
+ if (strcmp(langsuff, "UTF-8")) {
+ printf("Your system does not appear to have UTF-8 enabled ($LANG=\"%s\")\n", lang);
+ printf("If you want to have support for diacritics and Unicode characters,\n");
+ printf("please switch your locale to an UTF-8 locale, e.g. \"en_US.UTF-8\".\n");
+ }
+}
+
static char *prompt (const char *prompt, char *buffer, size_t bufsz, int required)
{
char *cp, *bp;
@@ -81,11 +111,81 @@
}
}
-int sendtrack_function(char * from_path, char * to_path, char *partist, char *ptitle, char *pgenre, char *palbum, uint16_t tracknum, uint16_t length, uint16_t year)
+static int add_track_to_album(LIBMTP_album_t *albuminfo, LIBMTP_track_t *trackmeta)
+{
+ LIBMTP_album_t *album;
+ LIBMTP_album_t *found_album = NULL;
+ int ret;
+
+ /* Look for the album */
+ album = LIBMTP_Get_Album_List(device);
+ while(album != NULL) {
+ if ((album->name != NULL &&
+ album->artist != NULL &&
+ !strcmp(album->name, albuminfo->name) &&
+ !strcmp(album->artist, albuminfo->artist)) ||
+ (album->name != NULL &&
+ album->composer != NULL &&
+ !strcmp(album->name, albuminfo->name) &&
+ !strcmp(album->composer, albuminfo->composer))) {
+ /* Disconnect this album for later use */
+ found_album = album;
+ album = album->next;
+ found_album->next = NULL;
+ } else {
+ LIBMTP_album_t *tmp;
+
+ tmp = album;
+ album = album->next;
+ LIBMTP_destroy_album_t(tmp);
+ }
+ }
+
+ if (found_album != NULL) {
+ uint32_t *tracks;
+
+ tracks = (uint32_t *)malloc((found_album->no_tracks+1) * sizeof(uint32_t));
+ printf("Album \"%s\" found: updating...\n", found_album->name);
+ if (!tracks) {
+ printf("failed malloc in add_track_to_album()\n");
+ return 1;
+ }
+ found_album->no_tracks++;
+ if (found_album->tracks != NULL) {
+ memcpy(tracks, found_album->tracks, found_album->no_tracks * sizeof(uint32_t));
+ free(found_album->tracks);
+ }
+ tracks[found_album->no_tracks-1] = trackmeta->item_id;
+ found_album->tracks = tracks;
+ ret = LIBMTP_Update_Album(device, found_album);
+ LIBMTP_destroy_album_t(found_album);
+ } else {
+ uint32_t *trackid;
+
+ trackid = (uint32_t *)malloc(sizeof(uint32_t));
+ *trackid = trackmeta->item_id;
+ albuminfo->tracks = trackid;
+ albuminfo->no_tracks = 1;
+ albuminfo->storage_id = trackmeta->storage_id;
+ printf("Album doesn't exist: creating...\n");
+ ret = LIBMTP_Create_New_Album(device, albuminfo);
+ /* albuminfo will be destroyed later by caller */
+ }
+
+ if (ret != 0) {
+ printf("Error creating or updating album.\n");
+ LIBMTP_Dump_Errorstack(device);
+ LIBMTP_Clear_Errorstack(device);
+ } else {
+ printf("success!\n");
+ }
+ return ret;
+}
+
+int sendtrack_function(char * from_path, char * to_path, char *partist, char *palbumartist, char *ptitle, char *pgenre, char *palbum, char *pcomposer, uint16_t tracknum, uint16_t length, uint16_t year)
{
- printf("Sending track %s to %s\n",from_path,to_path);
char *filename, *parent;
- char artist[80], title[80], genre[80], album[80];
+ char artist[80], albumartist[80], title[80], genre[80], album[80], composer[80];
char num[80];
uint64_t filesize;
uint32_t parent_id = 0;
@@ -95,7 +195,13 @@
struct stat sb;
#endif
LIBMTP_track_t *trackmeta;
+ LIBMTP_album_t *albuminfo;
+ int ret;
+
+ printf("Sending track %s to %s\n",from_path,to_path);
+
trackmeta = LIBMTP_new_track_t();
+ albuminfo = LIBMTP_new_album_t();
parent = dirname(to_path);
filename = basename(to_path);
@@ -120,40 +226,38 @@
filesize = (uint64_t) sb.st_size;
#endif
trackmeta->filetype = find_filetype (from_path);
- if ((trackmeta->filetype != LIBMTP_FILETYPE_MP3)
- && (trackmeta->filetype != LIBMTP_FILETYPE_WAV)
- && (trackmeta->filetype != LIBMTP_FILETYPE_OGG)
- && (trackmeta->filetype != LIBMTP_FILETYPE_MP4)
- && (trackmeta->filetype != LIBMTP_FILETYPE_AAC)
- && (trackmeta->filetype != LIBMTP_FILETYPE_M4A)
- && (trackmeta->filetype != LIBMTP_FILETYPE_FLAC)
- && (trackmeta->filetype != LIBMTP_FILETYPE_WMA)) {
- printf("Not a valid codec: \"%s\"\n", LIBMTP_Get_Filetype_Description(trackmeta->filetype));
- printf("Supported formats: MP3, WAV, OGG, MP4, AAC, M4A, FLAC, WMA\n");
+ if (!LIBMTP_FILETYPE_IS_TRACK(trackmeta->filetype)) {
+ printf("Not a valid track codec: \"%s\"\n", LIBMTP_Get_Filetype_Description(trackmeta->filetype));
return 1;
}
- int ret;
-
if (ptitle == NULL) {
ptitle = prompt("Title", title, 80, 0);
}
if (!strlen(ptitle))
ptitle = NULL;
-
if (palbum == NULL) {
palbum = prompt("Album", album, 80, 0);
}
if (!strlen(palbum))
palbum = NULL;
+ if (palbumartist == NULL) {
+ palbumartist = prompt("Album artist", albumartist, 80, 0);
+ }
if (partist == NULL) {
partist = prompt("Artist", artist, 80, 0);
}
if (!strlen(partist))
partist = NULL;
+ if (pcomposer == NULL) {
+ pcomposer = prompt("Writer or Composer", composer, 80, 0);
+ }
+ if (!strlen(pcomposer))
+ pcomposer = NULL;
+
if (pgenre == NULL) {
pgenre = prompt("Genre", genre, 80, 0);
}
@@ -192,7 +296,6 @@
length = 0;
}
}
-
printf("Sending track:\n");
printf("Codec: %s\n", LIBMTP_Get_Filetype_Description(trackmeta->filetype));
@@ -203,14 +306,28 @@
if (palbum) {
printf("Album: %s\n", palbum);
trackmeta->album = strdup(palbum);
+ albuminfo->name = strdup(palbum);
+ }
+ if (palbumartist) {
+ printf("Album artist: %s\n", palbumartist);
+ albuminfo->artist = strdup(palbumartist);
}
if (partist) {
printf("Artist: %s\n", partist);
trackmeta->artist = strdup(partist);
+ if (palbumartist == NULL)
+ albuminfo->artist = strdup(partist);
+ }
+
+ if (pcomposer) {
+ printf("Writer or Composer: %s\n", pcomposer);
+ trackmeta->composer = strdup(pcomposer);
+ albuminfo->composer = strdup(pcomposer);
}
if (pgenre) {
printf("Genre: %s\n", pgenre);
trackmeta->genre = strdup(pgenre);
+ albuminfo->genre = strdup(pgenre);
}
if (year > 0) {
char tmp[80];
@@ -233,9 +350,12 @@
trackmeta->filename = strdup(filename);
}
trackmeta->filesize = filesize;
+ trackmeta->parent_id = parent_id;
+ // Use default storage.
+ trackmeta->storage_id = 0;
printf("Sending track...\n");
- ret = LIBMTP_Send_Track_From_File(device, from_path, trackmeta, progress, NULL, parent_id);
+ ret = LIBMTP_Send_Track_From_File(device, from_path, trackmeta, progress, NULL);
printf("\n");
if (ret != 0) {
printf("Error sending track.\n");
@@ -245,8 +365,12 @@
printf("New track ID: %d\n", trackmeta->item_id);
}
+/* Add here add to album call */
+ ret = add_track_to_album(albuminfo, trackmeta);
+
+ LIBMTP_destroy_album_t(albuminfo);
LIBMTP_destroy_track_t(trackmeta);
-
+
return 0;
}
return 0;
@@ -257,6 +381,8 @@
extern int optind;
extern char *optarg;
char *partist = NULL;
+ char *palbumartist = NULL;
+ char *pcomposer = NULL;
char *ptitle = NULL;
char *pgenre = NULL;
char *pcodec = NULL;
@@ -266,7 +392,7 @@
uint16_t year = 0;
uint16_t quiet = 0;
char *lang;
- while ( (opt = getopt(argc, argv, "qD:t:a:l:c:g:n:d:y:")) != -1 ) {
+ while ( (opt = getopt(argc, argv, "qD:t:a:A:w:l:c:g:n:d:y:")) != -1 ) {
switch (opt) {
case 't':
ptitle = strdup(optarg);
@@ -274,6 +400,12 @@
case 'a':
partist = strdup(optarg);
break;
+ case 'A':
+ palbumartist = strdup(optarg);
+ break;
+ case 'w':
+ pcomposer = strdup(optarg);
+ break;
case 'l':
palbum = strdup(optarg);
break;
@@ -306,22 +438,9 @@
printf("You need to pass a filename and destination.\n");
sendtrack_usage();
}
- /*
- * Check environment variables $LANG and $LC_CTYPE
- * to see if we want to support UTF-8 unicode
- */
- lang = getenv("LANG");
- if (lang != NULL) {
- if (strlen(lang) > 5) {
- char *langsuff = &lang[strlen(lang)-5];
- if (strcmp(langsuff, "UTF-8")) {
- printf("Your system does not appear to have UTF-8 enabled ($LANG=\"%s\")\n", lang);
- printf("If you want to have support for diacritics and Unicode characters,\n");
- printf("please switch your locale to an UTF-8 locale, e.g. \"en_US.UTF-8\".\n");
- }
- }
- }
+
+ checklang();
- printf("%s,%s,%s,%s,%s,%s,%d%d,%d\n",argv[0],argv[1],partist,ptitle,pgenre,palbum,tracknum, length, year);
- sendtrack_function(argv[0],argv[1],partist,ptitle,pgenre,palbum, tracknum, length, year);
+ printf("%s,%s,%s,%s,%s,%s,%s,%s,%d%d,%d\n",argv[0],argv[1],partist,palbumartist,ptitle,pgenre,palbum,pcomposer,tracknum, length, year);
+ sendtrack_function(argv[0],argv[1],partist,palbumartist,ptitle,pgenre,palbum,pcomposer, tracknum, length, year);
}
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/examples/tracks.c
^
|
@@ -31,6 +31,8 @@
printf(" Artist: %s\n", track->artist);
if (track->genre != NULL)
printf(" Genre: %s\n", track->genre);
+ if (track->composer != NULL)
+ printf(" Composer: %s\n", track->composer);
if (track->album != NULL)
printf(" Album: %s\n", track->album);
if (track->date != NULL)
@@ -42,7 +44,7 @@
#ifdef __WIN32__
printf(" File size %I64u bytes\n", track->filesize);
#else
- printf(" File size %llu bytes\n", track->filesize);
+ printf(" File size %llu bytes\n", (long long unsigned int) track->filesize);
#endif
printf(" Filetype: %s\n", LIBMTP_Get_Filetype_Description(track->filetype));
if (track->samplerate != 0) {
@@ -87,25 +89,25 @@
switch(LIBMTP_Get_Connected_Devices(&device_list))
{
case LIBMTP_ERROR_NO_DEVICE_ATTACHED:
- fprintf(stdout, "mtp-folders: No Devices have been found\n");
+ fprintf(stdout, "mtp-tracks: No Devices have been found\n");
return 0;
case LIBMTP_ERROR_CONNECTING:
- fprintf(stderr, "mtp-folders: There has been an error connecting. Exit\n");
+ fprintf(stderr, "mtp-tracks: There has been an error connecting. Exit\n");
return 1;
case LIBMTP_ERROR_MEMORY_ALLOCATION:
- fprintf(stderr, "mtp-folders: Memory Allocation Error. Exit\n");
+ fprintf(stderr, "mtp-tracks: Memory Allocation Error. Exit\n");
return 1;
/* Unknown general errors - This should never execute */
case LIBMTP_ERROR_GENERAL:
default:
- fprintf(stderr, "mtp-folders: Unknown error, please report "
+ fprintf(stderr, "mtp-tracks: Unknown error, please report "
"this to the libmtp developers\n");
return 1;
/* Successfully connected at least one device, so continue */
case LIBMTP_ERROR_NONE:
- fprintf(stdout, "mtp-folders: Successfully connected\n");
+ fprintf(stdout, "mtp-tracks: Successfully connected\n");
fflush(stdout);
}
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/hotplug.sh.in
^
|
@@ -141,7 +141,7 @@
fi
echo "Installing script."
-${INSTALL} nomadjukebox ${HOTPLUGPATH}/usb
+${INSTALL} libmtp.sh ${HOTPLUGPATH}/usb
echo "Installing usermap."
${INSTALL} -m 644 ${USERMAP} ${HOTPLUGPATH}/usb
# If we find a usb.usermap file, and we see that this distribution
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/install-sh
^
|
@@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
-scriptversion=2006-10-14.15
+scriptversion=2006-12-25.00
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@@ -48,7 +48,7 @@
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
+doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
@@ -58,34 +58,49 @@
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+ test "$posix_glob" != "?" || {
+ if (set -f) 2>/dev/null; then
+ posix_glob=
+ else
+ posix_glob=:
+ fi
+ }
+'
-posix_glob=
posix_mkdir=
# Desired mode of installed file.
mode=0755
+chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
-chgrpcmd=
-stripcmd=
+mvcmd=$mvprog
rmcmd="$rmprog -f"
-mvcmd="$mvprog"
+stripcmd=
+
src=
dst=
dir_arg=
-dstarg=
+dst_arg=
+
+copy_on_change=false
no_target_directory=
-usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
@@ -95,65 +110,55 @@
In the 4th, create DIRECTORIES.
Options:
--c (ignored)
--d create directories instead of installing files.
--g GROUP $chgrpprog installed files to GROUP.
--m MODE $chmodprog installed files to MODE.
--o USER $chownprog installed files to USER.
--s $stripprog installed files.
--t DIRECTORY install into DIRECTORY.
--T report an error if DSTFILE is a directory.
---help display this help and exit.
---version display version info and exit.
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
Environment variables override the default commands:
- CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
- -c) shift
- continue;;
+ -c) ;;
+
+ -C) copy_on_change=true;;
- -d) dir_arg=true
- shift
- continue;;
+ -d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
- shift
- shift
- continue;;
+ shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
- shift
- shift
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
- continue;;
+ shift;;
-o) chowncmd="$chownprog $2"
- shift
- shift
- continue;;
-
- -s) stripcmd=$stripprog
- shift
- continue;;
-
- -t) dstarg=$2
- shift
- shift
- continue;;
-
- -T) no_target_directory=true
- shift
- continue;;
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ shift;;
+
+ -T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
@@ -165,21 +170,22 @@
*) break;;
esac
+ shift
done
-if test $# -ne 0 && test -z "$dir_arg$dstarg"; then
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
- if test -n "$dstarg"; then
+ if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
- set fnord "$@" "$dstarg"
+ set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
- dstarg=$arg
+ dst_arg=$arg
done
fi
@@ -224,7 +230,7 @@
do
# Protect names starting with `-'.
case $src in
- -*) src=./$src ;;
+ -*) src=./$src;;
esac
if test -n "$dir_arg"; then
@@ -242,22 +248,22 @@
exit 1
fi
- if test -z "$dstarg"; then
+ if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
- dst=$dstarg
+ dst=$dst_arg
# Protect names starting with `-'.
case $dst in
- -*) dst=./$dst ;;
+ -*) dst=./$dst;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
- echo "$0: $dstarg: Is a directory" >&2
+ echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
@@ -378,26 +384,19 @@
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
- /*) prefix=/ ;;
- -*) prefix=./ ;;
- *) prefix= ;;
+ /*) prefix='/';;
+ -*) prefix='./';;
+ *) prefix='';;
esac
- case $posix_glob in
- '')
- if (set -f) 2>/dev/null; then
- posix_glob=true
- else
- posix_glob=false
- fi ;;
- esac
+ eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
- $posix_glob && set -f
+ $posix_glob set -f
set fnord $dstdir
shift
- $posix_glob && set +f
+ $posix_glob set +f
IFS=$oIFS
prefixes=
@@ -459,41 +458,54 @@
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
- { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
- && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
- && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
- && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
-
- # Now rename the file to the real destination.
- { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
- || {
- # The rename failed, perhaps because mv can't rename something else
- # to itself, or perhaps because mv is so ancient that it does not
- # support -f.
-
- # Now remove or move aside any old file at destination location.
- # We try this two ways since rm can't unlink itself on some
- # systems and the destination file might be busy for other
- # reasons. In this case, the final cleanup might fail but the new
- # file should still install successfully.
- {
- if test -f "$dst"; then
- $doit $rmcmd -f "$dst" 2>/dev/null \
- || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
- && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
- || {
- echo "$0: cannot unlink or rename $dst" >&2
- (exit 1); exit 1
- }
- else
- :
- fi
- } &&
-
- # Now rename the file to the real destination.
- $doit $mvcmd "$dsttmp" "$dst"
- }
- } || exit 1
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+ eval "$initialize_posix_glob" &&
+ $posix_glob set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ $posix_glob set +f &&
+
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
trap '' 0
fi
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/libmtp.pc
^
|
@@ -7,7 +7,7 @@
Name: libmtp
Description: libmtp is a library for accessing Media Transfer Protocol devices
-Version: 0.2.4
+Version: 0.3.0
Requires: libusb
Conflicts:
Libs: -L${libdir} -lmtp
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/src/Makefile.am
^
|
@@ -28,9 +28,9 @@
# increment AGE, Otherwise AGE is reset to 0. If CURRENT has changed,
# REVISION is set to 0, otherwise REVISION is incremented.
# ---------------------------------------------------------------------------
-CURRENT=7
+CURRENT=8
AGE=0
-REVISION=1
+REVISION=0
SOVERSION=$(CURRENT):$(REVISION):$(AGE)
if COMPILE_MINGW32
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/src/Makefile.in
^
|
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -61,7 +61,7 @@
libmtp_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libmtp_la_LDFLAGS) $(LDFLAGS) -o $@
-DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -224,9 +224,9 @@
# increment AGE, Otherwise AGE is reset to 0. If CURRENT has changed,
# REVISION is set to 0, otherwise REVISION is incremented.
# ---------------------------------------------------------------------------
-CURRENT = 7
+CURRENT = 8
AGE = 0
-REVISION = 1
+REVISION = 0
SOVERSION = $(CURRENT):$(REVISION):$(AGE)
@COMPILE_MINGW32_TRUE@noinst_DATA = libmtp.lib
@COMPILE_MINGW32_TRUE@W32LF = -export-dynamic -no-undefined -export-symbols libmtp.sym
@@ -272,8 +272,8 @@
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
- $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
else :; fi; \
done
@@ -281,8 +281,8 @@
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
p=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
- $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
done
clean-libLTLIBRARIES:
@@ -357,8 +357,8 @@
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
@@ -370,8 +370,8 @@
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -381,13 +381,12 @@
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
- here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/src/device-flags.h
^
|
@@ -127,4 +127,29 @@
* this device, but the metadata is plain ignored on
* tracks, though e.g. playlist names can be set.)
*/
-#define DEVICE_FLAG_BROKEN_SET_OBJECT_PROPLIST 0x000000100
+#define DEVICE_FLAG_BROKEN_SET_OBJECT_PROPLIST 0x00000100
+/**
+ * The Samsung YP-T10 think Ogg files shall be sent with
+ * the "unknown" (PTP_OFC_Undefined) file type, this gives a
+ * side effect that is a combination of the iRiver Ogg Alzheimer
+ * problem (have to recognized Ogg files on file extension)
+ * and a need to report the Ogg support (the device itself does
+ * not properly claim to support it) and need to set filetype
+ * to unknown when storing Ogg files, even though they're not
+ * actually unknown.
+ */
+#define DEVICE_FLAG_OGG_IS_UNKNOWN 0x00000200
+/**
+ * The Creative Zen is quite unstable in libmtp but seems to
+ * be better with later firmware versions. However, it still
+ * frequently crashes when setting album art dimensions. This
+ * flag disables setting the dimensions (which seems to make
+ * no difference to how the graphic is displayed).
+ */
+#define DEVICE_FLAG_BROKEN_SET_SAMPLE_DIMENSIONS 0x00000400
+/**
+ * Some devices, particularly SanDisk Sansas, need to always
+ * have their "OS Descriptor" probed in order to work correctly.
+ * This flag provides that extra massage.
+ */
+#define DEVICE_FLAG_ALWAYS_PROBE_DESCRIPTOR 0x00000800
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/src/libmtp.c
^
|
@@ -1,10 +1,11 @@
/**
* \file libmtp.c
*
- * Copyright (C) 2005-2007 Linus Walleij <triad@df.lth.se>
- * Copyright (C) 2005-2007 Richard A. Low <richard@wentnet.com>
+ * Copyright (C) 2005-2008 Linus Walleij <triad@df.lth.se>
+ * Copyright (C) 2005-2008 Richard A. Low <richard@wentnet.com>
* Copyright (C) 2007 Ted Bullock <tbullock@canada.com>
* Copyright (C) 2007 Tero Saarni <tero.saarni@gmail.com>
+ * Copyright (C) 2008 Florent Mertens <flomertens@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -128,8 +129,10 @@
static int create_new_abstract_list(LIBMTP_mtpdevice_t *device,
char const * const name,
char const * const artist,
+ char const * const composer,
char const * const genre,
uint32_t const parenthandle,
+ uint32_t const storageid,
uint16_t const objectformat,
char const * const suffix,
uint32_t * const newid,
@@ -138,6 +141,7 @@
static int update_abstract_list(LIBMTP_mtpdevice_t *device,
char const * const name,
char const * const artist,
+ char const * const composer,
char const * const genre,
uint32_t const objecthandle,
uint16_t const objectformat,
@@ -293,8 +297,8 @@
/**
- * Returns the PTP internal filetype that maps to a certain libmtp
- * interface file type.
+ * Returns the MTP internal interface type that maps to a certain ptp
+ * interface type.
* @param intype the PTP (libgphoto2) interface type
* @return the MTP library interface type
*/
@@ -825,218 +829,236 @@
LIBMTP_mtpdevice_t *LIBMTP_Get_First_Device(void)
{
LIBMTP_mtpdevice_t *first_device = NULL;
+ LIBMTP_raw_device_t *devices;
+ int numdevs;
+ LIBMTP_error_number_t ret;
- switch(LIBMTP_Get_Connected_Devices(&first_device))
- {
- /* Specific Errors or Messages that connect_mtp_devices should return */
- case LIBMTP_ERROR_NO_DEVICE_ATTACHED:
- fprintf(stderr, "LIBMTP_Get_First_Device: No Devices Attached\n");
+ ret = LIBMTP_Detect_Raw_Devices(&devices, &numdevs);
+ if (ret != LIBMTP_ERROR_NONE) {
return NULL;
+ }
- case LIBMTP_ERROR_CONNECTING:
- fprintf(stderr, "LIBMTP_Get_First_Device: Error Connecting\n");
+ if (devices == NULL || numdevs == 0) {
return NULL;
+ }
- case LIBMTP_ERROR_MEMORY_ALLOCATION:
- fprintf(stderr, "LIBMTP_Get_First_Device: Memory Alloc Error\n");
+ first_device = LIBMTP_Open_Raw_Device(&devices[0]);
+ free(devices);
+ return first_device;
+}
+
+/**
+ * This function opens a device from a raw device. It is the
+ * preferred way to access devices in the new interface where
+ * several devices can come and go as the library is working
+ * on a certain device.
+ * @param rawdevice the raw device to open a "real" device for.
+ * @return an open device.
+ */
+LIBMTP_mtpdevice_t *LIBMTP_Open_Raw_Device(LIBMTP_raw_device_t *rawdevice)
+{
+ LIBMTP_mtpdevice_t *mtp_device;
+ uint8_t bs = 0;
+ PTPParams *current_params;
+ PTP_USB *ptp_usb;
+ LIBMTP_error_number_t err;
+ int i;
+
+ /* Allocate dynamic space for our device */
+ mtp_device = (LIBMTP_mtpdevice_t *) malloc(sizeof(LIBMTP_mtpdevice_t));
+ /* Check if there was a memory allocation error */
+ if(mtp_device == NULL) {
+ /* There has been an memory allocation error. We are going to ignore this
+ device and attempt to continue */
+
+ /* TODO: This error statement could probably be a bit more robust */
+ fprintf(stderr, "LIBMTP PANIC: connect_usb_devices encountered a memory "
+ "allocation error with device %d on bus %d, trying to continue",
+ rawdevice->devnum, rawdevice->bus_location);
+
+ return NULL;
+ }
+
+ /* Create PTP params */
+ current_params = (PTPParams *) malloc(sizeof(PTPParams));
+ if (current_params == NULL) {
+ free(mtp_device);
+ return NULL;
+ }
+ memset(current_params, 0, sizeof(PTPParams));
+ /* Clear all handlers */
+ current_params->handles.Handler = NULL;
+ current_params->objectinfo = NULL;
+ current_params->props = NULL;
+ /* TODO: Will this always be little endian? */
+ current_params->byteorder = PTP_DL_LE;
+ current_params->cd_locale_to_ucs2 = iconv_open("UCS-2LE", "UTF-8");
+ current_params->cd_ucs2_to_locale = iconv_open("UTF-8", "UCS-2LE");
+
+ if(current_params->cd_locale_to_ucs2 == (iconv_t) -1 ||
+ current_params->cd_ucs2_to_locale == (iconv_t) -1) {
+ fprintf(stderr, "LIBMTP PANIC: Cannot open iconv() converters to/from UCS-2!\n"
+ "Too old stdlibc, glibc and libiconv?\n");
+ free(current_params);
+ free(mtp_device);
return NULL;
+ }
+ mtp_device->params = current_params;
+
- /* Unknown general errors - This should never execute */
- case LIBMTP_ERROR_GENERAL:
- default:
- fprintf(stderr, "LIBMTP_Get_First_Device: Unknown Connection Error\n");
+ /* Create usbinfo, this also opens the session */
+ err = configure_usb_device(rawdevice,
+ current_params,
+ &mtp_device->usbinfo);
+ if (err != LIBMTP_ERROR_NONE) {
+ free(current_params);
+ free(mtp_device);
+ return NULL;
+ }
+ ptp_usb = (PTP_USB*) mtp_device->usbinfo;
+ /* Set pointer back to params */
+ ptp_usb->params = current_params;
+
+
+ /* Cache the device information for later use */
+ if (ptp_getdeviceinfo(current_params,
+ ¤t_params->deviceinfo) != PTP_RC_OK) {
+ fprintf(stderr, "LIBMTP PANIC: Unable to read device information on device "
+ "%d on bus %d, trying to continue",
+ rawdevice->devnum, rawdevice->bus_location);
+
+ /* Prevent memory leaks for this device */
+ free(mtp_device->usbinfo);
+ free(mtp_device->params);
+ current_params = NULL;
+ free(mtp_device);
return NULL;
+ }
- /* Successfully connect at least one device, so continue */
- case LIBMTP_ERROR_NONE:
- break;
+ /* Determine if the object size supported is 32 or 64 bit wide */
+ for (i=0;i<current_params->deviceinfo.ImageFormats_len;i++) {
+ PTPObjectPropDesc opd;
+
+ if (ptp_mtp_getobjectpropdesc(current_params,
+ PTP_OPC_ObjectSize,
+ current_params->deviceinfo.ImageFormats[i],
+ &opd) != PTP_RC_OK) {
+ printf("LIBMTP PANIC: create_usb_mtp_devices(): "
+ "could not inspect object property descriptions!\n");
+ } else {
+ if (opd.DataType == PTP_DTC_UINT32) {
+ if (bs == 0) {
+ bs = 32;
+ } else if (bs != 32) {
+ printf("LIBMTP PANIC: create_usb_mtp_devices(): "
+ "different objects support different object sizes!\n");
+ bs = 0;
+ break;
+ }
+ } else if (opd.DataType == PTP_DTC_UINT64) {
+ if (bs == 0) {
+ bs = 64;
+ } else if (bs != 64) {
+ printf("LIBMTP PANIC: create_usb_mtp_devices(): "
+ "different objects support different object sizes!\n");
+ bs = 0;
+ break;
+ }
+ } else {
+ // Ignore if other size.
+ printf("LIBMTP PANIC: create_usb_mtp_devices(): "
+ "awkward object size data type: %04x\n", opd.DataType);
+ bs = 0;
+ break;
+ }
+ }
}
-
- /* Only return the first device, release the rest */
- if(first_device->next != NULL)
- {
- LIBMTP_Release_Device_List(first_device->next);
- first_device->next = NULL;
+ if (bs == 0) {
+ // Could not detect object bitsize, assume 32 bits
+ bs = 32;
+ }
+ mtp_device->object_bitsize = bs;
+
+ /* No Errors yet for this device */
+ mtp_device->errorstack = NULL;
+
+ /* Default Max Battery Level, we will adjust this if possible */
+ mtp_device->maximum_battery_level = 100;
+
+ /* Check if device supports reading maximum battery level */
+ if(ptp_property_issupported( current_params,
+ PTP_DPC_BatteryLevel)) {
+ PTPDevicePropDesc dpd;
+
+ /* Try to read maximum battery level */
+ if(ptp_getdevicepropdesc(current_params,
+ PTP_DPC_BatteryLevel,
+ &dpd) != PTP_RC_OK) {
+ add_error_to_errorstack(mtp_device,
+ LIBMTP_ERROR_CONNECTING,
+ "Unable to read Maximum Battery Level for this "
+ "device even though the device supposedly "
+ "supports this functionality");
+ }
+
+ /* TODO: is this appropriate? */
+ /* If max battery level is 0 then leave the default, otherwise assign */
+ if (dpd.FORM.Range.MaximumValue.u8 != 0) {
+ mtp_device->maximum_battery_level = dpd.FORM.Range.MaximumValue.u8;
+ }
+
+ ptp_free_devicepropdesc(&dpd);
+ }
+
+ /* Set all default folders to 0 (root directory) */
+ mtp_device->default_music_folder = 0;
+ mtp_device->default_playlist_folder = 0;
+ mtp_device->default_picture_folder = 0;
+ mtp_device->default_video_folder = 0;
+ mtp_device->default_organizer_folder = 0;
+ mtp_device->default_zencast_folder = 0;
+ mtp_device->default_album_folder = 0;
+ mtp_device->default_text_folder = 0;
+
+ /* Set initial storage information */
+ mtp_device->storage = NULL;
+ if (LIBMTP_Get_Storage(mtp_device, LIBMTP_STORAGE_SORTBY_NOTSORTED) == -1) {
+ add_error_to_errorstack(mtp_device,
+ LIBMTP_ERROR_GENERAL,
+ "Get Storage information failed.");
+ mtp_device->storage = NULL;
}
- return first_device;
+ /*
+ * Then get the handles and try to locate the default folders.
+ * This has the desired side effect of caching all handles from
+ * the device which speeds up later operations.
+ */
+ flush_handles(mtp_device);
+
+ return mtp_device;
}
/**
* Recursive function that adds MTP devices to a linked list
- * @param devices a list of devices to be created.
+ * @param devices a list of raw devices to have real devices created for.
* @return a device pointer to a newly created mtpdevice (used in linked
* list creation).
*/
-static LIBMTP_mtpdevice_t * create_usb_mtp_devices(mtpdevice_list_t *devices)
+static LIBMTP_mtpdevice_t * create_usb_mtp_devices(LIBMTP_raw_device_t *devices, int numdevs)
{
- uint8_t i = 1;
+ uint8_t i;
LIBMTP_mtpdevice_t *mtp_device_list = NULL;
LIBMTP_mtpdevice_t *current_device = NULL;
- PTPParams *current_params;
- mtpdevice_list_t *tmplist = devices;
-
- while (tmplist != NULL) {
+
+ for (i=0; i < numdevs; i++) {
LIBMTP_mtpdevice_t *mtp_device;
- uint8_t bs = 0;
-
- /* Clear any handlers */
- tmplist->params->handles.Handler = NULL;
- tmplist->params->objectinfo = NULL;
- tmplist->params->props = NULL;
-
- /* Allocate dynamic space for our device */
- mtp_device = (LIBMTP_mtpdevice_t *) malloc(sizeof(LIBMTP_mtpdevice_t));
-
- /* Check if there was a memory allocation error */
- if(mtp_device == NULL) {
- /* There has been an memory allocation error. We are going to ignore this
- device and attempt to continue */
-
- /* TODO: This error statement could probably be a bit more robust */
- fprintf(stderr, "LIBMTP PANIC: connect_usb_devices encountered a memory "
- "allocation error with device %u, trying to continue",
- i);
-
- /* Prevent memory leaks for this device */
- free(tmplist->ptp_usb);
- tmplist->ptp_usb = NULL;
-
- free(tmplist->params);
- tmplist->params = NULL;
-
- /* We have freed a bit of memory so try again with the next device */
- tmplist = tmplist->next;
- i++;
- continue;
- }
-
- /* Copy device information to mtp_device structure */
- mtp_device->params = tmplist->params;
- mtp_device->usbinfo = tmplist->ptp_usb;
- current_params = tmplist->params;
-
- /* Cache the device information for later use */
- if (ptp_getdeviceinfo(current_params,
- ¤t_params->deviceinfo) != PTP_RC_OK) {
- fprintf(stderr, "LIBMTP PANIC: Unable to read device information on device "
- "number %u, trying to continue", i);
-
- /* Prevent memory leaks for this device */
- free(tmplist->ptp_usb);
- tmplist->ptp_usb = NULL;
-
- free(current_params);
- current_params = NULL;
- free(mtp_device);
-
- /* try again with the next device */
- tmplist = tmplist->next;
- i++;
- continue;
- }
+ mtp_device = LIBMTP_Open_Raw_Device(&devices[i]);
- /* Determine if the object size supported is 32 or 64 bit wide */
- for (i=0;i<current_params->deviceinfo.ImageFormats_len;i++) {
- PTPObjectPropDesc opd;
-
- if (ptp_mtp_getobjectpropdesc(current_params,
- PTP_OPC_ObjectSize,
- current_params->deviceinfo.ImageFormats[i],
- &opd) != PTP_RC_OK) {
- printf("LIBMTP PANIC: create_usb_mtp_devices(): "
- "could not inspect object property descriptions!\n");
- } else {
- if (opd.DataType == PTP_DTC_UINT32) {
- if (bs == 0) {
- bs = 32;
- } else if (bs != 32) {
- printf("LIBMTP PANIC: create_usb_mtp_devices(): "
- "different objects support different object sizes!\n");
- bs = 0;
- break;
- }
- } else if (opd.DataType == PTP_DTC_UINT64) {
- if (bs == 0) {
- bs = 64;
- } else if (bs != 64) {
- printf("LIBMTP PANIC: create_usb_mtp_devices(): "
- "different objects support different object sizes!\n");
- bs = 0;
- break;
- }
- } else {
- // Ignore if other size.
- printf("LIBMTP PANIC: create_usb_mtp_devices(): "
- "awkward object size data type: %04x\n", opd.DataType);
- bs = 0;
- break;
- }
- }
- }
- if (bs == 0) {
- // Could not detect object bitsize, assume 32 bits
- bs = 32;
- }
- mtp_device->object_bitsize = bs;
-
- /* No Errors yet for this device */
- mtp_device->errorstack = NULL;
-
- /* Default Max Battery Level, we will adjust this if possible */
- mtp_device->maximum_battery_level = 100;
-
- /* Check if device supports reading maximum battery level */
- if(ptp_property_issupported( current_params,
- PTP_DPC_BatteryLevel)) {
- PTPDevicePropDesc dpd;
-
- /* Try to read maximum battery level */
- if(ptp_getdevicepropdesc(current_params,
- PTP_DPC_BatteryLevel,
- &dpd) != PTP_RC_OK) {
- add_error_to_errorstack(mtp_device,
- LIBMTP_ERROR_CONNECTING,
- "Unable to read Maximum Battery Level for this "
- "device even though the device supposedly "
- "supports this functionality");
- }
-
- /* TODO: is this appropriate? */
- /* If max battery level is 0 then leave the default, otherwise assign */
- if (dpd.FORM.Range.MaximumValue.u8 != 0) {
- mtp_device->maximum_battery_level = dpd.FORM.Range.MaximumValue.u8;
- }
-
- ptp_free_devicepropdesc(&dpd);
- }
-
- /* Set all default folders to 0 (root directory) */
- mtp_device->default_music_folder = 0;
- mtp_device->default_playlist_folder = 0;
- mtp_device->default_picture_folder = 0;
- mtp_device->default_video_folder = 0;
- mtp_device->default_organizer_folder = 0;
- mtp_device->default_zencast_folder = 0;
- mtp_device->default_album_folder = 0;
- mtp_device->default_text_folder = 0;
-
- /* Set initial storage information */
- mtp_device->storage = NULL;
- if (LIBMTP_Get_Storage(mtp_device, LIBMTP_STORAGE_SORTBY_NOTSORTED) == -1) {
- add_error_to_errorstack(mtp_device,
- LIBMTP_ERROR_GENERAL,
- "Get Storage information failed.");
- mtp_device->storage = NULL;
- }
+ /* On error, try next device */
+ if (mtp_device == NULL)
+ continue;
- /*
- * Then get the handles and try to locate the default folders.
- * This has the desired side effect of caching all handles from
- * the device which speeds up later operations.
- */
- flush_handles(mtp_device);
-
/* Add the device to the list */
mtp_device->next = NULL;
if (mtp_device_list == NULL) {
@@ -1045,9 +1067,6 @@
current_device->next = mtp_device;
current_device = mtp_device;
}
-
- tmplist = tmplist->next;
- i++;
}
return mtp_device_list;
}
@@ -1078,20 +1097,26 @@
*/
LIBMTP_error_number_t LIBMTP_Get_Connected_Devices(LIBMTP_mtpdevice_t **device_list)
{
- mtpdevice_list_t *devices;
+ LIBMTP_raw_device_t *devices;
+ int numdevs;
LIBMTP_error_number_t ret;
-
- ret = find_usb_devices(&devices);
+
+ ret = LIBMTP_Detect_Raw_Devices(&devices, &numdevs);
if (ret != LIBMTP_ERROR_NONE) {
*device_list = NULL;
return ret;
}
/* Assign linked list of devices */
- *device_list = create_usb_mtp_devices(devices);
+ if (devices == NULL || numdevs == 0) {
+ *device_list = NULL;
+ return LIBMTP_ERROR_NO_DEVICE_ATTACHED;
+ }
+
+ *device_list = create_usb_mtp_devices(devices, numdevs);
+ free(devices);
/* TODO: Add wifi device access here */
- free_mtpdevice_list(devices);
/* We have found some devices but create failed */
if (*device_list == NULL)
@@ -1285,7 +1310,7 @@
MTPProperties *prop;
uint16_t ret;
- ret = ptp_mtp_getobjectproplist (params, 0xffffffff, &props, &nrofprops);
+ ret = ptp_mtp_getobjectproplist(params, 0xffffffff, &props, &nrofprops);
if (ret == PTP_RC_MTP_Specification_By_Group_Unsupported) {
// What's the point in the device implementing this command if
@@ -1300,12 +1325,19 @@
"could not get proplist of all objects.");
return -1;
}
+ if (props == NULL && nrofprops != 0) {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL,
+ "get_all_metadata_fast(): "
+ "call to ptp_mtp_getobjectproplist() returned "
+ "inconsistent results.");
+ return -1;
+ }
params->props = props; /* cache it */
params->nrofprops = nrofprops; /* cache it */
/*
* We count the number of objects by counting the ObjectHandle
- * references, whenever it changes we get a new objects, when it's
+ * references, whenever it changes we get a new object, when it's
* the same, it is just different properties of the same object.
*/
prop = props;
@@ -1475,8 +1507,8 @@
params->nrofprops = 0;
if (ptp_operation_issupported(params,PTP_OC_MTP_GetObjPropList)
- && !(ptp_usb->device_flags & DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST)
- && !(ptp_usb->device_flags & DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL)) {
+ && !FLAG_BROKEN_MTPGETOBJPROPLIST(ptp_usb)
+ && !FLAG_BROKEN_MTPGETOBJPROPLIST_ALL(ptp_usb)) {
// Use the fast method. Ignore return value for now.
ret = get_all_metadata_fast(device, PTP_GOH_ALL_STORAGE);
}
@@ -1501,7 +1533,12 @@
}
}
}
-
+
+ /*
+ * Loop over the handles, fix up any NULL filenames or
+ * keywords, then attempt to locate some default folders
+ * in the root directory of the primary storage.
+ */
for(i = 0; i < params->handles.n; i++) {
PTPObjectInfo *oi;
@@ -1516,8 +1553,13 @@
/* Ignore handles that point to non-folders */
if(oi->ObjectFormat != PTP_OFC_Association)
continue;
- if (oi->Filename == NULL)
+ /* Only look in the root folder */
+ if (oi->ParentObject != 0x00000000U)
+ continue;
+ /* Only look in the primary storage */
+ if (device->storage != NULL && oi->StorageID != device->storage->id)
continue;
+
/* Is this the Music Folder */
if (!strcasecmp(oi->Filename, "My Music") ||
@@ -1544,7 +1586,8 @@
device->default_organizer_folder =
params->handles.Handler[i];
}
- else if (!strcasecmp(oi->Filename, "ZENcast")) {
+ else if (!strcasecmp(oi->Filename, "ZENcast") ||
+ !strcasecmp(oi->Filename, "Datacasts")) {
device->default_zencast_folder =
params->handles.Handler[i];
}
@@ -1553,7 +1596,8 @@
device->default_album_folder =
params->handles.Handler[i];
}
- else if (!strcasecmp(oi->Filename, "Text")) {
+ else if (!strcasecmp(oi->Filename, "Text") ||
+ !strcasecmp(oi->Filename, "Texts")) {
device->default_text_folder =
params->handles.Handler[i];
}
@@ -2003,9 +2047,9 @@
printf(" StorageType: 0x%04x\n",storage->StorageType);
printf(" FilesystemType: 0x%04x\n",storage->FilesystemType);
printf(" AccessCapability: 0x%04x\n",storage->AccessCapability);
- printf(" MaxCapacity: %lld\n",storage->MaxCapacity);
- printf(" FreeSpaceInBytes: %lld\n",storage->FreeSpaceInBytes);
- printf(" FreeSpaceInObjects: %lld\n",storage->FreeSpaceInObjects);
+ printf(" MaxCapacity: %llu\n", (long long unsigned int) storage->MaxCapacity);
+ printf(" FreeSpaceInBytes: %llu\n", (long long unsigned int) storage->FreeSpaceInBytes);
+ printf(" FreeSpaceInObjects: %llu\n", (long long unsigned int) storage->FreeSpaceInObjects);
printf(" StorageDescription: %s\n",storage->StorageDescription);
printf(" VolumeIdentifier: %s\n",storage->VolumeIdentifier);
storage = storage->next;
@@ -2048,6 +2092,24 @@
}
/**
+ * This retrieves the manufacturer name of an MTP device.
+ * @param device a pointer to the device to get the manufacturer name for.
+ * @return a newly allocated UTF-8 string representing the manufacturer name.
+ * The string must be freed by the caller after use. If the call
+ * was unsuccessful this will contain NULL.
+ */
+char *LIBMTP_Get_Manufacturername(LIBMTP_mtpdevice_t *device)
+{
+ char *retmanuf = NULL;
+ PTPParams *params = (PTPParams *) device->params;
+
+ if (params->deviceinfo.Manufacturer != NULL) {
+ retmanuf = strdup(params->deviceinfo.Manufacturer);
+ }
+ return retmanuf;
+}
+
+/**
* This retrieves the model name (often equal to product name)
* of an MTP device.
* @param device a pointer to the device to get the model name for.
@@ -2443,6 +2505,7 @@
uint16_t * const length)
{
PTPParams *params = (PTPParams *) device->params;
+ PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo;
uint16_t *localtypes;
uint16_t localtypelen;
uint32_t i;
@@ -2458,6 +2521,12 @@
localtypelen++;
}
}
+ // The forgotten Ogg support on YP-10 and others...
+ if (FLAG_OGG_IS_UNKNOWN(ptp_usb)) {
+ localtypes = (uint16_t *) realloc(localtypes, (params->deviceinfo.ImageFormats_len+1) * sizeof(uint16_t));
+ localtypes[localtypelen] = LIBMTP_FILETYPE_OGG;
+ localtypelen++;
+ }
*filetypes = localtypes;
*length = localtypelen;
@@ -2466,12 +2535,21 @@
}
/**
- * This function retrieves all the storage id's of a device and there
- * properties. Then creates a linked list and puts the list head into
+ * This function updates all the storage id's of a device and their
+ * properties, then creates a linked list and puts the list head into
* the device struct. It also optionally sorts this list. If you want
* to display storage information in your application you should call
- * this function, then dereference the device struct
- * (<code>device->storage</code>) to get out information on the storage.
+ * this function, then dereference the device struct
+ * (<code>device->storage</code>) to get out information on the storage.
+ *
+ * You need to call this everytime you want to update the
+ * <code>device->storage</code> list, for example anytime you need
+ * to check available storage somewhere.
+ *
+ * <b>WARNING:</b> since this list is dynamically updated, do not
+ * reference its fields in external applications by pointer! E.g
+ * do not put a reference to any <code>char *</code> field. instead
+ * <code>strncpy()</code> it!
*
* @param device a pointer to the device to get the filetype capabilities for.
* @param sortby an integer that determines the sorting of the storage list.
@@ -2480,7 +2558,6 @@
* sort.
* @return 0 on success, 1 success but only with storage id's, storage
* properities could not be retrieved and -1 means failure.
- * @see LIBMTP_Get_Filetype_Description()
*/
int LIBMTP_Get_Storage(LIBMTP_mtpdevice_t *device, int const sortby)
{
@@ -2591,6 +2668,9 @@
return NULL;
}
new->filename = NULL;
+ new->item_id = 0;
+ new->parent_id = 0;
+ new->storage_id = 0;
new->filesize = 0;
new->filetype = LIBMTP_FILETYPE_UNKNOWN;
new->next = NULL;
@@ -2629,7 +2709,7 @@
/**
* This returns a long list of all files available
- * on the current MTP device. Typical usage:
+ * on the current MTP device. Folders will not be returned. Typical usage:
*
* <pre>
* LIBMTP_file_t *filelist;
@@ -2695,6 +2775,7 @@
file = LIBMTP_new_file_t();
file->parent_id = oi->ParentObject;
+ file->storage_id = oi->StorageID;
// This is some sort of unique ID so we can keep track of the track.
file->item_id = params->handles.Handler[i];
@@ -2735,7 +2816,7 @@
prop ++;
}
} else if (ptp_operation_issupported(params,PTP_OC_MTP_GetObjPropList)
- && !(ptp_usb->device_flags & DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST)) {
+ && !FLAG_BROKEN_MTPGETOBJPROPLIST(ptp_usb)) {
MTPProperties *props = NULL;
MTPProperties *prop;
@@ -2751,6 +2832,13 @@
add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Filelisting_With_Callback(): call to ptp_mtp_getobjectproplist() failed.");
// Silently fall through.
}
+ if (props == NULL && nrofprops != 0) {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL,
+ "LIBMTP_Get_Filelisting_With_Callback: "
+ "call to ptp_mtp_getobjectproplist() returned "
+ "inconsistent results.");
+ nrofprops = 0;
+ }
if (props != NULL) {
int i;
prop = props;
@@ -2823,6 +2911,10 @@
* <code>LIBMTP_Get_Filelisting()</code> and cache the file, preferably
* as an efficient data structure such as a hash list.
*
+ * Incidentally this function will return metadata for
+ * a folder (association) as well, but this is not a proper use
+ * of it, it is intended for file manipulation, not folder manipulation.
+ *
* @param device a pointer to the device to get the file metadata from.
* @param fileid the object ID of the file that you want the metadata for.
* @return a metadata entry on success or NULL on failure.
@@ -2851,16 +2943,11 @@
oi = ¶ms->objectinfo[i];
- if (oi->ObjectFormat == PTP_OFC_Association) {
- // MTP use thesis object format for folders which means
- // these "files" will turn up on a folder listing instead.
- return NULL;
- }
-
// Allocate a new file type
file = LIBMTP_new_file_t();
file->parent_id = oi->ParentObject;
+ file->storage_id = oi->StorageID;
// Set the filetype
file->filetype = map_ptp_type_to_libmtp_type(oi->ObjectFormat);
@@ -2898,7 +2985,7 @@
}
}
} else if (ptp_operation_issupported(params,PTP_OC_MTP_GetObjPropList)
- && !(ptp_usb->device_flags & DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST)) {
+ && !FLAG_BROKEN_MTPGETOBJPROPLIST(ptp_usb)) {
MTPProperties *props = NULL;
MTPProperties *prop;
int nrofprops;
@@ -2910,9 +2997,17 @@
*/
ret = ptp_mtp_getobjectproplist(params, file->item_id, &props, &nrofprops);
if (ret != PTP_RC_OK) {
- add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Filelisting_With_Callback(): call to ptp_mtp_getobjectproplist() failed.");
+ add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Filelisting_With_Callback(): "
+ "call to ptp_mtp_getobjectproplist() failed.");
// Silently fall through.
}
+ if (props == NULL && nrofprops != 0) {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL,
+ "LIBMTP_Get_Filelisting_With_Callback(): "
+ "call to ptp_mtp_getobjectproplist() returned "
+ "inconsistent results.");
+ return NULL;
+ }
prop = props;
for (i=0;i<nrofprops;i++) {
if ((prop->ObjectHandle == file->item_id) && (prop->property == PTP_OPC_ObjectSize)) {
@@ -2984,8 +3079,12 @@
if (new == NULL) {
return NULL;
}
+ new->item_id = 0;
+ new->parent_id = 0;
+ new->storage_id = 0;
new->title = NULL;
new->artist = NULL;
+ new->composer = NULL;
new->album = NULL;
new->genre = NULL;
new->date = NULL;
@@ -3021,6 +3120,8 @@
free(track->title);
if (track->artist != NULL)
free(track->artist);
+ if (track->composer != NULL)
+ free(track->composer);
if (track->album != NULL)
free(track->album);
if (track->genre != NULL)
@@ -3051,6 +3152,12 @@
else
track->artist = NULL;
break;
+ case PTP_OPC_Composer:
+ if (prop->propval.str != NULL)
+ track->composer = strdup(prop->propval.str);
+ else
+ track->composer = NULL;
+ break;
case PTP_OPC_Duration:
track->duration = prop->propval.u32;
break;
@@ -3137,7 +3244,7 @@
pick_property_to_track_metadata(device, prop, track);
}
} else if (ptp_operation_issupported(params,PTP_OC_MTP_GetObjPropList)
- && !(ptp_usb->device_flags & DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST)) {
+ && !FLAG_BROKEN_MTPGETOBJPROPLIST(ptp_usb)) {
MTPProperties *props = NULL;
MTPProperties *prop;
int nrofprops;
@@ -3152,6 +3259,13 @@
add_ptp_error_to_errorstack(device, ret, "get_track_metadata(): call to ptp_mtp_getobjectproplist() failed.");
return;
}
+ if (props == NULL && nrofprops != 0) {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL,
+ "get_track_metadata(): "
+ "call to ptp_mtp_getobjectproplist() returned "
+ "inconsistent results.");
+ return;
+ }
prop = props;
for (i=0;i<nrofprops;i++,prop++) {
if (prop->ObjectHandle == track->item_id)
@@ -3177,6 +3291,9 @@
case PTP_OPC_Artist:
track->artist = get_string_from_object(device, track->item_id, PTP_OPC_Artist);
break;
+ case PTP_OPC_Composer:
+ track->composer = get_string_from_object(device, track->item_id, PTP_OPC_Composer);
+ break;
case PTP_OPC_Duration:
track->duration = get_u32_from_object(device, track->item_id, PTP_OPC_Duration, 0);
break;
@@ -3291,29 +3408,26 @@
for (i = 0; i < params->handles.n; i++) {
LIBMTP_track_t *track;
PTPObjectInfo *oi;
+ LIBMTP_filetype_t mtptype;
if (callback != NULL)
callback(i, params->handles.n, data);
oi = ¶ms->objectinfo[i];
+ mtptype = map_ptp_type_to_libmtp_type(oi->ObjectFormat);
// Ignore stuff we don't know how to handle...
// TODO: get this list as an intersection of the sets
// supported by the device and the from the device and
// all known audio track files?
- if ( oi->ObjectFormat != PTP_OFC_WAV &&
- oi->ObjectFormat != PTP_OFC_MP3 &&
- oi->ObjectFormat != PTP_OFC_MTP_MP2 &&
- oi->ObjectFormat != PTP_OFC_MTP_WMA &&
- oi->ObjectFormat != PTP_OFC_MTP_OGG &&
- oi->ObjectFormat != PTP_OFC_MTP_FLAC &&
- oi->ObjectFormat != PTP_OFC_MTP_AAC &&
- oi->ObjectFormat != PTP_OFC_MTP_M4A &&
- oi->ObjectFormat != PTP_OFC_MTP_MP4 &&
- oi->ObjectFormat != PTP_OFC_MTP_UndefinedAudio &&
- // This row lets through undefined files for examination since they may be forgotten OGG files.
- (oi->ObjectFormat != PTP_OFC_Undefined || !(ptp_usb->device_flags & DEVICE_FLAG_IRIVER_OGG_ALZHEIMER))
- ) {
+ if (!LIBMTP_FILETYPE_IS_AUDIO(mtptype) &&
+ !LIBMTP_FILETYPE_IS_VIDEO(mtptype) &&
+ !LIBMTP_FILETYPE_IS_AUDIOVIDEO(mtptype) &&
+ // This row lets through undefined files for examination since they may be forgotten OGG files.
+ (oi->ObjectFormat != PTP_OFC_Undefined ||
+ !FLAG_IRIVER_OGG_ALZHEIMER(ptp_usb) ||
+ !FLAG_OGG_IS_UNKNOWN(ptp_usb))
+ ) {
// printf("Not a music track (format: %d), skipping...\n",oi.ObjectFormat);
continue;
}
@@ -3324,8 +3438,9 @@
// This is some sort of unique ID so we can keep track of the track.
track->item_id = params->handles.Handler[i];
track->parent_id = oi->ParentObject;
+ track->storage_id = oi->StorageID;
- track->filetype = map_ptp_type_to_libmtp_type(oi->ObjectFormat);
+ track->filetype = mtptype;
// Original file-specific properties
track->filesize = oi->ObjectCompressedSize;
@@ -3344,7 +3459,8 @@
* for these bugged devices only.
*/
if (track->filetype == LIBMTP_FILETYPE_UNKNOWN &&
- ptp_usb->device_flags & DEVICE_FLAG_IRIVER_OGG_ALZHEIMER) {
+ (FLAG_IRIVER_OGG_ALZHEIMER(ptp_usb) ||
+ FLAG_OGG_IS_UNKNOWN(ptp_usb))) {
// Repair forgotten OGG filetype
char *ptype;
@@ -3403,6 +3519,7 @@
for (i = 0; i < params->handles.n; i++) {
PTPObjectInfo *oi;
LIBMTP_track_t *track;
+ LIBMTP_filetype_t mtptype;
// Skip if this is not the track we want.
if (params->handles.Handler[i] != trackid) {
@@ -3410,18 +3527,12 @@
}
oi = ¶ms->objectinfo[i];
+ mtptype = map_ptp_type_to_libmtp_type(oi->ObjectFormat);
// Ignore stuff we don't know how to handle...
- if ( oi->ObjectFormat != PTP_OFC_WAV &&
- oi->ObjectFormat != PTP_OFC_MP3 &&
- oi->ObjectFormat != PTP_OFC_MTP_MP2 &&
- oi->ObjectFormat != PTP_OFC_MTP_WMA &&
- oi->ObjectFormat != PTP_OFC_MTP_OGG &&
- oi->ObjectFormat != PTP_OFC_MTP_FLAC &&
- oi->ObjectFormat != PTP_OFC_MTP_AAC &&
- oi->ObjectFormat != PTP_OFC_MTP_M4A &&
- oi->ObjectFormat != PTP_OFC_MTP_MP4 &&
- oi->ObjectFormat != PTP_OFC_MTP_UndefinedAudio ) {
+ if (!LIBMTP_FILETYPE_IS_AUDIO(mtptype) &&
+ !LIBMTP_FILETYPE_IS_VIDEO(mtptype) &&
+ !LIBMTP_FILETYPE_IS_AUDIOVIDEO(mtptype)) {
return NULL;
}
@@ -3431,8 +3542,9 @@
// This is some sort of unique ID so we can keep track of the track.
track->item_id = params->handles.Handler[i];
track->parent_id = oi->ParentObject;
+ track->storage_id = oi->StorageID;
- track->filetype = map_ptp_type_to_libmtp_type(oi->ObjectFormat);
+ track->filetype = mtptype;
// Original file-specific properties
track->filesize = oi->ObjectCompressedSize;
@@ -3639,17 +3751,30 @@
* @param device a pointer to the device to send the track to.
* @param path the filename of a local file which will be sent.
* @param metadata a track metadata set to be written along with the file.
+ * After this call the field <code>metadata->item_id</code>
+ * will contain the new track ID. Other fields such
+ * as the <code>metadata->filename</code>, <code>metadata->parent_id</code>
+ * or <code>metadata->storage_id</code> may also change during this
+ * operation due to device restrictions, so do not rely on the
+ * contents of this struct to be preserved in any way.
+ * <ul>
+ * <li><code>metadata->parent_id</code> should be set to the parent
+ * (e.g. folder) to store this track in. Since some
+ * devices are a bit picky about where files
+ * are placed, a default folder will be chosen if libmtp
+ * has detected one for the current filetype and this
+ * parameter is set to 0. If this is 0 and no default folder
+ * can be found, the file will be stored in the root folder.
+ * <li><code>metadata->storage_id</code> should be set to the
+ * desired storage (e.g. memory card or whatever your device
+ * presents) to store this track in. Setting this to 0 will store
+ * the track on the primary storage.
+ * </ul>
* @param callback a progress indicator function or NULL to ignore.
* @param data a user-defined pointer that is passed along to
* the <code>progress</code> function in order to
* pass along some user defined data to the progress
* updates. If not used, set this to NULL.
- * @param parenthandle the parent (e.g. folder) to store this file
- * in. Since some devices are a bit picky about where files
- * are placed, a default folder will be chosen if libmtp
- * has detected one for the current filetype and this
- * parameter is set to 0. If this is 0 and no default folder
- * can be found, the file will be stored in the root folder.
* @return 0 if the transfer was successful, any other value means
* failure.
* @see LIBMTP_Send_Track_From_File_Descriptor()
@@ -3659,7 +3784,7 @@
int LIBMTP_Send_Track_From_File(LIBMTP_mtpdevice_t *device,
char const * const path, LIBMTP_track_t * const metadata,
LIBMTP_progressfunc_t const callback,
- void const * const data, uint32_t const parenthandle)
+ void const * const data)
{
int fd;
int ret;
@@ -3688,7 +3813,7 @@
return -1;
}
- ret = LIBMTP_Send_Track_From_File_Descriptor(device, fd, metadata, callback, data, parenthandle);
+ ret = LIBMTP_Send_Track_From_File_Descriptor(device, fd, metadata, callback, data);
// Close file.
#ifdef USE_WINDOWS_IO_H
@@ -3709,19 +3834,30 @@
* @param device a pointer to the device to send the track to.
* @param fd the filedescriptor for a local file which will be sent.
* @param metadata a track metadata set to be written along with the file.
- * After this call the field <code>item_id</code>
- * will contain the new track ID.
+ * After this call the field <code>metadata->item_id</code>
+ * will contain the new track ID. Other fields such
+ * as the <code>metadata->filename</code>, <code>metadata->parent_id</code>
+ * or <code>metadata->storage_id</code> may also change during this
+ * operation due to device restrictions, so do not rely on the
+ * contents of this struct to be preserved in any way.
+ * <ul>
+ * <li><code>metadata->parent_id</code> should be set to the parent
+ * (e.g. folder) to store this track in. Since some
+ * devices are a bit picky about where files
+ * are placed, a default folder will be chosen if libmtp
+ * has detected one for the current filetype and this
+ * parameter is set to 0. If this is 0 and no default folder
+ * can be found, the file will be stored in the root folder.
+ * <li><code>metadata->storage_id</code> should be set to the
+ * desired storage (e.g. memory card or whatever your device
+ * presents) to store this track in. Setting this to 0 will store
+ * the track on the primary storage.
+ * </ul>
* @param callback a progress indicator function or NULL to ignore.
* @param data a user-defined pointer that is passed along to
* the <code>progress</code> function in order to
* pass along some user defined data to the progress
* updates. If not used, set this to NULL.
- * @param parenthandle the parent (e.g. folder) to store this file
- * in. Since some devices are a bit picky about where files
- * are placed, a default folder will be chosen if libmtp
- * has detected one for the current filetype and this
- * parameter is set to 0. If this is 0 and no default folder
- * can be found, the file will be stored in the root folder.
* @return 0 if the transfer was successful, any other value means
* failure.
* @see LIBMTP_Send_Track_From_File()
@@ -3730,29 +3866,22 @@
int LIBMTP_Send_Track_From_File_Descriptor(LIBMTP_mtpdevice_t *device,
int const fd, LIBMTP_track_t * const metadata,
LIBMTP_progressfunc_t const callback,
- void const * const data, uint32_t const parenthandle)
+ void const * const data)
{
int subcall_ret;
LIBMTP_file_t filedata;
// Sanity check, is this really a track?
- if (metadata->filetype != LIBMTP_FILETYPE_WAV &&
- metadata->filetype != LIBMTP_FILETYPE_MP3 &&
- metadata->filetype != LIBMTP_FILETYPE_MP2 &&
- metadata->filetype != LIBMTP_FILETYPE_WMA &&
- metadata->filetype != LIBMTP_FILETYPE_OGG &&
- metadata->filetype != LIBMTP_FILETYPE_FLAC &&
- metadata->filetype != LIBMTP_FILETYPE_AAC &&
- metadata->filetype != LIBMTP_FILETYPE_M4A &&
- metadata->filetype != LIBMTP_FILETYPE_MP4 &&
- metadata->filetype != LIBMTP_FILETYPE_UNDEF_AUDIO) {
- printf("LIBMTP_Send_Track_From_File_Descriptor(): "
- "I don't think this is actually a track, strange filetype...\n");
+ if (!LIBMTP_FILETYPE_IS_TRACK(metadata->filetype)) {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL,
+ "LIBMTP_Send_Track_From_File_Descriptor(): "
+ "I don't think this is actually a track, strange filetype...");
}
// Wrap around the file transfer function
filedata.item_id = metadata->item_id;
filedata.parent_id = metadata->parent_id;
+ filedata.storage_id = metadata->storage_id;
filedata.filename = metadata->filename;
filedata.filesize = metadata->filesize;
filedata.filetype = metadata->filetype;
@@ -3762,20 +3891,21 @@
fd,
&filedata,
callback,
- data,
- parenthandle);
+ data);
if (subcall_ret != 0) {
- add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Send_Track_From_File_Descriptor(): "
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL,
+ "LIBMTP_Send_Track_From_File_Descriptor(): "
"subcall to LIBMTP_Send_File_From_File_Descriptor failed.");
// We used to delete the file here, but don't... It might be OK after all.
// (void) LIBMTP_Delete_Object(device, metadata->item_id);
return -1;
}
- // Pick up new item (and parent) ID
+ // Pick up new item (and parent, storage) ID
metadata->item_id = filedata.item_id;
metadata->parent_id = filedata.parent_id;
+ metadata->storage_id = filedata.storage_id;
// Set track metadata for the new fine track
subcall_ret = LIBMTP_Update_Track_Metadata(device, metadata);
@@ -3798,20 +3928,27 @@
* given as input.
* @param device a pointer to the device to send the track to.
* @param path the filename of a local file which will be sent.
- * @param filedata a file strtuct to pass in info about the file.
- * After this call the field <code>item_id</code>
- * will contain the new file ID.
+ * @param filedata a file metadata set to be written along with the file.
+ * After this call the field <code>filedata->item_id</code>
+ * will contain the new file ID. Other fields such
+ * as the <code>filedata->filename</code>, <code>filedata->parent_id</code>
+ * or <code>filedata->storage_id</code> may also change during this
+ * operation due to device restrictions, so do not rely on the
+ * contents of this struct to be preserved in any way.
+ * <ul>
+ * <li><code>filedata->parent_id</code> should be set to the parent
+ * (e.g. folder) to store this file in. If this is 0,
+ * the file will be stored in the root folder.
+ * <li><code>filedata->storage_id</code> should be set to the
+ * desired storage (e.g. memory card or whatever your device
+ * presents) to store this file in. Setting this to 0 will store
+ * the file on the primary storage.
+ * </ul>
* @param callback a progress indicator function or NULL to ignore.
* @param data a user-defined pointer that is passed along to
* the <code>progress</code> function in order to
* pass along some user defined data to the progress
* updates. If not used, set this to NULL.
- * @param parenthandle the parent (e.g. folder) to store this file
- * in. Since some devices are a bit picky about where files
- * are placed, a default folder will be chosen if libmtp
- * has detected one for the current filetype and this
- * parameter is set to 0. If this is 0 and no default folder
- * can be found, the file will be stored in the root folder.
* @return 0 if the transfer was successful, any other value means
* failure.
* @see LIBMTP_Send_File_From_File_Descriptor()
@@ -3820,7 +3957,7 @@
int LIBMTP_Send_File_From_File(LIBMTP_mtpdevice_t *device,
char const * const path, LIBMTP_file_t * const filedata,
LIBMTP_progressfunc_t const callback,
- void const * const data, uint32_t const parenthandle)
+ void const * const data)
{
int fd;
int ret;
@@ -3849,7 +3986,7 @@
return -1;
}
- ret = LIBMTP_Send_File_From_File_Descriptor(device, fd, filedata, callback, data, parenthandle);
+ ret = LIBMTP_Send_File_From_File_Descriptor(device, fd, filedata, callback, data);
// Close file.
#ifdef USE_WINDOWS_IO_H
@@ -3872,20 +4009,27 @@
*
* @param device a pointer to the device to send the file to.
* @param fd the filedescriptor for a local file which will be sent.
- * @param filedata a file strtuct to pass in info about the file.
- * After this call the field <code>item_id</code>
- * will contain the new track ID.
+ * @param filedata a file metadata set to be written along with the file.
+ * After this call the field <code>filedata->item_id</code>
+ * will contain the new file ID. Other fields such
+ * as the <code>filedata->filename</code>, <code>filedata->parent_id</code>
+ * or <code>filedata->storage_id</code> may also change during this
+ * operation due to device restrictions, so do not rely on the
+ * contents of this struct to be preserved in any way.
+ * <ul>
+ * <li><code>filedata->parent_id</code> should be set to the parent
+ * (e.g. folder) to store this file in. If this is 0,
+ * the file will be stored in the root folder.
+ * <li><code>filedata->storage_id</code> should be set to the
+ * desired storage (e.g. memory card or whatever your device
+ * presents) to store this file in. Setting this to 0 will store
+ * the file on the primary storage.
+ * </ul>
* @param callback a progress indicator function or NULL to ignore.
* @param data a user-defined pointer that is passed along to
* the <code>progress</code> function in order to
* pass along some user defined data to the progress
* updates. If not used, set this to NULL.
- * @param parenthandle the parent (e.g. folder) to store this file
- * in. Since some devices are a bit picky about where files
- * are placed, a default folder will be chosen if libmtp
- * has detected one for the current filetype and this
- * parameter is set to 0. If this is 0 and no default folder
- * can be found, the file will be stored in the root folder.
* @return 0 if the transfer was successful, any other value means
* failure.
* @see LIBMTP_Send_File_From_File()
@@ -3895,17 +4039,19 @@
int LIBMTP_Send_File_From_File_Descriptor(LIBMTP_mtpdevice_t *device,
int const fd, LIBMTP_file_t * const filedata,
LIBMTP_progressfunc_t const callback,
- void const * const data, uint32_t const parenthandle)
+ void const * const data)
{
uint16_t ret;
- LIBMTP_devicestorage_t *storage;
uint32_t store;
- uint32_t localph = parenthandle;
+ uint32_t localph = filedata->parent_id;
+ LIBMTP_devicestorage_t *storage;
PTPParams *params = (PTPParams *) device->params;
PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo;
int i;
int subcall_ret;
uint16_t of = map_libmtp_type_to_ptp_type(filedata->filetype);
+ LIBMTP_file_t *newfilemeta;
+ int use_primary_storage = 1;
// Sanity check: no zerolength files.
if (filedata->filesize == 0) {
@@ -3914,25 +4060,34 @@
return -1;
}
- // See if there is some storage we can fit this file on.
- storage = device->storage;
- if (storage == NULL) {
- // Sometimes the storage just cannot be detected.
- store = 0x00000000U;
+ if (filedata->storage_id != 0) {
+ store = filedata->storage_id;
} else {
- while(storage != NULL) {
- subcall_ret = check_if_file_fits(device, storage, filedata->filesize);
- if (subcall_ret != 0) {
- storage = storage->next;
- }
- break;
- }
+ // See if there is some storage we can fit this file on.
+ storage = device->storage;
if (storage == NULL) {
- add_error_to_errorstack(device, LIBMTP_ERROR_STORAGE_FULL, "LIBMTP_Send_File_From_File_Descriptor(): "
- "all device storage is full or corrupt.");
- return -1;
+ // Sometimes the storage just cannot be detected.
+ store = 0x00000000U;
+ } else {
+ while(storage != NULL) {
+ subcall_ret = check_if_file_fits(device, storage, filedata->filesize);
+ if (subcall_ret != 0) {
+ storage = storage->next;
+ }
+ break;
+ }
+ if (storage == NULL) {
+ add_error_to_errorstack(device, LIBMTP_ERROR_STORAGE_FULL, "LIBMTP_Send_File_From_File_Descriptor(): "
+ "all device storage is full or corrupt.");
+ return -1;
+ }
+ store = storage->id;
}
- store = storage->id;
+ }
+ // Detect if something non-primary is in use.
+ storage = device->storage;
+ if (store != storage->id) {
+ use_primary_storage = 0;
}
/*
@@ -3942,31 +4097,14 @@
* do I know, we use a fixed list in lack of any better method.
* Some devices obviously need to have their files in certain
* folders in order to find/display them at all (hello Creative),
- * so we have to have a method for this.
+ * so we have to have a method for this. We only do this if the
+ * primary storage is in use.
*/
- if (localph == 0) {
- if (of == PTP_OFC_WAV ||
- of == PTP_OFC_MP3 ||
- of == PTP_OFC_MTP_MP2 ||
- of == PTP_OFC_MTP_WMA ||
- of == PTP_OFC_MTP_OGG ||
- of == PTP_OFC_MTP_FLAC ||
- of == PTP_OFC_MTP_AAC ||
- of == PTP_OFC_MTP_M4A ||
- of == PTP_OFC_AIFF ||
- //of == PTP_OFC_MTP_MP4 || /* ambiguous mp4 can contain video */
- of == PTP_OFC_MTP_AudibleCodec ||
- of == PTP_OFC_MTP_UndefinedAudio) {
+ if (localph == 0 && use_primary_storage) {
+ if (LIBMTP_FILETYPE_IS_AUDIO(filedata->filetype)) {
localph = device->default_music_folder;
- } else if (of == PTP_OFC_MTP_WMV ||
- of == PTP_OFC_AVI ||
- of == PTP_OFC_MPEG ||
- of == PTP_OFC_ASF ||
- of == PTP_OFC_QT ||
- of == PTP_OFC_MTP_3GP ||
- of == PTP_OFC_MTP_MP4 || /* ambiguous mp4 can also contain only audio */
- of == PTP_OFC_MTP_UndefinedVideo) {
+ } else if (LIBMTP_FILETYPE_IS_VIDEO(filedata->filetype)) {
localph = device->default_video_folder;
} else if (of == PTP_OFC_EXIF_JPEG ||
of == PTP_OFC_JP2 ||
@@ -3987,12 +4125,17 @@
of == PTP_OFC_MTP_vCard3 ||
of == PTP_OFC_MTP_UndefinedCalendarItem) {
localph = device->default_organizer_folder;
- } else if (of == PTP_OFC_Text
- ) {
+ } else if (of == PTP_OFC_Text) {
localph = device->default_text_folder;
}
}
+ // Here we wire the type to unknown on bugged, but
+ // Ogg-supportive devices.
+ if (FLAG_OGG_IS_UNKNOWN(ptp_usb) && of == PTP_OFC_MTP_OGG) {
+ of = PTP_OFC_Undefined;
+ }
+
if (ptp_operation_issupported(params,PTP_OC_MTP_SendObjectPropList)) {
/*
* MTP enhanched does it this way (from a sniff):
@@ -4059,7 +4202,7 @@
uint16_t *properties = NULL;
uint32_t propcnt = 0;
- // default handle
+ // default parent handle
if (localph == 0)
localph = 0xFFFFFFFFU; // Set to -1
@@ -4084,7 +4227,7 @@
prop->datatype = PTP_DTC_STR;
if (filedata->filename != NULL) {
prop->propval.str = strdup(filedata->filename);
- if (ptp_usb->device_flags & DEVICE_FLAG_ONLY_7BIT_FILENAMES) {
+ if (FLAG_ONLY_7BIT_FILENAMES(ptp_usb)) {
strip_7bit_from_utf8(prop->propval.str);
}
}
@@ -4145,7 +4288,7 @@
memset(&new_file, 0, sizeof(PTPObjectInfo));
new_file.Filename = filedata->filename;
- if (ptp_usb->device_flags & DEVICE_FLAG_ONLY_7BIT_FILENAMES) {
+ if (FLAG_ONLY_7BIT_FILENAMES(ptp_usb)) {
strip_7bit_from_utf8(new_file.Filename);
}
// We loose precision here.
@@ -4171,7 +4314,7 @@
// Now there IS an object with this parent handle.
filedata->parent_id = localph;
-
+
// Callbacks
ptp_usb->callback_active = 1;
// The callback will deactivate itself after this amount of data has been sent
@@ -4198,13 +4341,31 @@
}
add_object_to_cache(device, filedata->item_id);
+
+ /*
+ * Get the device-assined parent_id from the cache.
+ * The operation that adds it to the cache will
+ * look it up from the device, so we get the new
+ * parent_id from the cache.
+ */
+ newfilemeta = LIBMTP_Get_Filemetadata(device, filedata->item_id);
+ if (newfilemeta != NULL) {
+ filedata->parent_id = newfilemeta->parent_id;
+ filedata->storage_id = newfilemeta->storage_id;
+ LIBMTP_destroy_file_t(newfilemeta);
+ } else {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL,
+ "LIBMTP_Send_File_From_File_Descriptor(): "
+ "Could not retrieve updated metadata.");
+ return -1;
+ }
return 0;
}
/**
- * This function updates the MTP object metadata on a single file
- * identified by an object ID.
+ * This function updates the MTP track object metadata on a
+ * single file identified by an object ID.
* @param device a pointer to the device to update the track
* metadata on.
* @param metadata a track metadata set to be written to the file.
@@ -4239,7 +4400,7 @@
return -1;
}
if (ptp_operation_issupported(params, PTP_OC_MTP_SetObjPropList) &&
- !(ptp_usb->device_flags & DEVICE_FLAG_BROKEN_SET_OBJECT_PROPLIST)) {
+ !FLAG_BROKEN_SET_OBJECT_PROPLIST(ptp_usb)) {
MTPProperties *props = NULL;
MTPProperties *prop = NULL;
int nrofprops = 0;
@@ -4280,6 +4441,15 @@
prop->datatype = PTP_DTC_STR;
prop->propval.str = strdup(metadata->artist);
break;
+ case PTP_OPC_Composer:
+ if (metadata->composer == NULL)
+ break;
+ prop = ptp_get_new_object_prop_entry(&props, &nrofprops);
+ prop->ObjectHandle = metadata->item_id;
+ prop->property = PTP_OPC_Composer;
+ prop->datatype = PTP_DTC_STR;
+ prop->propval.str = strdup(metadata->composer);
+ break;
case PTP_OPC_Genre:
if (metadata->genre == NULL)
break;
@@ -4428,6 +4598,14 @@
"could not set track artist name.");
}
break;
+ case PTP_OPC_Composer:
+ // Update composer
+ ret = set_object_string(device, metadata->item_id, PTP_OPC_Composer, metadata->composer);
+ if (ret != 0) {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): "
+ "could not set track composer name.");
+ }
+ break;
case PTP_OPC_Genre:
// Update genre
ret = set_object_string(device, metadata->item_id, PTP_OPC_Genre, metadata->genre);
@@ -4571,11 +4749,18 @@
}
/**
- * This function deletes a single file, track, playlist or
- * any other object off the MTP device,
- * identified by an object ID.
- * @param device a pointer to the device to delete the file or track from.
- * @param item_id the item to delete.
+ * This function deletes a single file, track, playlist, folder or
+ * any other object off the MTP device, identified by the object ID.
+ *
+ * If you delete a folder, there is no guarantee that the device will
+ * really delete all the files that were in that folder, rather it is
+ * expected that they will not be deleted, and will turn up in object
+ * listings with parent set to a non-existant object ID. The safe way
+ * to do this is to recursively delete all files (and folders) contained
+ * in the folder, then the folder itself.
+ *
+ * @param device a pointer to the device to delete the object from.
+ * @param object_id the object to delete.
* @return 0 on success, any other value means failure.
*/
int LIBMTP_Delete_Object(LIBMTP_mtpdevice_t *device,
@@ -4594,6 +4779,107 @@
}
/**
+ * This function renames a single file, track, playlist, folder or
+ * any other object on the MTP device, identified by an object ID.
+ * This simply means that the PTP_OPC_ObjectFileName property
+ * is updated, if this is supported by the device.
+ *
+ * @param device a pointer to the device that contains the the file,
+ * track, foler, playlist or other object to set the filename for.
+ * @param object_id the ID of the object to rename.
+ * @param newname the new filename for this object. You MUST assume that
+ * this string can be modified by the call to this function, since
+ * some devices have restrictions as to which filenames may be
+ * used on them.
+ * @return 0 on success, any other value means failure.
+ */
+int LIBMTP_Set_Object_Filename(LIBMTP_mtpdevice_t *device,
+ uint32_t object_id, char *newname)
+{
+ PTPParams *params = (PTPParams *) device->params;
+ PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo;
+ LIBMTP_file_t *file;
+ uint16_t ptp_type;
+ PTPObjectPropDesc opd;
+ uint16_t ret;
+
+ // Get metadata for this object.
+ file = LIBMTP_Get_Filemetadata(device, object_id);
+ if (file == NULL) {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Set_Object_Filename(): "
+ "could not get file metadata for target object.");
+ return -1;
+ }
+ ptp_type = map_libmtp_type_to_ptp_type(file->filetype);
+ LIBMTP_destroy_file_t(file);
+
+ // See if we can modify the filename on this kind of files.
+ ret = ptp_mtp_getobjectpropdesc(params, PTP_OPC_ObjectFileName, ptp_type, &opd);
+ if (ret != PTP_RC_OK) {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Set_Object_Filename(): "
+ "could not get property description.");
+ return -1;
+ }
+
+ if (!opd.GetSet) {
+ ptp_free_objectpropdesc(&opd);
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Set_Object_Filename(): "
+ "property is not settable.");
+ // TODO: we COULD actually upload/download the object here, if we feel
+ // like wasting time for the user.
+ return -1;
+ }
+
+ if (FLAG_ONLY_7BIT_FILENAMES(ptp_usb)) {
+ strip_7bit_from_utf8(newname);
+ }
+
+ if (ptp_operation_issupported(params, PTP_OC_MTP_SetObjPropList) &&
+ !FLAG_BROKEN_SET_OBJECT_PROPLIST(ptp_usb)) {
+ MTPProperties *props = NULL;
+ MTPProperties *prop = NULL;
+ int nrofprops = 0;
+
+ prop = ptp_get_new_object_prop_entry(&props, &nrofprops);
+ prop->ObjectHandle = object_id;
+ prop->property = PTP_OPC_ObjectFileName;
+ prop->datatype = PTP_DTC_STR;
+ prop->propval.str = strdup(newname);
+
+ ret = ptp_mtp_setobjectproplist(params, props, nrofprops);
+
+ ptp_destroy_object_prop_list(props, nrofprops);
+
+ if (ret != PTP_RC_OK) {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Set_Oject_Filename(): "
+ "could not set object property list.");
+ ptp_free_objectpropdesc(&opd);
+ return -1;
+ }
+ } else if (ptp_operation_issupported(params, PTP_OC_MTP_SetObjectPropValue)) {
+ ret = set_object_string(device, object_id, PTP_OPC_ObjectFileName, newname);
+ if (ret != 0) {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Set_Oject_Filename(): "
+ "could not set object filename.");
+ ptp_free_objectpropdesc(&opd);
+ return -1;
+ }
+ } else {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Set_Oject_Filename(): "
+ "Your device doesn't seem to support any known way of setting metadata.");
+ ptp_free_objectpropdesc(&opd);
+ return -1;
+ }
+
+ ptp_free_objectpropdesc(&opd);
+
+ // update cached object properties if metadata cache exists
+ update_metadata_cache(device, object_id);
+
+ return 0;
+}
+
+/**
* Helper function. This indicates if a track exists on the device
* @param device a pointer to the device to get the track from.
* @param id the track ID of the track to retrieve.
@@ -4631,6 +4917,7 @@
}
new->folder_id = 0;
new->parent_id = 0;
+ new->storage_id = 0;
new->name = NULL;
new->sibling = NULL;
new->child = NULL;
@@ -4724,6 +5011,7 @@
}
folder->folder_id = params->handles.Handler[i];
folder->parent_id = oi->ParentObject;
+ folder->storage_id = oi->StorageID;
if (oi->Filename != NULL) {
folder->name = (char *)strdup(oi->Filename);
} else {
@@ -4785,28 +5073,40 @@
* @param name the name of the new folder.
* @param parent_id id of parent folder to add the new folder to,
* or 0 to put it in the root directory.
+ * @param storage_id id of the storage to add this new folder to.
+ * notice that you cannot mismatch storage id and parent id:
+ * they must both be on the same storage! Pass in 0 if you
+ * want to create this folder on the default storage.
* @return id to new folder or 0 if an error occured
*/
-uint32_t LIBMTP_Create_Folder(LIBMTP_mtpdevice_t *device, char *name, uint32_t parent_id)
+uint32_t LIBMTP_Create_Folder(LIBMTP_mtpdevice_t *device, char *name,
+ uint32_t parent_id, uint32_t storage_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);
+ uint32_t store;
PTPObjectInfo new_folder;
uint16_t ret;
uint32_t new_id = 0;
+ if (storage_id == 0) {
+ store = get_first_storageid(device);
+ } else {
+ store = storage_id;
+ }
+ parenthandle = parent_id;
+
memset(&new_folder, 0, sizeof(new_folder));
new_folder.Filename = name;
- if (ptp_usb->device_flags & DEVICE_FLAG_ONLY_7BIT_FILENAMES) {
+ if (FLAG_ONLY_7BIT_FILENAMES(ptp_usb)) {
strip_7bit_from_utf8(new_folder.Filename);
}
new_folder.ObjectCompressedSize = 1;
new_folder.ObjectFormat = PTP_OFC_Association;
new_folder.ParentObject = parent_id;
+ new_folder.StorageID = store;
- parenthandle = parent_id;
// Create the object
// FIXME: use send list here if available.
ret = ptp_sendobjectinfo(params, &store, &parenthandle, &new_id, &new_folder);
@@ -4849,6 +5149,8 @@
return NULL;
}
new->playlist_id = 0;
+ new->parent_id = 0;
+ new->storage_id = 0;
new->name = NULL;
new->tracks = NULL;
new->no_tracks = 0;
@@ -4917,9 +5219,9 @@
// Ignoring the oi->Filename field.
pl->name = get_string_from_object(device, params->handles.Handler[i], PTP_OPC_Name);
-
- // This is some sort of unique playlist ID so we can keep track of it
pl->playlist_id = params->handles.Handler[i];
+ pl->parent_id = oi->ParentObject;
+ pl->storage_id = oi->StorageID;
// Then get the track listing for this playlist
ret = ptp_mtp_getobjectreferences(params, pl->playlist_id, &pl->tracks, &pl->no_tracks);
@@ -4982,9 +5284,9 @@
// Ignoring the io.Filename field.
pl->name = get_string_from_object(device, params->handles.Handler[i], PTP_OPC_Name);
-
- // This is some sort of unique playlist ID so we can keep track of it
pl->playlist_id = params->handles.Handler[i];
+ pl->parent_id = oi->ParentObject;
+ pl->storage_id = oi->StorageID;
// Then get the track listing for this playlist
ret = ptp_mtp_getobjectreferences(params, pl->playlist_id, &pl->tracks, &pl->no_tracks);
@@ -4999,7 +5301,7 @@
return NULL;
}
-/*
+/**
* This function creates a new abstract list such as a playlist
* or an album.
*
@@ -5022,8 +5324,10 @@
static int create_new_abstract_list(LIBMTP_mtpdevice_t *device,
char const * const name,
char const * const artist,
+ char const * const composer,
char const * const genre,
uint32_t const parenthandle,
+ uint32_t const storageid,
uint16_t const objectformat,
char const * const suffix,
uint32_t * const newid,
@@ -5036,7 +5340,7 @@
uint16_t ret;
uint16_t *properties = NULL;
uint32_t propcnt = 0;
- uint32_t store = get_first_storageid(device);
+ uint32_t store;
uint32_t localph = parenthandle;
uint8_t nonconsumable = 0x00U; /* By default it is consumable */
PTPParams *params = (PTPParams *) device->params;
@@ -5044,6 +5348,12 @@
char fname[256];
uint8_t data[2];
+ if (storageid == 0) {
+ store = get_first_storageid(device);
+ } else {
+ store = storageid;
+ }
+
// Check if we can create an object of this type
for ( i=0; i < params->deviceinfo.ImageFormats_len; i++ ) {
if (params->deviceinfo.ImageFormats[i] == objectformat) {
@@ -5098,7 +5408,7 @@
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) {
+ if (FLAG_ONLY_7BIT_FILENAMES(ptp_usb)) {
strip_7bit_from_utf8(prop->propval.str);
}
break;
@@ -5125,6 +5435,15 @@
prop->propval.str = strdup(name);
}
break;
+ case PTP_OPC_AlbumArtist:
+ if (artist != NULL) {
+ prop = ptp_get_new_object_prop_entry(&props,&nrofprops);
+ prop->ObjectHandle = *newid;
+ prop->property = PTP_OPC_AlbumArtist;
+ prop->datatype = PTP_DTC_STR;
+ prop->propval.str = strdup(artist);
+ }
+ break;
case PTP_OPC_Artist:
if (artist != NULL) {
prop = ptp_get_new_object_prop_entry(&props,&nrofprops);
@@ -5134,6 +5453,15 @@
prop->propval.str = strdup(artist);
}
break;
+ case PTP_OPC_Composer:
+ if (composer != NULL) {
+ prop = ptp_get_new_object_prop_entry(&props,&nrofprops);
+ prop->ObjectHandle = *newid;
+ prop->property = PTP_OPC_Composer;
+ prop->datatype = PTP_DTC_STR;
+ prop->propval.str = strdup(composer);
+ }
+ break;
case PTP_OPC_Genre:
if (genre != NULL) {
prop = ptp_get_new_object_prop_entry(&props,&nrofprops);
@@ -5182,7 +5510,7 @@
PTPObjectInfo new_object;
new_object.Filename = fname;
- if (ptp_usb->device_flags & DEVICE_FLAG_ONLY_7BIT_FILENAMES) {
+ if (FLAG_ONLY_7BIT_FILENAMES(ptp_usb)) {
strip_7bit_from_utf8(new_object.Filename);
}
new_object.ObjectCompressedSize = 1;
@@ -5225,6 +5553,15 @@
// Update artist
// FIXME: check if supported
if (artist != NULL) {
+ ret = set_object_string(device, *newid, PTP_OPC_AlbumArtist, artist);
+ if (ret != 0) {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "create_new_abstract_list(): could not set entity album artist.");
+ return -1;
+ }
+ }
+ // Update artist
+ // FIXME: check if supported
+ if (artist != NULL) {
ret = set_object_string(device, *newid, PTP_OPC_Artist, artist);
if (ret != 0) {
add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "create_new_abstract_list(): could not set entity artist.");
@@ -5232,6 +5569,16 @@
}
}
+ // Update composer
+ // FIXME: check if supported
+ if (composer != NULL) {
+ ret = set_object_string(device, *newid, PTP_OPC_Composer, composer);
+ if (ret != 0) {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "create_new_abstract_list(): could not set entity composer.");
+ return -1;
+ }
+ }
+
// Update genre
// FIXME: check if supported
if (genre != NULL) {
@@ -5277,6 +5624,7 @@
static int update_abstract_list(LIBMTP_mtpdevice_t *device,
char const * const name,
char const * const artist,
+ char const * const composer,
char const * const genre,
uint32_t const objecthandle,
uint16_t const objectformat,
@@ -5300,7 +5648,7 @@
return -1;
}
if (ptp_operation_issupported(params,PTP_OC_MTP_SetObjPropList) &&
- !(ptp_usb->device_flags & DEVICE_FLAG_BROKEN_SET_OBJECT_PROPLIST)) {
+ !FLAG_BROKEN_SET_OBJECT_PROPLIST(ptp_usb)) {
MTPProperties *props = NULL;
MTPProperties *prop = NULL;
int nrofprops = 0;
@@ -5322,15 +5670,33 @@
if (name != NULL)
prop->propval.str = strdup(name);
break;
+ case PTP_OPC_AlbumArtist:
+ if (artist != NULL) {
+ prop = ptp_get_new_object_prop_entry(&props, &nrofprops);
+ prop->ObjectHandle = objecthandle;
+ prop->property = PTP_OPC_AlbumArtist;
+ prop->datatype = PTP_DTC_STR;
+ prop->propval.str = strdup(artist);
+ }
+ break;
case PTP_OPC_Artist:
if (artist != NULL) {
prop = ptp_get_new_object_prop_entry(&props, &nrofprops);
- prop->ObjectHandle = objecthandle;
+ prop->ObjectHandle = objecthandle;
prop->property = PTP_OPC_Artist;
prop->datatype = PTP_DTC_STR;
prop->propval.str = strdup(artist);
}
break;
+ case PTP_OPC_Composer:
+ if (composer != NULL) {
+ prop = ptp_get_new_object_prop_entry(&props, &nrofprops);
+ prop->ObjectHandle = objecthandle;
+ prop->property = PTP_OPC_Composer;
+ prop->datatype = PTP_DTC_STR;
+ prop->propval.str = strdup(composer);
+ }
+ break;
case PTP_OPC_Genre:
if (genre != NULL) {
prop = ptp_get_new_object_prop_entry(&props, &nrofprops);
@@ -5381,6 +5747,14 @@
"could not set title.");
}
break;
+ case PTP_OPC_AlbumArtist:
+ // Update album artist
+ ret = set_object_string(device, objecthandle, PTP_OPC_AlbumArtist, artist);
+ if (ret != 0) {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "update_abstract_list(): "
+ "could not set album artist name.");
+ }
+ break;
case PTP_OPC_Artist:
// Update artist
ret = set_object_string(device, objecthandle, PTP_OPC_Artist, artist);
@@ -5388,6 +5762,13 @@
add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "update_abstract_list(): "
"could not set artist name.");
}
+ case PTP_OPC_Composer:
+ // Update composer
+ ret = set_object_string(device, objecthandle, PTP_OPC_Composer, composer);
+ if (ret != 0) {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "update_abstract_list(): "
+ "could not set composer name.");
+ }
break;
case PTP_OPC_Genre:
// Update genre
@@ -5447,6 +5828,7 @@
* @param metadata the metadata for the new playlist. If the function
* exits with success, the <code>playlist_id</code> field of this
* struct will contain the new playlist ID of the playlist.
+ * <code>parent_id</code> will also be valid.
* @param parenthandle the parent (e.g. folder) to store this playlist
* in. Pass in 0 to put the playlist in the root directory.
* @return 0 on success, any other value means failure.
@@ -5454,24 +5836,27 @@
* @see LIBMTP_Delete_Object()
*/
int LIBMTP_Create_New_Playlist(LIBMTP_mtpdevice_t *device,
- LIBMTP_playlist_t * const metadata,
- uint32_t const parenthandle)
+ LIBMTP_playlist_t * const metadata)
{
- uint32_t localph = parenthandle;
+ PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo;
+ uint32_t localph = metadata->parent_id;
// Use a default folder if none given
if (localph == 0) {
localph = device->default_playlist_folder;
}
+ metadata->parent_id = localph;
// Just create a new abstract audio/video playlist...
return create_new_abstract_list(device,
metadata->name,
NULL,
NULL,
+ NULL,
localph,
+ metadata->storage_id,
PTP_OFC_MTP_AbstractAudioVideoPlaylist,
- ".zpl",
+ get_playlist_extension(ptp_usb),
&metadata->playlist_id,
metadata->tracks,
metadata->no_tracks);
@@ -5498,6 +5883,7 @@
metadata->name,
NULL,
NULL,
+ NULL,
metadata->playlist_id,
PTP_OFC_MTP_AbstractAudioVideoPlaylist,
metadata->tracks,
@@ -5521,8 +5907,11 @@
return NULL;
}
new->album_id = 0;
+ new->parent_id = 0;
+ new->storage_id = 0;
new->name = NULL;
new->artist = NULL;
+ new->composer = NULL;
new->genre = NULL;
new->tracks = NULL;
new->no_tracks = 0;
@@ -5545,6 +5934,8 @@
free(album->name);
if (album->artist != NULL)
free(album->artist);
+ if (album->composer != NULL)
+ free(album->composer);
if (album->genre != NULL)
free(album->genre);
if (album->tracks != NULL)
@@ -5588,11 +5979,18 @@
// Allocate a new album type
alb = LIBMTP_new_album_t();
+ alb->album_id = params->handles.Handler[i];
+ alb->parent_id = oi->ParentObject;
+ alb->storage_id = oi->StorageID;
+
// Get metadata for it.
alb->name = get_string_from_object(device, params->handles.Handler[i], PTP_OPC_Name);
- alb->artist = get_string_from_object(device, params->handles.Handler[i], PTP_OPC_Artist);
+ alb->artist = get_string_from_object(device, params->handles.Handler[i], PTP_OPC_AlbumArtist);
+ if (alb->artist == NULL) {
+ alb->artist = get_string_from_object(device, params->handles.Handler[i], PTP_OPC_Artist);
+ }
+ alb->composer = get_string_from_object(device, params->handles.Handler[i], PTP_OPC_Composer);
alb->genre = get_string_from_object(device, params->handles.Handler[i], PTP_OPC_Genre);
- alb->album_id = params->handles.Handler[i];
// Then get the track listing for this album
ret = ptp_mtp_getobjectreferences(params, alb->album_id, &alb->tracks, &alb->no_tracks);
@@ -5651,8 +6049,16 @@
// Allocate a new album type
alb = LIBMTP_new_album_t();
alb->album_id = params->handles.Handler[i];
+ alb->parent_id = oi->ParentObject;
+ alb->storage_id = oi->StorageID;
+
+ // Get metadata for it.
alb->name = get_string_from_object(device, params->handles.Handler[i], PTP_OPC_Name);
- alb->artist = get_string_from_object(device, params->handles.Handler[i], PTP_OPC_Artist);
+ alb->artist = get_string_from_object(device, params->handles.Handler[i], PTP_OPC_AlbumArtist);
+ if (alb->artist == NULL) {
+ alb->artist = get_string_from_object(device, params->handles.Handler[i], PTP_OPC_Artist);
+ }
+ alb->composer = get_string_from_object(device, params->handles.Handler[i], PTP_OPC_Composer);
alb->genre = get_string_from_object(device, params->handles.Handler[i], PTP_OPC_Genre);
ret = ptp_mtp_getobjectreferences(params, alb->album_id, &alb->tracks, &alb->no_tracks);
if (ret != PTP_RC_OK) {
@@ -5675,6 +6081,7 @@
* @param metadata the metadata for the new album. If the function
* exits with success, the <code>album_id</code> field of this
* struct will contain the new ID of the album.
+ * <code>parent_id</code> will also be valid.
* @param parenthandle the parent (e.g. folder) to store this album
* in. Pass in 0 to put the album in the default music directory.
* @return 0 on success, any other value means failure.
@@ -5682,22 +6089,24 @@
* @see LIBMTP_Delete_Object()
*/
int LIBMTP_Create_New_Album(LIBMTP_mtpdevice_t *device,
- LIBMTP_album_t * const metadata,
- uint32_t const parenthandle)
+ LIBMTP_album_t * const metadata)
{
- uint32_t localph = parenthandle;
+ uint32_t localph = metadata->parent_id;
// Use a default folder if none given
if (localph == 0) {
localph = device->default_album_folder;
}
+ metadata->parent_id = localph;
// Just create a new abstract album...
return create_new_abstract_list(device,
metadata->name,
metadata->artist,
+ metadata->composer,
metadata->genre,
localph,
+ metadata->storage_id,
PTP_OFC_MTP_AbstractAudioAlbum,
".alb",
&metadata->album_id,
@@ -5751,7 +6160,7 @@
* playlists, but in theory any filetype could support representative
* samples.
* @param device a pointer to the device which is to be examined.
- * @param the filetype to examine, and return the representative sample
+ * @param filetype the fileype to examine, and return the representative sample
* properties for.
* @param sample this will contain a new sample type with the fields
* filled in with suitable default values. For example, the
@@ -5873,10 +6282,9 @@
* TODO: there must be a way to find the max size for an ObjectPropertyValue.
* @param device a pointer to the device which the object is on.
* @param id unique id of the object to set artwork for.
- * @param data pointer to an array of uint8_t containing the representative
- * sample data.
- * @param size number of bytes in the sample.
+ * @param pointer to LIBMTP_filesampledata_t struct containing data
* @return 0 on success, any other value means failure.
+ * @see LIBMTP_Get_Representative_Sample()
* @see LIBMTP_Get_Representative_Sample_Format()
* @see LIBMTP_Create_New_Album()
*/
@@ -5886,6 +6294,7 @@
{
uint16_t ret;
PTPParams *params = (PTPParams *) device->params;
+ PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo;
PTPPropertyValue propval;
PTPObjectInfo *oi;
uint32_t i;
@@ -5942,12 +6351,6 @@
return -1;
}
free(propval.a.v);
-
- /*
- * TODO: Send Representative Sample Height, Width and Size here if it is an
- * image (typically JPEG) thumbnail, send Duration and Size if it is an audio
- * sample (MP3, WAV etc).
- */
/* Set the height and width if the sample is an image, otherwise just
* set the duration and size */
@@ -5959,9 +6362,11 @@
case LIBMTP_FILETYPE_GIF:
case LIBMTP_FILETYPE_PICT:
case LIBMTP_FILETYPE_PNG:
- // For images, set the height and width
- set_object_u32(device, id, PTP_OPC_RepresentativeSampleHeight, sampledata->height);
- set_object_u32(device, id, PTP_OPC_RepresentativeSampleWidth, sampledata->width);
+ if (!FLAG_BROKEN_SET_SAMPLE_DIMENSIONS(ptp_usb)) {
+ // For images, set the height and width
+ set_object_u32(device, id, PTP_OPC_RepresentativeSampleHeight, sampledata->height);
+ set_object_u32(device, id, PTP_OPC_RepresentativeSampleWidth, sampledata->width);
+ }
break;
default:
// For anything not an image, set the duration and size
@@ -5974,6 +6379,91 @@
}
/**
+ * This routine gets representative sample data for an object.
+ * This uses the RepresentativeSampleData property of the album,
+ * if the device supports it.
+ * @param device a pointer to the device which the object is on.
+ * @param id unique id of the object to get data for.
+ * @param pointer to LIBMTP_filesampledata_t struct to receive data
+ * @return 0 on success, any other value means failure.
+ * @see LIBMTP_Send_Representative_Sample()
+ * @see LIBMTP_Get_Representative_Sample_Format()
+ * @see LIBMTP_Create_New_Album()
+ */
+int LIBMTP_Get_Representative_Sample(LIBMTP_mtpdevice_t *device,
+ uint32_t const id,
+ LIBMTP_filesampledata_t *sampledata)
+{
+ uint16_t ret;
+ PTPParams *params = (PTPParams *) device->params;
+ PTPPropertyValue propval;
+ PTPObjectInfo *oi;
+ uint32_t i;
+ uint16_t *props = NULL;
+ uint32_t propcnt = 0;
+ int supported = 0;
+
+ // get the file format for the object we're going to send representative data for
+ oi = NULL;
+ for (i = 0; i < params->handles.n; i++) {
+ if (params->handles.Handler[i] == id) {
+ oi = ¶ms->objectinfo[i];
+ break;
+ }
+ }
+
+ if (oi == NULL) {
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Get_Representative_Sample(): could not get object info.");
+ return -1;
+ }
+
+ // check that we can store representative sample data for this object format
+ ret = ptp_mtp_getobjectpropssupported(params, oi->ObjectFormat, &propcnt, &props);
+ if (ret != PTP_RC_OK) {
+ add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Representative_Sample(): could not get object properties.");
+ return -1;
+ }
+
+ for (i = 0; i < propcnt; i++) {
+ if (props[i] == PTP_OPC_RepresentativeSampleData) {
+ supported = 1;
+ break;
+ }
+ }
+ if (!supported) {
+ free(props);
+ add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Get_Representative_Sample(): object type doesn't support RepresentativeSampleData.");
+ return -1;
+ }
+ free(props);
+
+ // Get the data
+ ret = ptp_mtp_getobjectpropvalue(params,id,PTP_OPC_RepresentativeSampleData,
+ &propval,PTP_DTC_AUINT8);
+ if (ret != PTP_RC_OK) {
+ add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Representative_Sample(): could not get sample data.");
+ return -1;
+ }
+
+ // Store it
+ sampledata->size = propval.a.count;
+ sampledata->data = malloc(sizeof(PTPPropertyValue) * propval.a.count);
+ for (i = 0; i < propval.a.count; i++) {
+ sampledata->data[i] = propval.a.v[i].u8;
+ }
+ free(propval.a.v);
+
+ // Get the other properties
+ sampledata->width = get_u32_from_object(device, id, PTP_OPC_RepresentativeSampleWidth, 0);
+ sampledata->height = get_u32_from_object(device, id, PTP_OPC_RepresentativeSampleHeight, 0);
+ sampledata->duration = get_u32_from_object(device, id, PTP_OPC_RepresentativeSampleDuration, 0);
+ sampledata->filetype = map_ptp_type_to_libmtp_type(
+ get_u16_from_object(device, id, PTP_OPC_RepresentativeSampleFormat, LIBMTP_FILETYPE_UNKNOWN));
+
+ return 0;
+}
+
+/**
* This routine updates an album based on the metadata
* supplied. If the <code>tracks</code> field of the metadata
* contains a track listing, these tracks will be added to the
@@ -5993,6 +6483,7 @@
return update_abstract_list(device,
metadata->name,
metadata->artist,
+ metadata->composer,
metadata->genre,
metadata->album_id,
PTP_OFC_MTP_AbstractAudioAlbum,
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/src/libmtp.h
^
|
@@ -2,9 +2,10 @@
* \file libmtp.h
* Interface to the Media Transfer Protocol library.
*
- * Copyright (C) 2005-2007 Linus Walleij <triad@df.lth.se>
- * Copyright (C) 2005-2007 Richard A. Low <richard@wentnet.com>
- * Copyright (C) 2007 Ted Bullock
+ * Copyright (C) 2005-2008 Linus Walleij <triad@df.lth.se>
+ * Copyright (C) 2005-2008 Richard A. Low <richard@wentnet.com>
+ * Copyright (C) 2007 Ted Bullock <tbullock@canada.com>
+ * Copyright (C) 2008 Florent Mertens <flomertens@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -28,8 +29,8 @@
#ifndef LIBMTP_H_INCLUSION_GUARD
#define LIBMTP_H_INCLUSION_GUARD
-#define LIBMTP_VERSION 0.2.4
-#define LIBMTP_VERSION_STRING "0.2.4"
+#define LIBMTP_VERSION 0.3.0
+#define LIBMTP_VERSION_STRING "0.3.0"
/* This handles MSVC pecularities */
#ifdef _MSC_VER
@@ -108,6 +109,34 @@
LIBMTP_FILETYPE_JPX,
LIBMTP_FILETYPE_UNKNOWN
} LIBMTP_filetype_t;
+
+/**
+ * Helpful macros to determine filetype properties
+ */
+#define LIBMTP_FILETYPE_IS_AUDIO(a)\
+(a == LIBMTP_FILETYPE_WAV ||\
+ a == LIBMTP_FILETYPE_MP3 ||\
+ a == LIBMTP_FILETYPE_MP2 ||\
+ a == LIBMTP_FILETYPE_WMA ||\
+ a == LIBMTP_FILETYPE_OGG ||\
+ a == LIBMTP_FILETYPE_FLAC ||\
+ a == LIBMTP_FILETYPE_AAC ||\
+ a == LIBMTP_FILETYPE_M4A ||\
+ a == LIBMTP_FILETYPE_UNDEF_AUDIO)
+#define LIBMTP_FILETYPE_IS_VIDEO(a)\
+(a == LIBMTP_FILETYPE_WMV ||\
+ a == LIBMTP_FILETYPE_AVI ||\
+ a == LIBMTP_FILETYPE_MPEG ||\
+ a == LIBMTP_FILETYPE_UNDEF_VIDEO)
+#define LIBMTP_FILETYPE_IS_AUDIOVIDEO(a)\
+(a == LIBMTP_FILETYPE_MP4 ||\
+ a == LIBMTP_FILETYPE_ASF ||\
+ a == LIBMTP_FILETYPE_QT)
+#define LIBMTP_FILETYPE_IS_TRACK(a)\
+(LIBMTP_FILETYPE_IS_AUDIO(a) ||\
+ LIBMTP_FILETYPE_IS_VIDEO(a) ||\
+ LIBMTP_FILETYPE_IS_AUDIOVIDEO(a))
+
/**
* These are the numbered error codes. You can also
* get string representations for errors.
@@ -124,6 +153,7 @@
LIBMTP_ERROR_CANCELLED
} LIBMTP_error_number_t;
typedef struct LIBMTP_device_entry_struct LIBMTP_device_entry_t; /**< @see LIBMTP_device_entry_struct */
+typedef struct LIBMTP_raw_device_struct LIBMTP_raw_device_t; /**< @see LIBMTP_raw_device_struct */
typedef struct LIBMTP_error_struct LIBMTP_error_t; /**< @see LIBMTP_error_struct */
typedef struct LIBMTP_mtpdevice_struct LIBMTP_mtpdevice_t; /**< @see LIBMTP_mtpdevice_struct */
typedef struct LIBMTP_file_struct LIBMTP_file_t; /**< @see LIBMTP_file_struct */
@@ -166,6 +196,16 @@
};
/**
+ * A data structure to hold a raw MTP device connected
+ * to the bus.
+ */
+struct LIBMTP_raw_device_struct {
+ LIBMTP_device_entry_t device_entry; /**< The device entry for this raw device */
+ uint32_t bus_location; /**< Location of the bus, if device available */
+ uint8_t devnum; /**< Device number on the bus, if device available */
+};
+
+/**
* A data structure to hold errors from the library.
*/
struct LIBMTP_error_struct {
@@ -196,6 +236,7 @@
* The storage for this device, do not use strings in here without
* copying them first, and beware that this list may be rebuilt at
* any time.
+ * @see LIBMTP_Get_Storage()
*/
LIBMTP_devicestorage_t *storage;
/**
@@ -234,6 +275,7 @@
struct LIBMTP_file_struct {
uint32_t item_id; /**< Unique item ID */
uint32_t parent_id; /**< ID of parent folder */
+ uint32_t storage_id; /**< ID of storage holding this file */
char *filename; /**< Filename of this file */
uint64_t filesize; /**< Size of file in bytes */
LIBMTP_filetype_t filetype; /**< Filetype used for the current file */
@@ -246,8 +288,10 @@
struct LIBMTP_track_struct {
uint32_t item_id; /**< Unique item ID */
uint32_t parent_id; /**< ID of parent folder */
+ uint32_t storage_id; /**< ID of storage holding this track */
char *title; /**< Track title */
char *artist; /**< Name of recording artist */
+ char *composer; /**< Name of recording composer */
char *genre; /**< Genre name for track */
char *album; /**< Album name for track */
char *date; /**< Date of original recording as a string */
@@ -271,6 +315,8 @@
*/
struct LIBMTP_playlist_struct {
uint32_t playlist_id; /**< Unique playlist ID */
+ uint32_t parent_id; /**< ID of parent folder */
+ uint32_t storage_id; /**< ID of storage holding this playlist */
char *name; /**< Name of playlist */
uint32_t *tracks; /**< The tracks in this playlist */
uint32_t no_tracks; /**< The number of tracks in this playlist */
@@ -282,8 +328,11 @@
*/
struct LIBMTP_album_struct {
uint32_t album_id; /**< Unique playlist ID */
+ uint32_t parent_id; /**< ID of parent folder */
+ uint32_t storage_id; /**< ID of storage holding this album */
char *name; /**< Name of album */
char *artist; /**< Name of album artist */
+ char *composer; /**< Name of recording composer */
char *genre; /**< Genre of album */
uint32_t *tracks; /**< The tracks in this album */
uint32_t no_tracks; /**< The number of tracks in this album */
@@ -296,6 +345,7 @@
struct LIBMTP_folder_struct {
uint32_t folder_id; /**< Unique folder ID */
uint32_t parent_id; /**< ID of parent folder */
+ uint32_t storage_id; /**< ID of storage holding this folder */
char *name; /**< Name of folder */
LIBMTP_folder_t *sibling; /**< Next folder at same level or NULL if no more */
LIBMTP_folder_t *child; /**< Child folder or NULL if no children */
@@ -349,14 +399,18 @@
* @defgroup basic The basic device management API.
* @{
*/
-int LIBMTP_Detect_Descriptor(uint16_t*,uint16_t*);
+LIBMTP_error_number_t LIBMTP_Detect_Raw_Devices(LIBMTP_raw_device_t **, int *);
+LIBMTP_mtpdevice_t *LIBMTP_Open_Raw_Device(LIBMTP_raw_device_t *);
+/* Begin old, legacy interface */
LIBMTP_mtpdevice_t *LIBMTP_Get_First_Device(void);
LIBMTP_error_number_t LIBMTP_Get_Connected_Devices(LIBMTP_mtpdevice_t **);
uint32_t LIBMTP_Number_Devices_In_List(LIBMTP_mtpdevice_t *);
void LIBMTP_Release_Device_List(LIBMTP_mtpdevice_t*);
+/* End old, legacy interface */
void LIBMTP_Release_Device(LIBMTP_mtpdevice_t*);
void LIBMTP_Dump_Device_Info(LIBMTP_mtpdevice_t*);
int LIBMTP_Reset_Device(LIBMTP_mtpdevice_t*);
+char *LIBMTP_Get_Manufacturername(LIBMTP_mtpdevice_t*);
char *LIBMTP_Get_Modelname(LIBMTP_mtpdevice_t*);
char *LIBMTP_Get_Serialnumber(LIBMTP_mtpdevice_t*);
char *LIBMTP_Get_Deviceversion(LIBMTP_mtpdevice_t*);
@@ -400,10 +454,10 @@
LIBMTP_progressfunc_t const, void const * const);
int LIBMTP_Send_File_From_File(LIBMTP_mtpdevice_t *, char const * const,
LIBMTP_file_t * const, LIBMTP_progressfunc_t const,
- void const * const, uint32_t const);
+ void const * const);
int LIBMTP_Send_File_From_File_Descriptor(LIBMTP_mtpdevice_t *, int const,
LIBMTP_file_t * const, LIBMTP_progressfunc_t const,
- void const * const, uint32_t const);
+ void const * const);
LIBMTP_filesampledata_t *LIBMTP_new_filesampledata_t(void);
void LIBMTP_destroy_filesampledata_t(LIBMTP_filesampledata_t *);
int LIBMTP_Get_Representative_Sample_Format(LIBMTP_mtpdevice_t *,
@@ -411,6 +465,8 @@
LIBMTP_filesampledata_t **);
int LIBMTP_Send_Representative_Sample(LIBMTP_mtpdevice_t *, uint32_t const,
LIBMTP_filesampledata_t *);
+int LIBMTP_Get_Representative_Sample(LIBMTP_mtpdevice_t *, uint32_t const,
+ LIBMTP_filesampledata_t *);
/**
* @}
@@ -430,11 +486,11 @@
int LIBMTP_Send_Track_From_File(LIBMTP_mtpdevice_t *,
char const * const, LIBMTP_track_t * const,
LIBMTP_progressfunc_t const,
- void const * const, uint32_t const);
+ void const * const);
int LIBMTP_Send_Track_From_File_Descriptor(LIBMTP_mtpdevice_t *,
int const, LIBMTP_track_t * const,
LIBMTP_progressfunc_t const,
- void const * const, uint32_t const);
+ void const * const);
int LIBMTP_Update_Track_Metadata(LIBMTP_mtpdevice_t *,
LIBMTP_track_t const * const);
int LIBMTP_Track_Exists(LIBMTP_mtpdevice_t *, uint32_t);
@@ -449,7 +505,7 @@
void LIBMTP_destroy_folder_t(LIBMTP_folder_t*);
LIBMTP_folder_t *LIBMTP_Get_Folder_List(LIBMTP_mtpdevice_t*);
LIBMTP_folder_t *LIBMTP_Find_Folder(LIBMTP_folder_t*, uint32_t const);
-uint32_t LIBMTP_Create_Folder(LIBMTP_mtpdevice_t*, char *, uint32_t);
+uint32_t LIBMTP_Create_Folder(LIBMTP_mtpdevice_t*, char *, uint32_t, uint32_t);
/** @} */
@@ -462,7 +518,7 @@
void LIBMTP_destroy_playlist_t(LIBMTP_playlist_t *);
LIBMTP_playlist_t *LIBMTP_Get_Playlist_List(LIBMTP_mtpdevice_t *);
LIBMTP_playlist_t *LIBMTP_Get_Playlist(LIBMTP_mtpdevice_t *, uint32_t const);
-int LIBMTP_Create_New_Playlist(LIBMTP_mtpdevice_t *, LIBMTP_playlist_t * const, uint32_t const);
+int LIBMTP_Create_New_Playlist(LIBMTP_mtpdevice_t *, LIBMTP_playlist_t * const);
int LIBMTP_Update_Playlist(LIBMTP_mtpdevice_t *, LIBMTP_playlist_t const * const);
/**
@@ -474,7 +530,7 @@
void LIBMTP_destroy_album_t(LIBMTP_album_t *);
LIBMTP_album_t *LIBMTP_Get_Album_List(LIBMTP_mtpdevice_t *);
LIBMTP_album_t *LIBMTP_Get_Album(LIBMTP_mtpdevice_t *, uint32_t const);
-int LIBMTP_Create_New_Album(LIBMTP_mtpdevice_t *, LIBMTP_album_t * const, uint32_t const);
+int LIBMTP_Create_New_Album(LIBMTP_mtpdevice_t *, LIBMTP_album_t * const);
int LIBMTP_Update_Album(LIBMTP_mtpdevice_t *, LIBMTP_album_t const * const);
/**
@@ -483,6 +539,7 @@
* @{
*/
int LIBMTP_Delete_Object(LIBMTP_mtpdevice_t *, uint32_t);
+int LIBMTP_Set_Object_Filename(LIBMTP_mtpdevice_t *, uint32_t , char *);
/** @} */
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/src/libmtp.h.in
^
|
@@ -2,9 +2,10 @@
* \file libmtp.h
* Interface to the Media Transfer Protocol library.
*
- * Copyright (C) 2005-2007 Linus Walleij <triad@df.lth.se>
- * Copyright (C) 2005-2007 Richard A. Low <richard@wentnet.com>
- * Copyright (C) 2007 Ted Bullock
+ * Copyright (C) 2005-2008 Linus Walleij <triad@df.lth.se>
+ * Copyright (C) 2005-2008 Richard A. Low <richard@wentnet.com>
+ * Copyright (C) 2007 Ted Bullock <tbullock@canada.com>
+ * Copyright (C) 2008 Florent Mertens <flomertens@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -108,6 +109,34 @@
LIBMTP_FILETYPE_JPX,
LIBMTP_FILETYPE_UNKNOWN
} LIBMTP_filetype_t;
+
+/**
+ * Helpful macros to determine filetype properties
+ */
+#define LIBMTP_FILETYPE_IS_AUDIO(a)\
+(a == LIBMTP_FILETYPE_WAV ||\
+ a == LIBMTP_FILETYPE_MP3 ||\
+ a == LIBMTP_FILETYPE_MP2 ||\
+ a == LIBMTP_FILETYPE_WMA ||\
+ a == LIBMTP_FILETYPE_OGG ||\
+ a == LIBMTP_FILETYPE_FLAC ||\
+ a == LIBMTP_FILETYPE_AAC ||\
+ a == LIBMTP_FILETYPE_M4A ||\
+ a == LIBMTP_FILETYPE_UNDEF_AUDIO)
+#define LIBMTP_FILETYPE_IS_VIDEO(a)\
+(a == LIBMTP_FILETYPE_WMV ||\
+ a == LIBMTP_FILETYPE_AVI ||\
+ a == LIBMTP_FILETYPE_MPEG ||\
+ a == LIBMTP_FILETYPE_UNDEF_VIDEO)
+#define LIBMTP_FILETYPE_IS_AUDIOVIDEO(a)\
+(a == LIBMTP_FILETYPE_MP4 ||\
+ a == LIBMTP_FILETYPE_ASF ||\
+ a == LIBMTP_FILETYPE_QT)
+#define LIBMTP_FILETYPE_IS_TRACK(a)\
+(LIBMTP_FILETYPE_IS_AUDIO(a) ||\
+ LIBMTP_FILETYPE_IS_VIDEO(a) ||\
+ LIBMTP_FILETYPE_IS_AUDIOVIDEO(a))
+
/**
* These are the numbered error codes. You can also
* get string representations for errors.
@@ -124,6 +153,7 @@
LIBMTP_ERROR_CANCELLED
} LIBMTP_error_number_t;
typedef struct LIBMTP_device_entry_struct LIBMTP_device_entry_t; /**< @see LIBMTP_device_entry_struct */
+typedef struct LIBMTP_raw_device_struct LIBMTP_raw_device_t; /**< @see LIBMTP_raw_device_struct */
typedef struct LIBMTP_error_struct LIBMTP_error_t; /**< @see LIBMTP_error_struct */
typedef struct LIBMTP_mtpdevice_struct LIBMTP_mtpdevice_t; /**< @see LIBMTP_mtpdevice_struct */
typedef struct LIBMTP_file_struct LIBMTP_file_t; /**< @see LIBMTP_file_struct */
@@ -166,6 +196,16 @@
};
/**
+ * A data structure to hold a raw MTP device connected
+ * to the bus.
+ */
+struct LIBMTP_raw_device_struct {
+ LIBMTP_device_entry_t device_entry; /**< The device entry for this raw device */
+ uint32_t bus_location; /**< Location of the bus, if device available */
+ uint8_t devnum; /**< Device number on the bus, if device available */
+};
+
+/**
* A data structure to hold errors from the library.
*/
struct LIBMTP_error_struct {
@@ -196,6 +236,7 @@
* The storage for this device, do not use strings in here without
* copying them first, and beware that this list may be rebuilt at
* any time.
+ * @see LIBMTP_Get_Storage()
*/
LIBMTP_devicestorage_t *storage;
/**
@@ -234,6 +275,7 @@
struct LIBMTP_file_struct {
uint32_t item_id; /**< Unique item ID */
uint32_t parent_id; /**< ID of parent folder */
+ uint32_t storage_id; /**< ID of storage holding this file */
char *filename; /**< Filename of this file */
uint64_t filesize; /**< Size of file in bytes */
LIBMTP_filetype_t filetype; /**< Filetype used for the current file */
@@ -246,8 +288,10 @@
struct LIBMTP_track_struct {
uint32_t item_id; /**< Unique item ID */
uint32_t parent_id; /**< ID of parent folder */
+ uint32_t storage_id; /**< ID of storage holding this track */
char *title; /**< Track title */
char *artist; /**< Name of recording artist */
+ char *composer; /**< Name of recording composer */
char *genre; /**< Genre name for track */
char *album; /**< Album name for track */
char *date; /**< Date of original recording as a string */
@@ -271,6 +315,8 @@
*/
struct LIBMTP_playlist_struct {
uint32_t playlist_id; /**< Unique playlist ID */
+ uint32_t parent_id; /**< ID of parent folder */
+ uint32_t storage_id; /**< ID of storage holding this playlist */
char *name; /**< Name of playlist */
uint32_t *tracks; /**< The tracks in this playlist */
uint32_t no_tracks; /**< The number of tracks in this playlist */
@@ -282,8 +328,11 @@
*/
struct LIBMTP_album_struct {
uint32_t album_id; /**< Unique playlist ID */
+ uint32_t parent_id; /**< ID of parent folder */
+ uint32_t storage_id; /**< ID of storage holding this album */
char *name; /**< Name of album */
char *artist; /**< Name of album artist */
+ char *composer; /**< Name of recording composer */
char *genre; /**< Genre of album */
uint32_t *tracks; /**< The tracks in this album */
uint32_t no_tracks; /**< The number of tracks in this album */
@@ -296,6 +345,7 @@
struct LIBMTP_folder_struct {
uint32_t folder_id; /**< Unique folder ID */
uint32_t parent_id; /**< ID of parent folder */
+ uint32_t storage_id; /**< ID of storage holding this folder */
char *name; /**< Name of folder */
LIBMTP_folder_t *sibling; /**< Next folder at same level or NULL if no more */
LIBMTP_folder_t *child; /**< Child folder or NULL if no children */
@@ -349,14 +399,18 @@
* @defgroup basic The basic device management API.
* @{
*/
-int LIBMTP_Detect_Descriptor(uint16_t*,uint16_t*);
+LIBMTP_error_number_t LIBMTP_Detect_Raw_Devices(LIBMTP_raw_device_t **, int *);
+LIBMTP_mtpdevice_t *LIBMTP_Open_Raw_Device(LIBMTP_raw_device_t *);
+/* Begin old, legacy interface */
LIBMTP_mtpdevice_t *LIBMTP_Get_First_Device(void);
LIBMTP_error_number_t LIBMTP_Get_Connected_Devices(LIBMTP_mtpdevice_t **);
uint32_t LIBMTP_Number_Devices_In_List(LIBMTP_mtpdevice_t *);
void LIBMTP_Release_Device_List(LIBMTP_mtpdevice_t*);
+/* End old, legacy interface */
void LIBMTP_Release_Device(LIBMTP_mtpdevice_t*);
void LIBMTP_Dump_Device_Info(LIBMTP_mtpdevice_t*);
int LIBMTP_Reset_Device(LIBMTP_mtpdevice_t*);
+char *LIBMTP_Get_Manufacturername(LIBMTP_mtpdevice_t*);
char *LIBMTP_Get_Modelname(LIBMTP_mtpdevice_t*);
char *LIBMTP_Get_Serialnumber(LIBMTP_mtpdevice_t*);
char *LIBMTP_Get_Deviceversion(LIBMTP_mtpdevice_t*);
@@ -400,10 +454,10 @@
LIBMTP_progressfunc_t const, void const * const);
int LIBMTP_Send_File_From_File(LIBMTP_mtpdevice_t *, char const * const,
LIBMTP_file_t * const, LIBMTP_progressfunc_t const,
- void const * const, uint32_t const);
+ void const * const);
int LIBMTP_Send_File_From_File_Descriptor(LIBMTP_mtpdevice_t *, int const,
LIBMTP_file_t * const, LIBMTP_progressfunc_t const,
- void const * const, uint32_t const);
+ void const * const);
LIBMTP_filesampledata_t *LIBMTP_new_filesampledata_t(void);
void LIBMTP_destroy_filesampledata_t(LIBMTP_filesampledata_t *);
int LIBMTP_Get_Representative_Sample_Format(LIBMTP_mtpdevice_t *,
@@ -411,6 +465,8 @@
LIBMTP_filesampledata_t **);
int LIBMTP_Send_Representative_Sample(LIBMTP_mtpdevice_t *, uint32_t const,
LIBMTP_filesampledata_t *);
+int LIBMTP_Get_Representative_Sample(LIBMTP_mtpdevice_t *, uint32_t const,
+ LIBMTP_filesampledata_t *);
/**
* @}
@@ -430,11 +486,11 @@
int LIBMTP_Send_Track_From_File(LIBMTP_mtpdevice_t *,
char const * const, LIBMTP_track_t * const,
LIBMTP_progressfunc_t const,
- void const * const, uint32_t const);
+ void const * const);
int LIBMTP_Send_Track_From_File_Descriptor(LIBMTP_mtpdevice_t *,
int const, LIBMTP_track_t * const,
LIBMTP_progressfunc_t const,
- void const * const, uint32_t const);
+ void const * const);
int LIBMTP_Update_Track_Metadata(LIBMTP_mtpdevice_t *,
LIBMTP_track_t const * const);
int LIBMTP_Track_Exists(LIBMTP_mtpdevice_t *, uint32_t);
@@ -449,7 +505,7 @@
void LIBMTP_destroy_folder_t(LIBMTP_folder_t*);
LIBMTP_folder_t *LIBMTP_Get_Folder_List(LIBMTP_mtpdevice_t*);
LIBMTP_folder_t *LIBMTP_Find_Folder(LIBMTP_folder_t*, uint32_t const);
-uint32_t LIBMTP_Create_Folder(LIBMTP_mtpdevice_t*, char *, uint32_t);
+uint32_t LIBMTP_Create_Folder(LIBMTP_mtpdevice_t*, char *, uint32_t, uint32_t);
/** @} */
@@ -462,7 +518,7 @@
void LIBMTP_destroy_playlist_t(LIBMTP_playlist_t *);
LIBMTP_playlist_t *LIBMTP_Get_Playlist_List(LIBMTP_mtpdevice_t *);
LIBMTP_playlist_t *LIBMTP_Get_Playlist(LIBMTP_mtpdevice_t *, uint32_t const);
-int LIBMTP_Create_New_Playlist(LIBMTP_mtpdevice_t *, LIBMTP_playlist_t * const, uint32_t const);
+int LIBMTP_Create_New_Playlist(LIBMTP_mtpdevice_t *, LIBMTP_playlist_t * const);
int LIBMTP_Update_Playlist(LIBMTP_mtpdevice_t *, LIBMTP_playlist_t const * const);
/**
@@ -474,7 +530,7 @@
void LIBMTP_destroy_album_t(LIBMTP_album_t *);
LIBMTP_album_t *LIBMTP_Get_Album_List(LIBMTP_mtpdevice_t *);
LIBMTP_album_t *LIBMTP_Get_Album(LIBMTP_mtpdevice_t *, uint32_t const);
-int LIBMTP_Create_New_Album(LIBMTP_mtpdevice_t *, LIBMTP_album_t * const, uint32_t const);
+int LIBMTP_Create_New_Album(LIBMTP_mtpdevice_t *, LIBMTP_album_t * const);
int LIBMTP_Update_Album(LIBMTP_mtpdevice_t *, LIBMTP_album_t const * const);
/**
@@ -483,6 +539,7 @@
* @{
*/
int LIBMTP_Delete_Object(LIBMTP_mtpdevice_t *, uint32_t);
+int LIBMTP_Set_Object_Filename(LIBMTP_mtpdevice_t *, uint32_t , char *);
/** @} */
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/src/libusb-glue.c
^
|
@@ -3,7 +3,7 @@
* Low-level USB interface glue towards libusb.
*
* Copyright (C) 2005-2007 Richard A. Low <richard@wentnet.com>
- * Copyright (C) 2005-2007 Linus Walleij <triad@df.lth.se>
+ * Copyright (C) 2005-2008 Linus Walleij <triad@df.lth.se>
* Copyright (C) 2006-2007 Marcus Meissner
* Copyright (C) 2007 Ted Bullock
*
@@ -64,6 +64,16 @@
#define USB_FEATURE_HALT 0x00
#endif
+/* Internal data types */
+struct mtpdevice_list_struct {
+ struct usb_device *libusb_device;
+ PTPParams *params;
+ PTP_USB *ptp_usb;
+ uint32_t bus_location;
+ struct mtpdevice_list_struct *next;
+};
+typedef struct mtpdevice_list_struct mtpdevice_list_t;
+
static const LIBMTP_device_entry_t mtp_device_table[] = {
/* We include an .h file which is shared between us and libgphoto2 */
#include "music-players.h"
@@ -125,12 +135,14 @@
* Small recursive function to append a new usb_device to the linked list of
* USB MTP devices
* @param devlist dynamic linked list of pointers to usb devices with MTP
- * properties.
- * @param next New USB MTP device to be added to list
- * @return nothing
+ * properties, to be extended with new device.
+ * @param newdevice the new device to add.
+ * @param bus_location bus for this device.
+ * @return an extended array or NULL on failure.
*/
static mtpdevice_list_t *append_to_mtpdevice_list(mtpdevice_list_t *devlist,
- struct usb_device *newdevice)
+ struct usb_device *newdevice,
+ uint32_t bus_location)
{
mtpdevice_list_t *new_list_entry;
@@ -140,6 +152,7 @@
}
// Fill in USB device, if we *HAVE* to make a copy of the device do it here.
new_list_entry->libusb_device = newdevice;
+ new_list_entry->bus_location = bus_location;
new_list_entry->next = NULL;
if (devlist == NULL) {
@@ -161,7 +174,7 @@
* properties.
* @return nothing
*/
-void free_mtpdevice_list(mtpdevice_list_t *devlist)
+static void free_mtpdevice_list(mtpdevice_list_t *devlist)
{
mtpdevice_list_t *tmplist = devlist;
@@ -346,8 +359,8 @@
* This function scans through the connected usb devices on a machine and
* if they match known Vendor and Product identifiers appends them to the
* dynamic array mtp_device_list. Be sure to call
- * <code>free(mtp_device_list)</code> when you are done with it, assuming it
- * is not NULL.
+ * <code>free_mtpdevice_list(mtp_device_list)</code> when you are done
+ * with it, assuming it is not NULL.
* @param mtp_device_list dynamic array of pointers to usb devices with MTP
* properties (if this list is not empty, new entries will be appended
* to the list).
@@ -372,7 +385,9 @@
if(dev->descriptor.idVendor == mtp_device_table[i].vendor_id &&
dev->descriptor.idProduct == mtp_device_table[i].product_id) {
/* Append this usb device to the MTP device list */
- *mtp_device_list = append_to_mtpdevice_list(*mtp_device_list, dev);
+ *mtp_device_list = append_to_mtpdevice_list(*mtp_device_list,
+ dev,
+ bus->location);
found = 1;
break;
}
@@ -381,7 +396,9 @@
if (!found) {
if (probe_device_descriptor(dev, NULL)) {
/* Append this usb device to the MTP USB Device List */
- *mtp_device_list = append_to_mtpdevice_list(*mtp_device_list, dev);
+ *mtp_device_list = append_to_mtpdevice_list(*mtp_device_list,
+ dev,
+ bus->location);
}
}
}
@@ -396,31 +413,115 @@
}
/**
- * Detect the MTP device descriptor and return the VID and PID
- * of the first device found. This is a very low-level function
- * which is intended for use with <b>udev</b> or other hotplug
- * mechanisms. The idea is that a script may want to know if the
- * just plugged-in device was an MTP device or not.
+ * Detect the raw MTP device descriptors and return a list of
+ * of the devices found.
*
- * @param vid the Vendor ID (VID) of the first device found.
- * @param pid the Product ID (PID) of the first device found.
- * @return the number of detected devices or -1 if the call
- * was unsuccessful.
+ * @param devices a pointer to a variable that will hold
+ * the list of raw devices found. This may be NULL
+ * on return if the number of detected devices is zero.
+ * The user shall simply <code>free()</code> this
+ * variable when finished with the raw devices,
+ * in order to release memory.
+ * @param numdevs a pointer to an integer that will hold
+ * the number of devices in the list. This may
+ * be 0.
+ * @return 0 if successful, any other value means failure.
*/
-int LIBMTP_Detect_Descriptor(uint16_t *vid, uint16_t *pid)
+LIBMTP_error_number_t LIBMTP_Detect_Raw_Devices(LIBMTP_raw_device_t ** devices,
+ int * numdevs)
{
- mtpdevice_list_t *devlist;
- LIBMTP_error_number_t ret;
+ mtpdevice_list_t *devlist = NULL;
+ mtpdevice_list_t *dev;
+ LIBMTP_error_number_t ret;
+ LIBMTP_raw_device_t *retdevs;
+ int devs = 0;
+ int i, j;
ret = get_mtp_usb_device_list(&devlist);
- if (ret != LIBMTP_ERROR_NONE) {
- *vid = *pid = 0;
- return -1;
+ if (ret == LIBMTP_ERROR_NO_DEVICE_ATTACHED) {
+ *devices = NULL;
+ *numdevs = 0;
+ return ret;
+ } else if (ret != LIBMTP_ERROR_NONE) {
+ fprintf(stderr, "LIBMTP PANIC: get_mtp_usb_device_list() "
+ "error code: %d on line %d\n", ret, __LINE__);
+ return ret;
}
- *vid = devlist->libusb_device->descriptor.idVendor;
- *pid = devlist->libusb_device->descriptor.idProduct;
+
+ // Get list size
+ dev = devlist;
+ while (dev != NULL) {
+ devs++;
+ dev = dev->next;
+ }
+ if (devs == 0) {
+ *devices = NULL;
+ *numdevs = 0;
+ return LIBMTP_ERROR_NONE;
+ }
+ // Conjure a device list
+ retdevs = (LIBMTP_raw_device_t *) malloc(sizeof(LIBMTP_raw_device_t) * devs);
+ if (retdevs == NULL) {
+ // Out of memory
+ *devices = NULL;
+ *numdevs = 0;
+ return LIBMTP_ERROR_MEMORY_ALLOCATION;
+ }
+ dev = devlist;
+ i = 0;
+ while (dev != NULL) {
+ int device_known = 0;
+
+ // Assign default device info
+ retdevs[i].device_entry.vendor = NULL;
+ retdevs[i].device_entry.vendor_id = dev->libusb_device->descriptor.idVendor;
+ retdevs[i].device_entry.product = NULL;
+ retdevs[i].device_entry.product_id = dev->libusb_device->descriptor.idProduct;
+ retdevs[i].device_entry.device_flags = 0x00000000U;
+ // See if we can locate some additional vendor info and device flags
+ for(j = 0; j < mtp_device_table_size; j++) {
+ if(dev->libusb_device->descriptor.idVendor == mtp_device_table[j].vendor_id &&
+ dev->libusb_device->descriptor.idProduct == mtp_device_table[j].product_id) {
+ device_known = 1;
+ retdevs[i].device_entry.vendor = mtp_device_table[j].vendor;
+ retdevs[i].device_entry.product = mtp_device_table[j].product;
+ retdevs[i].device_entry.device_flags = mtp_device_table[j].device_flags;
+#ifdef ENABLE_USB_BULK_DEBUG
+ // This device is known to the developers
+ fprintf(stderr, "Device %d (VID=%04x and PID=%04x) is a %s %s.\n",
+ i,
+ dev->libusb_device->descriptor.idVendor,
+ dev->libusb_device->descriptor.idProduct,
+ mtp_device_table[j].vendor,
+ mtp_device_table[j].product);
+#endif
+ break;
+ }
+ }
+ if (!device_known) {
+ // This device is unknown to the developers
+ fprintf(stderr, "Device %d (VID=%04x and PID=%04x) is UNKNOWN.\n",
+ i,
+ dev->libusb_device->descriptor.idVendor,
+ dev->libusb_device->descriptor.idProduct);
+ fprintf(stderr, "Please report this VID/PID and the device model to the "
+ "libmtp development team\n");
+ /*
+ * Trying to get iManufacturer or iProduct from the device at this
+ * point would require opening a device handle, that we don't want
+ * to do right now. (Takes time for no good enough reason.)
+ */
+ }
+ // Save the location on the bus
+ retdevs[i].bus_location = dev->bus_location;
+ retdevs[i].devnum = dev->libusb_device->devnum;
+ i++;
+ dev = dev->next;
+ }
+ *devices = retdevs;
+ *numdevs = i;
free_mtpdevice_list(devlist);
- return 1;
+ return LIBMTP_ERROR_NONE;
}
/**
@@ -451,11 +552,39 @@
printf(" idProduct: %04x\n", dev->descriptor.idProduct);
printf(" IN endpoint maxpacket: %d bytes\n", ptp_usb->inep_maxpacket);
printf(" OUT endpoint maxpacket: %d bytes\n", ptp_usb->outep_maxpacket);
- printf(" Device flags: 0x%08x\n", ptp_usb->device_flags);
- // TODO: add in string dumps for iManufacturer, iProduct, iSerialnumber...
+ printf(" Raw device info:\n");
+ printf(" Bus location: %d\n", ptp_usb->rawdevice.bus_location);
+ printf(" Device number: %d\n", ptp_usb->rawdevice.devnum);
+ printf(" Device entry info:\n");
+ printf(" Vendor: %s\n", ptp_usb->rawdevice.device_entry.vendor);
+ printf(" Vendor id: 0x%04x\n", ptp_usb->rawdevice.device_entry.vendor_id);
+ printf(" Product: %s\n", ptp_usb->rawdevice.device_entry.product);
+ printf(" Vendor id: 0x%04x\n", ptp_usb->rawdevice.device_entry.product_id);
+ printf(" Device flags: 0x%08x\n", ptp_usb->rawdevice.device_entry.device_flags);
(void) probe_device_descriptor(dev, stdout);
}
+/**
+ * Retrieve the apropriate playlist extension for this
+ * device. Rather hacky at the moment. This is probably
+ * desired by the managing software, but when creating
+ * lists on the device itself you notice certain preferences.
+ * @param ptp_usb the USB device to get suggestion for.
+ * @return the suggested playlist extension.
+ */
+char const * const get_playlist_extension(PTP_USB *ptp_usb)
+{
+ struct usb_device *dev;
+ static char creative_pl_extension[] = ".zpl";
+ static char default_pl_extension[] = ".pla";
+
+ dev = usb_device(ptp_usb->handle);
+ if (dev->descriptor.idVendor == 0x041e) {
+ return creative_pl_extension;
+ }
+ return default_pl_extension;
+}
+
static void
ptp_debug (PTPParams *params, const char *format, ...)
{
@@ -534,7 +663,7 @@
while (curread < size) {
#ifdef ENABLE_USB_BULK_DEBUG
- printf("Remaining size to read: 0x%04x bytes\n", size - curread);
+ printf("Remaining size to read: 0x%04lx bytes\n", size - curread);
#endif
// check equal to condition here
if (size - curread < CONTEXT_BLOCK_SIZE)
@@ -542,7 +671,7 @@
// this is the last packet
toread = size - curread;
// this is equivalent to zero read for these devices
- if (readzero && ptp_usb->device_flags & DEVICE_FLAG_NO_ZERO_READS && toread % 64 == 0) {
+ if (readzero && FLAG_NO_ZERO_READS(ptp_usb) && toread % 64 == 0) {
toread += 1;
expect_terminator_byte = 1;
}
@@ -559,7 +688,7 @@
(unsigned int) toread, (unsigned int) (size-curread));
#ifdef ENABLE_USB_BULK_DEBUG
- printf("Reading in 0x%04x bytes\n", toread);
+ printf("Reading in 0x%04lx bytes\n", toread);
#endif
result = USB_BULK_READ(ptp_usb->handle, ptp_usb->inep, (char*)bytes, toread, USB_TIMEOUT);
#ifdef ENABLE_USB_BULK_DEBUG
@@ -617,7 +746,7 @@
// there might be a zero packet waiting for us...
if (readzero &&
- !(ptp_usb->device_flags & DEVICE_FLAG_NO_ZERO_READS) &&
+ !FLAG_NO_ZERO_READS(ptp_usb) &&
curread % ptp_usb->outep_maxpacket == 0) {
char temp;
int zeroresult = 0;
@@ -823,8 +952,14 @@
uint16_t ret;
PTPUSBBulkContainer usbreq;
PTPDataHandler memhandler;
- unsigned long written, towrite;
+ unsigned long written = 0;
+ unsigned long towrite;
+#ifdef ENABLE_USB_BULK_DEBUG
+ char txt[256];
+ (void) ptp_render_opcode (params, req->Code, sizeof(txt), txt);
+ printf("REQUEST: 0x%04x, %s\n", req->Code, txt);
+#endif
/* build appropriate USB container */
usbreq.length=htod32(PTP_USB_BULK_REQ_LEN-
(sizeof(uint32_t)*(5-req->Nparam)));
@@ -870,6 +1005,9 @@
uint32_t bytes_left_to_transfer;
PTPDataHandler memhandler;
+#ifdef ENABLE_USB_BULK_DEBUG
+ printf("SEND DATA PHASE\n");
+#endif
/* build appropriate USB container */
usbdata.length = htod32(PTP_USB_BULK_HDR_LEN+size);
usbdata.type = htod16(PTP_USB_CONTAINER_DATA);
@@ -955,6 +1093,9 @@
unsigned long written;
PTP_USB *ptp_usb = (PTP_USB *) params->data;
+#ifdef ENABLE_USB_BULK_DEBUG
+ printf("GET DATA PHASE\n");
+#endif
memset(&usbdata,0,sizeof(usbdata));
do {
unsigned long len, rlen;
@@ -969,7 +1110,7 @@
break;
}
if (dtoh16(usbdata.code)!=ptp->Code) {
- if (ptp_usb->device_flags & DEVICE_FLAG_IGNORE_HEADER_ERRORS) {
+ if (FLAG_IGNORE_HEADER_ERRORS(ptp_usb)) {
ptp_debug (params, "ptp2/ptp_usb_getdata: detected a broken "
"PTP header, code field insane, expect problems! (But continuing)");
// Repair the header, so it won't wreak more havoc, don't just ignore it.
@@ -1033,8 +1174,8 @@
(uint8_t *) &usbdata + packlen, surplen);
params->response_packet_size = surplen;
/* Ignore reading one extra byte if device flags have been set */
- } else if(( !(ptp_usb->device_flags & DEVICE_FLAG_NO_ZERO_READS) &&
- rlen - dtoh32(usbdata.length) == 1)) {
+ } else if(!FLAG_NO_ZERO_READS(ptp_usb) &&
+ (rlen - dtoh32(usbdata.length) == 1)) {
ptp_debug (params, "ptp2/ptp_usb_getdata: read %d bytes "
"too much, expect problems!",
rlen - dtoh32(usbdata.length));
@@ -1059,7 +1200,7 @@
&written
);
- if (ptp_usb->device_flags & DEVICE_FLAG_NO_ZERO_READS &&
+ if (FLAG_NO_ZERO_READS(ptp_usb) &&
len+PTP_USB_BULK_HDR_LEN == PTP_USB_BULK_HS_MAX_PACKET_LEN_READ) {
#ifdef ENABLE_USB_BULK_DEBUG
printf("Reading in extra terminating byte\n");
@@ -1108,10 +1249,24 @@
PTPUSBBulkContainer usbresp;
PTP_USB *ptp_usb = (PTP_USB *)(params->data);
+#ifdef ENABLE_USB_BULK_DEBUG
+ printf("RESPONSE: ");
+#endif
memset(&usbresp,0,sizeof(usbresp));
/* read response, it should never be longer than sizeof(usbresp) */
ret = ptp_usb_getpacket(params, &usbresp, &rlen);
+ // Fix for bevahiour reported by Scott Snyder on Samsung YP-U3. The player
+ // sends a packet containing just zeroes of length 2 (up to 4 has been seen too)
+ // after a NULL packet when it should send the response. This code ignores
+ // such illegal packets.
+ while (ret==PTP_RC_OK && rlen<PTP_USB_BULK_HDR_LEN && usbresp.length==0) {
+ ptp_debug (params, "ptp_usb_getresp: detected short response "
+ "of %d bytes, expect problems! (re-reading "
+ "response), rlen");
+ ret = ptp_usb_getpacket(params, &usbresp, &rlen);
+ }
+
if (ret!=PTP_RC_OK) {
ret = PTP_ERROR_IO;
} else
@@ -1121,6 +1276,9 @@
if (dtoh16(usbresp.code)!=resp->Code) {
ret = dtoh16(usbresp.code);
}
+#ifdef ENABLE_USB_BULK_DEBUG
+ printf("%04x\n", ret);
+#endif
if (ret!=PTP_RC_OK) {
/* ptp_error (params,
"PTP: request code 0x%04x getting resp error 0x%04x",
@@ -1131,10 +1289,11 @@
resp->Code=dtoh16(usbresp.code);
resp->SessionID=params->session_id;
resp->Transaction_ID=dtoh32(usbresp.trans_id);
- if (ptp_usb->device_flags & DEVICE_FLAG_IGNORE_HEADER_ERRORS) {
+ if (FLAG_IGNORE_HEADER_ERRORS(ptp_usb)) {
if (resp->Transaction_ID != params->transaction_id-1) {
ptp_debug (params, "ptp_usb_getresp: detected a broken "
- "PTP header, transaction ID insane, expect problems! (But continuing)");
+ "PTP header, transaction ID insane, expect "
+ "problems! (But continuing)");
// Repair the header, so it won't wreak more havoc.
resp->Transaction_ID = params->transaction_id-1;
}
@@ -1265,7 +1424,7 @@
* drivers (such as mass storage), then try to unload it to make it
* accessible from user space.
*/
- if (ptp_usb->device_flags & DEVICE_FLAG_UNLOAD_DRIVER) {
+ if (FLAG_UNLOAD_DRIVER(ptp_usb)) {
if (usb_detach_kernel_driver_np(device_handle, (int) ptp_usb->interface)) {
// Totally ignore this error!
// perror("usb_detach_kernel_driver_np()");
@@ -1343,8 +1502,17 @@
{
// Commented out since it was confusing some
// devices to do these things.
- if (!(ptp_usb->device_flags & DEVICE_FLAG_NO_RELEASE_INTERFACE)) {
- // Clear any stalled endpoints
+ if (!FLAG_NO_RELEASE_INTERFACE(ptp_usb)) {
+ /*
+ * Clear any stalled endpoints
+ * On misbehaving devices designed for Windows/Mac, quote from:
+ * http://www2.one-eyed-alien.net/~mdharm/linux-usb/target_offenses.txt
+ * Device does Bad Things(tm) when it gets a GET_STATUS after CLEAR_HALT
+ * (...) Windows, when clearing a stall, only sends the CLEAR_HALT command,
+ * and presumes that the stall has cleared. Some devices actually choke
+ * if the CLEAR_HALT is followed by a GET_STATUS (used to determine if the
+ * STALL is persistant or not).
+ */
clear_stall(ptp_usb);
// Clear halts on any endpoints
clear_halt(ptp_usb);
@@ -1360,221 +1528,9 @@
usb_close(ptp_usb->handle);
}
-static LIBMTP_error_number_t prime_device_memory(mtpdevice_list_t *devlist)
-{
- mtpdevice_list_t *tmplist = devlist;
-
- while (tmplist != NULL) {
- /* Allocate a parameter box */
- tmplist->params = (PTPParams *) malloc(sizeof(PTPParams));
- tmplist->ptp_usb = (PTP_USB *) malloc(sizeof(PTP_USB));
-
- /* Check for allocation Error */
- if(tmplist->params == NULL || tmplist->ptp_usb == NULL) {
- /* Error and deallocation of memory will be handled by caller. */
- return LIBMTP_ERROR_MEMORY_ALLOCATION;
- }
-
- /* Start with a blank slate (includes setting device_flags to 0) */
- memset(tmplist->params, 0, sizeof(PTPParams));
- memset(tmplist->ptp_usb, 0, sizeof(PTP_USB));
- tmplist = tmplist->next;
- }
- return LIBMTP_ERROR_NONE;
-}
-
-static void assign_known_device_flags(mtpdevice_list_t *devlist)
-{
- int i;
- mtpdevice_list_t *tmplist = devlist;
- uint8_t current_device = 0;
-
- /* Search through known device list and set correct device flags */
- while (tmplist != NULL) {
- int device_known = 0;
-
- for(i = 0; i < mtp_device_table_size; i++) {
- if(tmplist->libusb_device->descriptor.idVendor == mtp_device_table[i].vendor_id &&
- tmplist->libusb_device->descriptor.idProduct == mtp_device_table[i].product_id) {
- /* This device is known, assign the correct device flags */
- /* Note that ptp_usb[current_device] could potentially be NULL */
- if(tmplist->ptp_usb != NULL) {
- tmplist->ptp_usb->device_flags = mtp_device_table[i].device_flags;
-
- /*
- * TODO:
- * Preferable to not do this with #ifdef ENABLE_USB_BULK_DEBUG but there is
- * currently no other compile time debug option
- */
-
- device_known = 1;
-#ifdef ENABLE_USB_BULK_DEBUG
- /* This device is known to the developers */
- fprintf(stderr, "Device %d (VID=%04x and PID=%04x) is a %s %s.\n",
- current_device + 1,
- tmplist->libusb_device->descriptor.idVendor,
- tmplist->libusb_device->descriptor.idProduct,
- mtp_device_table[i].vendor, mtp_device_table[i].product);
-#endif
- }
- break;
- }
- }
- if (!device_known) {
- /* This device is unknown to the developers */
- fprintf(stderr, "Device %d (VID=%04x and PID=%04x) is UNKNOWN.\n",
- current_device + 1,
- tmplist->libusb_device->descriptor.idVendor,
- tmplist->libusb_device->descriptor.idProduct);
- fprintf(stderr, "Please report this VID/PID and the device model to the "
- "libmtp development team\n");
- }
- tmplist = tmplist->next;
- current_device++;
- }
-}
-
-
-static LIBMTP_error_number_t configure_usb_devices(mtpdevice_list_t *devicelist)
-{
- mtpdevice_list_t *tmplist = devicelist;
- uint16_t ret = 0;
- uint8_t current_device = 0;
-
- while (tmplist != NULL) {
- /* This is erroneous, there must be a PTP_USB instance that we can initialize. */
- if(tmplist->ptp_usb == NULL) {
- return LIBMTP_ERROR_MEMORY_ALLOCATION;
- }
-
- /* Pointer back to params */
- tmplist->ptp_usb->params = tmplist->params;
-
- /* TODO: Will this always be little endian? */
- tmplist->params->byteorder = PTP_DL_LE;
- tmplist->params->cd_locale_to_ucs2 = iconv_open("UCS-2LE", "UTF-8");
- tmplist->params->cd_ucs2_to_locale = iconv_open("UTF-8", "UCS-2LE");
-
- if(tmplist->params->cd_locale_to_ucs2 == (iconv_t) -1 ||
- tmplist->params->cd_ucs2_to_locale == (iconv_t) -1) {
- fprintf(stderr, "LIBMTP PANIC: Cannot open iconv() converters to/from UCS-2!\n"
- "Too old stdlibc, glibc and libiconv?\n");
- return LIBMTP_ERROR_CONNECTING;
- }
-
- // ep = device->config->interface->altsetting->endpoint;
- // no_of_ep = device->config->interface->altsetting->bNumEndpoints;
-
- /* Assign endpoints to usbinfo... */
- find_interface_and_endpoints(tmplist->libusb_device,
- &tmplist->ptp_usb->interface,
- &tmplist->ptp_usb->inep,
- &tmplist->ptp_usb->inep_maxpacket,
- &tmplist->ptp_usb->outep,
- &tmplist->ptp_usb->outep_maxpacket,
- &tmplist->ptp_usb->intep);
-
- /* Attempt to initialize this device */
- if (init_ptp_usb(tmplist->params, tmplist->ptp_usb, tmplist->libusb_device) < 0) {
- fprintf(stderr, "LIBMTP PANIC: Unable to initialize device %d\n", current_device+1);
- // FIXME: perhaps use "continue" to keep trying the other devices.
- return LIBMTP_ERROR_CONNECTING;
- }
-
- /*
- * This works in situations where previous bad applications
- * have not used LIBMTP_Release_Device on exit
- */
- if ((ret = ptp_opensession(tmplist->params, 1)) == PTP_ERROR_IO) {
- fprintf(stderr, "PTP_ERROR_IO: Trying again after re-initializing USB interface\n");
- close_usb(tmplist->ptp_usb);
-
- if(init_ptp_usb(tmplist->params, tmplist->ptp_usb, tmplist->libusb_device) <0) {
- fprintf(stderr, "LIBMTP PANIC: Could not open session on device %d\n", current_device+1);
- return LIBMTP_ERROR_CONNECTING;
- }
-
- /* Device has been reset, try again */
- ret = ptp_opensession(tmplist->params, 1);
- }
-
- /* Was the transaction id invalid? Try again */
- if (ret == PTP_RC_InvalidTransactionID) {
- fprintf(stderr, "LIBMTP WARNING: Transaction ID was invalid, increment and try again\n");
- tmplist->params->transaction_id += 10;
- ret = ptp_opensession(tmplist->params, 1);
- }
-
- if (ret != PTP_RC_SessionAlreadyOpened && ret != PTP_RC_OK) {
- fprintf(stderr, "LIBMTP PANIC: Could not open session! "
- "(Return code %d)\n Try to reset the device.\n",
- ret);
- usb_release_interface(tmplist->ptp_usb->handle,
- (int) tmplist->ptp_usb->interface);
- return LIBMTP_ERROR_CONNECTING;
- }
-
- tmplist = tmplist->next;
- current_device++;
- }
-
- /* Exit with the nice list */
- return LIBMTP_ERROR_NONE;
-}
-
/**
- * This function scans through the results of the get_mtp_usb_device_list
- * function and attempts to connect to those devices listed using the
- * mtp_device_table at the top of the file. Returns a LIBMTP_error_number_t.
- *
- * @param devlist a list of devices with primed PTP_USB and params structs.
- * @return Error Codes as per the type definition
- */
-LIBMTP_error_number_t find_usb_devices(mtpdevice_list_t **devlist)
-{
- mtpdevice_list_t *mtp_device_list = NULL;
- LIBMTP_error_number_t ret;
-
- /*
- * Recover list of attached USB devices that match MTP criteria, i.e.
- * it either has an MTP device descriptor or it is in the known
- * devices list.
- */
- ret = get_mtp_usb_device_list (&mtp_device_list);
- if (ret != LIBMTP_ERROR_NONE) {
- return ret;
- }
-
- // Then prime them
- ret = prime_device_memory(mtp_device_list);
- if(ret) {
- fprintf(stderr, "LIBMTP PANIC: prime_device_memory() error code: %d on line %d\n", ret, __LINE__);
- goto find_usb_devices_error_exit;
- }
-
- /* Assign specific device flags and detect unknown devices */
- assign_known_device_flags(mtp_device_list);
-
- /* Configure the devices */
- ret = configure_usb_devices(mtp_device_list);
- if(ret) {
- fprintf(stderr, "LIBMTP PANIC: configure_usb_devices() error code: %d on line %d\n", ret, __LINE__);
- goto find_usb_devices_error_exit;
- }
-
- /* we're connected to all devices, return the list and OK */
- *devlist = mtp_device_list;
- return LIBMTP_ERROR_NONE;
-
- find_usb_devices_error_exit:
- if(mtp_device_list != NULL) {
- free_mtpdevice_list(mtp_device_list);
- mtp_device_list = NULL;
- }
- *devlist = NULL;
- return ret;
-}
-
+ * Self-explanatory?
+ */
static void find_interface_and_endpoints(struct usb_device *dev,
uint8_t *interface,
int* inep,
@@ -1632,6 +1588,121 @@
}
}
+/**
+ * This function assigns params and usbinfo given a raw device
+ * as input.
+ * @param device the device to be assigned.
+ * @param usbinfo a pointer to the new usbinfo.
+ * @return an error code.
+ */
+LIBMTP_error_number_t configure_usb_device(LIBMTP_raw_device_t *device,
+ PTPParams *params,
+ void **usbinfo)
+{
+ PTP_USB *ptp_usb;
+ struct usb_device *libusb_device;
+ uint16_t ret = 0;
+ struct usb_bus *bus;
+ int found = 0;
+
+ /* See if we can find this raw device again... */
+ bus = init_usb();
+ for (; bus != NULL; bus = bus->next) {
+ if (bus->location == device->bus_location) {
+ struct usb_device *dev = bus->devices;
+
+ for (; dev != NULL; dev = dev->next) {
+ if(dev->devnum == device->devnum &&
+ dev->descriptor.idVendor == device->device_entry.vendor_id &&
+ dev->descriptor.idProduct == device->device_entry.product_id ) {
+ libusb_device = dev;
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ break;
+ }
+ }
+ /* Device has gone since detecting raw devices! */
+ if (!found) {
+ return LIBMTP_ERROR_NO_DEVICE_ATTACHED;
+ }
+
+ /* Allocate structs */
+ ptp_usb = (PTP_USB *) malloc(sizeof(PTP_USB));
+ if (ptp_usb == NULL) {
+ return LIBMTP_ERROR_MEMORY_ALLOCATION;
+ }
+ /* Start with a blank slate (includes setting device_flags to 0) */
+ memset(ptp_usb, 0, sizeof(PTP_USB));
+
+ /* Copy the raw device */
+ memcpy(&ptp_usb->rawdevice, device, sizeof(LIBMTP_raw_device_t));
+
+ /*
+ * Some devices must have their "OS Descriptor" massaged in order
+ * to work.
+ */
+ if (FLAG_ALWAYS_PROBE_DESCRIPTOR(ptp_usb)) {
+ // Massage the device descriptor
+ (void) probe_device_descriptor(libusb_device, NULL);
+ }
+
+ /* Assign endpoints to usbinfo... */
+ find_interface_and_endpoints(libusb_device,
+ &ptp_usb->interface,
+ &ptp_usb->inep,
+ &ptp_usb->inep_maxpacket,
+ &ptp_usb->outep,
+ &ptp_usb->outep_maxpacket,
+ &ptp_usb->intep);
+
+ /* Attempt to initialize this device */
+ if (init_ptp_usb(params, ptp_usb, libusb_device) < 0) {
+ fprintf(stderr, "LIBMTP PANIC: Unable to initialize device\n");
+ return LIBMTP_ERROR_CONNECTING;
+ }
+
+ /*
+ * This works in situations where previous bad applications
+ * have not used LIBMTP_Release_Device on exit
+ */
+ if ((ret = ptp_opensession(params, 1)) == PTP_ERROR_IO) {
+ fprintf(stderr, "PTP_ERROR_IO: Trying again after re-initializing USB interface\n");
+ close_usb(ptp_usb);
+
+ if(init_ptp_usb(params, ptp_usb, libusb_device) <0) {
+ fprintf(stderr, "LIBMTP PANIC: Could not open session on device\n");
+ return LIBMTP_ERROR_CONNECTING;
+ }
+
+ /* Device has been reset, try again */
+ ret = ptp_opensession(params, 1);
+ }
+
+ /* Was the transaction id invalid? Try again */
+ if (ret == PTP_RC_InvalidTransactionID) {
+ fprintf(stderr, "LIBMTP WARNING: Transaction ID was invalid, increment and try again\n");
+ params->transaction_id += 10;
+ ret = ptp_opensession(params, 1);
+ }
+
+ if (ret != PTP_RC_SessionAlreadyOpened && ret != PTP_RC_OK) {
+ fprintf(stderr, "LIBMTP PANIC: Could not open session! "
+ "(Return code %d)\n Try to reset the device.\n",
+ ret);
+ usb_release_interface(ptp_usb->handle,
+ (int) ptp_usb->interface);
+ return LIBMTP_ERROR_CONNECTING;
+ }
+
+ /* OK configured properly */
+ *usbinfo = (void *) ptp_usb;
+ return LIBMTP_ERROR_NONE;
+}
+
+
void close_device (PTP_USB *ptp_usb, PTPParams *params)
{
if (ptp_closesession(params)!=PTP_RC_OK)
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/src/libusb-glue.h
^
|
@@ -30,6 +30,7 @@
#include "ptp.h"
#include <usb.h>
#include "libmtp.h"
+#include "device-flags.h"
#define USB_BULK_READ usb_bulk_read
#define USB_BULK_WRITE usb_bulk_write
@@ -54,22 +55,42 @@
LIBMTP_progressfunc_t current_transfer_callback;
void const * current_transfer_callback_data;
/** Any special device flags, only used internally */
- uint32_t device_flags;
+ LIBMTP_raw_device_t rawdevice;
};
-struct mtpdevice_list_struct {
- struct usb_device *libusb_device;
- PTPParams *params;
- PTP_USB *ptp_usb;
- struct mtpdevice_list_struct *next;
-};
-typedef struct mtpdevice_list_struct mtpdevice_list_t;
-
int open_device (int busn, int devn, short force, PTP_USB *ptp_usb, PTPParams *params, struct usb_device **dev);
void dump_usbinfo(PTP_USB *ptp_usb);
-void close_device (PTP_USB *ptp_usb, PTPParams *params);
-LIBMTP_error_number_t find_usb_devices(mtpdevice_list_t **devlist);
-void free_mtpdevice_list(mtpdevice_list_t *devlist);
+char const * const get_playlist_extension(PTP_USB *ptp_usb);
+void close_device(PTP_USB *ptp_usb, PTPParams *params);
+LIBMTP_error_number_t configure_usb_device(LIBMTP_raw_device_t *device,
+ PTPParams *params,
+ void **usbinfo);
+
+/* Flag check macros */
+#define FLAG_BROKEN_MTPGETOBJPROPLIST_ALL(a) \
+ ((a)->rawdevice.device_entry.device_flags & DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL)
+#define FLAG_UNLOAD_DRIVER(a) \
+ ((a)->rawdevice.device_entry.device_flags & DEVICE_FLAG_UNLOAD_DRIVER)
+#define FLAG_BROKEN_MTPGETOBJPROPLIST(a) \
+ ((a)->rawdevice.device_entry.device_flags & DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST)
+#define FLAG_NO_ZERO_READS(a) \
+ ((a)->rawdevice.device_entry.device_flags & DEVICE_FLAG_NO_ZERO_READS)
+#define FLAG_IRIVER_OGG_ALZHEIMER(a) \
+ ((a)->rawdevice.device_entry.device_flags & DEVICE_FLAG_IRIVER_OGG_ALZHEIMER)
+#define FLAG_ONLY_7BIT_FILENAMES(a) \
+ ((a)->rawdevice.device_entry.device_flags & DEVICE_FLAG_ONLY_7BIT_FILENAMES)
+#define FLAG_NO_RELEASE_INTERFACE(a) \
+ ((a)->rawdevice.device_entry.device_flags & DEVICE_FLAG_NO_RELEASE_INTERFACE)
+#define FLAG_IGNORE_HEADER_ERRORS(a) \
+ ((a)->rawdevice.device_entry.device_flags & DEVICE_FLAG_IGNORE_HEADER_ERRORS)
+#define FLAG_BROKEN_SET_OBJECT_PROPLIST(a) \
+ ((a)->rawdevice.device_entry.device_flags & DEVICE_FLAG_BROKEN_SET_OBJECT_PROPLIST)
+#define FLAG_OGG_IS_UNKNOWN(a) \
+ ((a)->rawdevice.device_entry.device_flags & DEVICE_FLAG_OGG_IS_UNKNOWN)
+#define FLAG_BROKEN_SET_SAMPLE_DIMENSIONS(a) \
+ ((a)->rawdevice.device_entry.device_flags & DEVICE_FLAG_BROKEN_SET_SAMPLE_DIMENSIONS)
+#define FLAG_ALWAYS_PROBE_DESCRIPTOR(a) \
+ ((a)->rawdevice.device_entry.device_flags & DEVICE_FLAG_ALWAYS_PROBE_DESCRIPTOR)
/* connect_first_device return codes */
#define PTP_CD_RC_CONNECTED 0
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/src/music-players.h
^
|
@@ -3,7 +3,7 @@
* List of music players as USB ids.
*
* Copyright (C) 2005-2007 Richard A. Low <richard@wentnet.com>
- * Copyright (C) 2005-2007 Linus Walleij <triad@df.lth.se>
+ * Copyright (C) 2005-2008 Linus Walleij <triad@df.lth.se>
* Copyright (C) 2006-2007 Marcus Meissner
* Copyright (C) 2007 Ted Bullock
*
@@ -62,8 +62,9 @@
// Reported by Darel on the XNJB forums
{ "Creative", 0x041e, "ZEN V Plus", 0x4152, DEVICE_FLAG_NONE },
{ "Creative", 0x041e, "ZEN Vision W", 0x4153, DEVICE_FLAG_NONE },
+ // Don't add 0x4155: this is a Zen Stone device which is not MTP
// Reported by Paul Kurczaba <paul@kurczaba.com>
- { "Creative", 0x041e, "ZEN 8GB", 0x4157, DEVICE_FLAG_IGNORE_HEADER_ERRORS },
+ { "Creative", 0x041e, "ZEN", 0x4157, DEVICE_FLAG_IGNORE_HEADER_ERRORS | DEVICE_FLAG_BROKEN_SET_SAMPLE_DIMENSIONS },
// Reported by Ringofan <mcroman@users.sourceforge.net>
{ "Creative", 0x041e, "ZEN V 2GB", 0x4158, DEVICE_FLAG_NONE },
@@ -99,20 +100,31 @@
{ "Samsung", 0x04e8, "YP-F2J", 0x5057, DEVICE_FLAG_UNLOAD_DRIVER },
// Reported by Patrick <skibler@gmail.com>
{ "Samsung", 0x04e8, "YP-K5", 0x505a, DEVICE_FLAG_NO_ZERO_READS },
- // From dev.local@gmail.com - 0x4e8/0x507c is the UMS mode, don't add this.
+ // From dev.local@gmail.com - 0x4e8/0x507c is the UMS mode, apparently
+ // do not add that device.
// From m.eik michalke
{ "Samsung", 0x04e8, "YP-U3", 0x507d, DEVICE_FLAG_NONE },
// Reported by Matthew Wilcox <matthew@wil.cx>
- { "Samsung", 0x04e8, "YP-T9", 0x507f, DEVICE_FLAG_NONE },
+ // Sergio <sfrdll@tiscali.it> reports this device need the BROKEN ALL flag.
+ { "Samsung", 0x04e8, "YP-T9", 0x507f, DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL },
// From Paul Clinch
{ "Samsung", 0x04e8, "YP-K3", 0x5081, DEVICE_FLAG_NONE },
// From XNJB user
{ "Samsung", 0x04e8, "YP-P2", 0x5083, DEVICE_FLAG_NO_ZERO_READS },
// From Paul Clinch
- { "Samsung", 0x04e8, "YP-T10", 0x508a, DEVICE_FLAG_NONE },
+ { "Samsung", 0x04e8, "YP-T10", 0x508a, DEVICE_FLAG_OGG_IS_UNKNOWN | DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST },
+ // From Wim Verwimp <wimverwimp@gmail.com>
+ // Not sure about the Ogg and broken proplist flags here. Just guessing.
+ { "Samsung", 0x04e8, "YP-S5", 0x508b, DEVICE_FLAG_OGG_IS_UNKNOWN | DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST },
// From a rouge .INF file,
- // this device ID seems to have been recycled for the Samsung SGH-A707 Cingular cellphone
- { "Samsung", 0x04e8, "YH-999 Portable Media Center / SGH-A707", 0x5a0f, DEVICE_FLAG_NONE },
+ // this device ID seems to have been recycled for:
+ // the Samsung SGH-A707 Cingular cellphone
+ // the Samsung L760-V cellphone
+ { "Samsung", 0x04e8, "YH-999 Portable Media Center/SGH-A707/SGH-L760V", 0x5a0f, DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL },
+ // From Santi Béjar <sbejar@gmail.com> - not sure this is MTP...
+ // { "Samsung", 0x04e8, "Z170 Mobile Phone", 0x6601, DEVICE_FLAG_UNLOAD_DRIVER },
+ // From Santi Béjar <sbejar@gmail.com> - not sure this is MTP...
+ // { "Samsung", 0x04e8, "E250 Mobile Phone", 0x663e, DEVICE_FLAG_UNLOAD_DRIVER },
// From Lionel Bouton
{ "Samsung", 0x04e8, "X830 Mobile Phone", 0x6702, DEVICE_FLAG_NONE },
// From James <jamestech@gmail.com>
@@ -124,6 +136,11 @@
* Intel
*/
{ "Intel", 0x045e, "Bandon Portable Media Center", 0x00c9, DEVICE_FLAG_NONE },
+ // Reported by Tadimarri Sarath <sarath.tadi@gmail.com>
+ // No idea why this use an Intel PID, perhaps a leftover from
+ // the early PMC development days when Intel and Microsoft were
+ // partnering.
+ { "Microsoft", 0x045e, "Windows MTP Simulator", 0x0622, DEVICE_FLAG_NONE },
/*
* JVC
@@ -140,7 +157,7 @@
// from discussion forum
{ "Philips", 0x0471, "HDD085/00 or HDD082/17", 0x014d, DEVICE_FLAG_NONE },
// from XNJB forum
- { "Philips", 0x0471, "GoGear SA9200", 0x014f, DEVICE_FLAG_NONE },
+ { "Philips", 0x0471, "GoGear SA9200", 0x014f, DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL },
// From John Coppens <jcoppens@users.sourceforge.net>
{ "Philips", 0x0471, "SA1115/55", 0x0164, DEVICE_FLAG_NONE },
// From Gerhard Mekenkamp
@@ -152,7 +169,13 @@
// From libgphoto2 source
{ "Philips", 0x0471, "HDD6320", 0x01eb, DEVICE_FLAG_NONE },
// From Detlef Meier <dm@emlix.com>
- { "Philips", 0x0471, "SA6014/SA6015/SA6024/SA6025/SA6044/SA6045", 0x084e, DEVICE_FLAG_UNLOAD_DRIVER },
+ { "Philips", 0x0471, "GoGear SA6014/SA6015/SA6024/SA6025/SA6044/SA6045", 0x084e, DEVICE_FLAG_UNLOAD_DRIVER },
+ // From anonymous Sourceforge user SA5145/02
+ { "Philips", 0x0471, "GoGear SA5145", 0x0857, DEVICE_FLAG_UNLOAD_DRIVER },
+ // From a
+ { "Philips", 0x0471, "GoGear SA6125/SA6145/SA6185", 0x2002, DEVICE_FLAG_UNLOAD_DRIVER },
+ // From anonymous Sourceforge user, not verified to be MTP!
+ { "Philips", 0x0471, "GoGear SA3345", 0x2004, DEVICE_FLAG_UNLOAD_DRIVER },
// from XNJB user
{ "Philips", 0x0471, "PSA235", 0x7e01, DEVICE_FLAG_NONE },
@@ -162,8 +185,17 @@
* several devices (c150 for sure) are definately dual-mode and must
* have the USB mass storage driver that hooks them unloaded first.
* They all have problematic dual-mode making the device unload effect
- * uncertain on these devices. All except for the Linux based ones seem
- * to need DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL.
+ * uncertain on these devices.
+ *
+ * All older devices seem to need DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL.
+ * Old chipsets: e200/c200 use PP5024 from Nvidia (formerly PortalPlayer).
+ * m200 use TCC770 from Telechips.
+ *
+ * The newer Sansa v2 chipset, AD3525 from Austriamicrosystems (AMS) found
+ * in e280 v2 c200 v2, Clip, Fuze etc require DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST
+ * and DEVICE_FLAG_ALWAYS_PROBE_DESCRIPTOR to work properly.
+ *
+ * For more info see: http://daniel.haxx.se/sansa/v2.html
*/
// Reported by Brian Robison
{ "SanDisk", 0x0781, "Sansa m230/m240", 0x7400,
@@ -184,12 +216,17 @@
DEVICE_FLAG_UNLOAD_DRIVER | DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL |
DEVICE_FLAG_NO_RELEASE_INTERFACE },
// Reported by XNJB user
+ { "SanDisk", 0x0781, "Sansa e280 v2", 0x7422,
+ DEVICE_FLAG_UNLOAD_DRIVER | DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST |
+ DEVICE_FLAG_NO_RELEASE_INTERFACE | DEVICE_FLAG_ALWAYS_PROBE_DESCRIPTOR },
+ // Reported by XNJB user
{ "SanDisk", 0x0781, "Sansa m240", 0x7430,
DEVICE_FLAG_UNLOAD_DRIVER | DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL |
DEVICE_FLAG_NO_RELEASE_INTERFACE },
// Reported by Eugene Brevdo <ebrevdo@princeton.edu>
- { "SanDisk", 0x0781, "Sansa Clip", 0x7432, DEVICE_FLAG_UNLOAD_DRIVER |
- DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST },
+ { "SanDisk", 0x0781, "Sansa Clip", 0x7432,
+ DEVICE_FLAG_UNLOAD_DRIVER | DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST |
+ DEVICE_FLAG_NO_RELEASE_INTERFACE | DEVICE_FLAG_ALWAYS_PROBE_DESCRIPTOR },
// Reported by anonymous user at sourceforge.net
{ "SanDisk", 0x0781, "Sansa c240/c250", 0x7450,
DEVICE_FLAG_UNLOAD_DRIVER | DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL |
@@ -205,7 +242,12 @@
// Reported by anonymous SourceForge user
{ "SanDisk", 0x0781, "Sansa View", 0x74b0,
DEVICE_FLAG_UNLOAD_DRIVER | DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL |
- DEVICE_FLAG_NO_RELEASE_INTERFACE },
+ DEVICE_FLAG_NO_RELEASE_INTERFACE },
+ // Reported by Patrick <skibler@gmail.com>
+ // There are apparently problems with this device.
+ { "SanDisk", 0x0781, "Sansa Fuze", 0x74c0,
+ DEVICE_FLAG_UNLOAD_DRIVER | DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST |
+ DEVICE_FLAG_NO_RELEASE_INTERFACE | DEVICE_FLAG_ALWAYS_PROBE_DESCRIPTOR },
/*
* iRiver
@@ -213,7 +255,6 @@
* broken on all iRiver devices, meaning it simply won't return
* all properties for a file when asking for metadata 0xffffffff.
* Please test on your device if you believe it isn't broken!
- * Some devices from http://www.mtp-ums.net/viewdeviceinfo.php
*/
{ "iRiver", 0x1006, "Portable Media Center", 0x4002,
DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST | DEVICE_FLAG_NO_ZERO_READS |
@@ -271,6 +312,10 @@
{ "iRiver", 0x4102, "T60", 0x1134,
DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST | DEVICE_FLAG_NO_ZERO_READS |
DEVICE_FLAG_IRIVER_OGG_ALZHEIMER },
+ // Reported by two anonymous SourceForge users
+ { "iRiver", 0x4102, "E100", 0x1141,
+ DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST | DEVICE_FLAG_NO_ZERO_READS |
+ DEVICE_FLAG_IRIVER_OGG_ALZHEIMER },
// Reported by Scott Call
{ "iRiver", 0x4102, "H10 20GB", 0x2101,
DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST | DEVICE_FLAG_NO_ZERO_READS |
@@ -300,6 +345,11 @@
{ "Toshiba", 0x0930, "Gigabeat V30", 0x0014, DEVICE_FLAG_NONE },
// Reported by Michael Davis <slithy@yahoo.com>
{ "Toshiba", 0x0930, "Gigabeat U", 0x0016, DEVICE_FLAG_NONE },
+ // Reported by Devon Jacobs <devo@godevo.com>
+ { "Toshiba", 0x0930, "Gigabeat MEU202", 0x0018, DEVICE_FLAG_NO_RELEASE_INTERFACE },
+ // Reported by Rolf <japan (at) dl3lar.de>
+ { "Toshiba", 0x0930, "Gigabeat T", 0x0019, DEVICE_FLAG_NONE },
+
/*
* Archos
@@ -313,10 +363,14 @@
{ "Archos", 0x0e79, "XS202 (MTP mode)", 0x1208, DEVICE_FLAG_NONE },
// Reported by gudul1@users.sourceforge.net
{ "Archos", 0x0e79, "104 (MTP mode)", 0x120a, DEVICE_FLAG_NONE },
+ // Reported by anonymous Sourceforge user.
+ { "Archos", 0x0e79, "404 (MTP mode)", 0x1301, DEVICE_FLAG_UNLOAD_DRIVER },
// Reported by Etienne Chauchot <chauchot.etienne@free.fr>
{ "Archos", 0x0e79, "504 (MTP mode)", 0x1307, DEVICE_FLAG_UNLOAD_DRIVER },
// Reported by Kay McCormick <kaym@modsystems.com>
{ "Archos", 0x0e79, "704 mobile dvr", 0x130d, DEVICE_FLAG_UNLOAD_DRIVER },
+ // Reported by Joe Rabinoff
+ { "Archos", 0x0e79, "605 (MTP mode)", 0x1313, DEVICE_FLAG_UNLOAD_DRIVER },
/*
* Dunlop (OEM of EGOMAN ltd?) reported by Nanomad
@@ -338,6 +392,10 @@
* Sirius
*/
{ "Sirius", 0x18f6, "Stiletto", 0x0102, DEVICE_FLAG_NONE },
+ // Reported by Chris Bagwell <chris@cnpbagwell.com>
+ // Apparently this comes with a firmware upgrade to the original
+ // Stiletto as well.
+ { "Sirius", 0x18f6, "Stiletto 2", 0x0110, DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST },
/*
* Canon
@@ -348,9 +406,22 @@
/*
* Nokia
+ * Please verify the low device IDs here, I suspect these might be for
+ * things like USB storage or modem mode actually, whereas the higher
+ * range (0x04nn) could be for MTP.
*/
// From: DoomHammer <gaczek@users.sourceforge.net>
+ { "Nokia", 0x0421, "N81 Mobile Phone", 0x000a, DEVICE_FLAG_NONE },
+ // From an anonymous SourceForge user
+ { "Nokia", 0x0421, "6120c Classic Mobile Phone", 0x002e, DEVICE_FLAG_NONE },
+ // From: DoomHammer <gaczek@users.sourceforge.net>
{ "Nokia", 0x0421, "3110c Mobile Phone", 0x005f, DEVICE_FLAG_NONE },
+ // From: Vasily <spc-@users.sourceforge.net>
+ { "Nokia", 0x0421, "3109c Mobile Phone", 0x0065, DEVICE_FLAG_NONE },
+ // From: robin (AT) headbank D0Tco DOTuk
+ { "Nokia", 0x0421, "N95 Mobile Phone 8GB", 0x006e, DEVICE_FLAG_NONE },
+ // From: Christian Rusa <kristous@users.sourceforge.net>
+ { "Nokia", 0x0421, "5700 XpressMusic Mobile Phone", 0x04b4, DEVICE_FLAG_NONE },
// From: Mitchell Hicks <mitchix@yahoo.com>
{ "Nokia", 0x0421, "5300 Mobile Phone", 0x04ba, DEVICE_FLAG_NONE },
// From Christian Arnold <webmaster@arctic-media.de>
@@ -374,10 +445,13 @@
*/
// From kiki <omkiki@users.sourceforge.net>
{ "Thomson", 0x069b, "EM28 Series", 0x0774, DEVICE_FLAG_NONE },
- { "Thomson / RCA", 0x069b, "Opal / Lyrca MC4002", 0x0777, DEVICE_FLAG_NONE },
+ { "Thomson / RCA", 0x069b, "Opal / Lyra MC4002", 0x0777, DEVICE_FLAG_NONE },
+ { "Thomson", 0x069b, "RCA H106", 0x301a, DEVICE_FLAG_UNLOAD_DRIVER },
// From Svenna <svenna@svenna.de>
// Not confirmed to be MTP.
{ "Thomson", 0x069b, "scenium E308", 0x3028, DEVICE_FLAG_NONE },
+ // From XNJB user
+ { "Thomson / RCA", 0x069b, "Lyra HC308A", 0x3035, DEVICE_FLAG_NONE },
/*
* NTT DoCoMo
@@ -406,10 +480,12 @@
DEVICE_FLAG_UNLOAD_DRIVER },
/*
- * Disney (have had no reports of this actually working.)
+ * Disney/Tevion (have had no reports of these actually working.)
*/
// Reported by XNJB user
{ "Disney", 0x0aa6, "MixMax", 0x6021, DEVICE_FLAG_NONE },
+ // Reported by anonymous Sourceforge user
+ { "Tevion", 0x0aa6, "MD 81488", 0x3011, DEVICE_FLAG_NONE },
/*
* Cowon Systems, Inc.
@@ -419,6 +495,8 @@
{ "Cowon", 0x0e21, "iAudio U3 (MTP mode)", 0x0701, DEVICE_FLAG_NONE },
// Reported by Roberth Karman
{ "Cowon", 0x0e21, "iAudio 7 (MTP mode)", 0x0751, DEVICE_FLAG_NONE },
+ // Reported by an anonymous SourceForge user
+ { "Cowon", 0x0e21, "iAudio U5 (MTP mode)", 0x0761, DEVICE_FLAG_NONE },
// Reported by TJ Something <tjbk_tjb@users.sourceforge.net>
{ "Cowon", 0x0e21, "iAudio D2 (MTP mode)", 0x0801,
DEVICE_FLAG_UNLOAD_DRIVER | DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL },
@@ -427,6 +505,8 @@
* Insignia, dual-mode.
*/
{ "Insignia", 0x19ff, "NS-DV45", 0x0303, DEVICE_FLAG_UNLOAD_DRIVER },
+ // Reported by Rajan Bella <rajanbella@yahoo.com>
+ { "Insignia", 0x19ff, "Sport Player", 0x0307, DEVICE_FLAG_UNLOAD_DRIVER },
// Reported by "brad" (anonymous, sourceforge)
{ "Insignia", 0x19ff, "Pilot 4GB", 0x0309, DEVICE_FLAG_UNLOAD_DRIVER },
@@ -438,10 +518,22 @@
/*
* Sony
- */
+ * It could be that these PIDs are one-per hundred series, so
+ * NWZ-A8xx is 0325, NWZ-S5xx is 0x326 etc. We need more devices
+ * reported to see a pattern here.
+ */
+ // Reported by Alessandro Radaelli <alessandro.radaelli@aruba.it>
+ { "Sony", 0x054c, "Walkman NWZ-A815/NWZ-A818", 0x0325, DEVICE_FLAG_UNLOAD_DRIVER },
+ // Reported by anonymous Sourceforge user.
+ { "Sony", 0x054c, "Walkman NWZ-S516", 0x0326, DEVICE_FLAG_UNLOAD_DRIVER },
// Reported by Endre Oma <endre.88.oma@gmail.com>
- // (possibly this is for the A-series too)
- { "Sony", 0x054c, "Walkman S-series", 0x0327, DEVICE_FLAG_UNLOAD_DRIVER },
+ { "Sony", 0x054c, "Walkman NWZ-S615F/NWZ-S616F/NWZ-S618F", 0x0327, DEVICE_FLAG_UNLOAD_DRIVER },
+ // Reported by Jean-Marc Bourguet <jm@bourguet.org>
+ { "Sony", 0x054c, "Walkman NWZ-S716F", 0x035a, DEVICE_FLAG_UNLOAD_DRIVER },
+ // Reported by Anon SF User / Anthon van der Neut <avanderneut@avid.com>
+ { "Sony", 0x054c, "Walkman NWZ-A828/NWZ-A829", 0x035b, DEVICE_FLAG_UNLOAD_DRIVER },
+ // Reported by Niek Klaverstijn <niekez@users.sourceforge.net>
+ { "Sony", 0x054c, "Walkman NWZ-A728B", 0x035c, DEVICE_FLAG_UNLOAD_DRIVER },
/*
* SonyEricsson
@@ -450,17 +542,51 @@
{ "SonyEricsson", 0x0fce, "K850i", 0x0075, DEVICE_FLAG_NONE },
// Reported by Michael Eriksson
{ "SonyEricsson", 0x0fce, "W910", 0x0076, DEVICE_FLAG_NONE },
+ // Reported by Zack <zackdvd@users.sourceforge.net>
+ { "SonyEricsson", 0x0fce, "W890i", 0x00b3, DEVICE_FLAG_NONE },
+ // Reported by Linus Åkesson <linusakesson@users.sourceforge.net>
+ { "SonyEricsson", 0x0fce, "C902", 0x00d4, DEVICE_FLAG_NONE },
/*
* Motorola
* Assume DEVICE_FLAG_BROKEN_SET_OBJECT_PROPLIST on all of these.
*/
+ // Reported by David Boyd <tiggrdave@users.sourceforge.net>
+ { "Motorola", 0x22b8, "V3m verizon", 0x2a65, DEVICE_FLAG_BROKEN_SET_OBJECT_PROPLIST |
+ DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL },
// Reported by Marcus Meissner to libptp2
{ "Motorola", 0x22b8, "K1", 0x4811, DEVICE_FLAG_BROKEN_SET_OBJECT_PROPLIST },
// Reported by Hans-Joachim Baader <hjb@pro-linux.de> to libptp2
{ "Motorola", 0x22b8, "A1200", 0x60ca, DEVICE_FLAG_BROKEN_SET_OBJECT_PROPLIST },
// Reported by anonymous user
- { "Motorola", 0x22b8, "RAZR2 V8", 0x6415, DEVICE_FLAG_BROKEN_SET_OBJECT_PROPLIST },
+ { "Motorola", 0x22b8, "RAZR2 V8/U9", 0x6415, DEVICE_FLAG_BROKEN_SET_OBJECT_PROPLIST },
+
+
+ /*
+ * Media Keg
+ */
+ // Reported by Rajan Bella <rajanbella@yahoo.com>
+ { "Kenwood", 0x0b28, "Media Keg HD10GB7 Sport Player", 0x100c, DEVICE_FLAG_UNLOAD_DRIVER},
+
+ /*
+ * Micro-Star International (MSI)
+ */
+ // Reported by anonymous sourceforge user.
+ { "Micro-Star International", 0x0db0, "P610/Model MS-5557", 0x5572, DEVICE_FLAG_NONE },
+
+ /*
+ * FOMA
+ */
+ { "FOMA", 0x06d3, "D905i", 0x21ba, DEVICE_FLAG_NONE },
+
+ /*
+ * Haier
+ */
+ // Both reported by an anonymous SourceForge user
+ // This is the 30 GiB model
+ { "Haier", 0x1302, "Ibiza Rhapsody", 0x1016, DEVICE_FLAG_NONE },
+ // This is the 4/8 GiB model
+ { "Haier", 0x1302, "Ibiza Rhapsody", 0x1017, DEVICE_FLAG_NONE },
/*
* Other strange stuff.
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/src/ptp-pack.c
^
|
@@ -1121,7 +1121,7 @@
break;
entries++;
}
- *ce = malloc (sizeof(PTPCanon_changes_entry)*entries);
+ *ce = malloc (sizeof(PTPCanon_changes_entry)*(entries+1));
if (!*ce) return 0;
curdata = data;
@@ -1271,6 +1271,8 @@
}
curdata += size;
i++;
+ if ((size == 8) && (type == 0))
+ break;
}
return entries;
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/src/ptp.c
^
|
@@ -1819,6 +1819,8 @@
unsigned int size = 0;
unsigned char *data = NULL;
+ *nrofentries = 0;
+ *entries = NULL;
PTP_CNT_INIT(ptp);
ptp.Code = PTP_OC_CANON_EOS_GetEvent;
ptp.Nparam = 0;
@@ -1854,18 +1856,19 @@
uint16_t
-ptp_canon_eos_getstorageids (PTPParams* params)
+ptp_canon_eos_getstorageids (PTPParams* params, PTPStorageIDs* storageids)
{
- PTPContainer ptp;
- unsigned char *data = NULL;
- unsigned int size = 0;
+ PTPContainer ptp;
+ unsigned int len = 0;
uint16_t ret;
+ unsigned char* sids=NULL;
PTP_CNT_INIT(ptp);
ptp.Code = PTP_OC_CANON_EOS_GetStorageIDs;
ptp.Nparam = 0;
- ret = ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size);
- /* FIXME: do stuff with data */
+ ret = ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &sids, &len);
+ if (ret == PTP_RC_OK) ptp_unpack_SIDs(params, sids, storageids, len);
+ free(sids);
return ret;
}
@@ -2804,13 +2807,23 @@
PTPContainer ptp;
uint16_t ret;
unsigned char* dpv=NULL;
+ unsigned int dpvlen = 0;
PTP_CNT_INIT(ptp);
ptp.Code=PTP_OC_MTP_GetObjectReferences;
ptp.Param1=handle;
ptp.Nparam=1;
- ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &dpv, NULL);
- if (ret == PTP_RC_OK) *arraylen = ptp_unpack_uint32_t_array(params, dpv, 0, ohArray);
+ ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &dpv, &dpvlen);
+ if (ret == PTP_RC_OK) {
+ /* Sandisk Sansa skips the DATA phase, but returns OK as response.
+ * this will gives us a NULL here. Handle it. -Marcus */
+ if ((dpv == NULL) || (dpvlen == 0)) {
+ *arraylen = 0;
+ *ohArray = NULL;
+ } else {
+ *arraylen = ptp_unpack_uint32_t_array(params, dpv, 0, ohArray);
+ }
+ }
free(dpv);
return ret;
}
@@ -3858,6 +3871,8 @@
{PTP_OFC_MTP_vCalendar1,N_("vCalendar1")},
{PTP_OFC_MTP_vCalendar2,N_("vCalendar2")},
{PTP_OFC_MTP_UndefinedWindowsExecutable,N_("Undefined Windows Executable")},
+ {PTP_OFC_MTP_MediaCast,N_("Media Cast")},
+ {PTP_OFC_MTP_Section,N_("Section")},
};
int
|
[-]
[+]
|
Changed |
libmtp-0.3.0.tar.gz/src/ptp.h
^
|
@@ -62,7 +62,7 @@
* and fixed the bugs that made this necessary and it can be 512 again.
*/
#define PTP_USB_BULK_HS_MAX_PACKET_LEN_WRITE 512
-#define PTP_USB_BULK_HS_MAX_PACKET_LEN_READ 512
+#define PTP_USB_BULK_HS_MAX_PACKET_LEN_READ 512
#define PTP_USB_BULK_HDR_LEN (2*sizeof(uint32_t)+2*sizeof(uint16_t))
#define PTP_USB_BULK_PAYLOAD_LEN_WRITE (PTP_USB_BULK_HS_MAX_PACKET_LEN_WRITE-PTP_USB_BULK_HDR_LEN)
#define PTP_USB_BULK_PAYLOAD_LEN_READ (PTP_USB_BULK_HS_MAX_PACKET_LEN_READ-PTP_USB_BULK_HDR_LEN)
@@ -714,7 +714,8 @@
#define PTP_OFC_MTP_vCalendar1 0xbe02
#define PTP_OFC_MTP_vCalendar2 0xbe03
#define PTP_OFC_MTP_UndefinedWindowsExecutable 0xbe80
-
+#define PTP_OFC_MTP_MediaCast 0xbe81
+#define PTP_OFC_MTP_Section 0xbe82
/* PTP Association Types */
#define PTP_AT_Undefined 0x0000
@@ -1064,7 +1065,9 @@
#define PTP_DPC_CANON_FocalLengthTele 0xD026
#define PTP_DPC_CANON_FocalLengthWide 0xD027
#define PTP_DPC_CANON_FocalLengthDenominator 0xD028
-#define PTP_DPC_CANON_CaptureTransferMode 0xD029
+#define PTP_DPC_CANON_CaptureTransferMode 0xD029
+#define CANON_TRANSFER_MEMORY 3
+#define CANON_TRANSFER_CARD 15
#define PTP_DPC_CANON_Zoom 0xD02A
#define PTP_DPC_CANON_NamePrefix 0xD02B
#define PTP_DPC_CANON_SizeQualityMode 0xD02C
@@ -1704,7 +1707,7 @@
unsigned char **data, unsigned int *size);
uint16_t ptp_canon_getpairinginfo (PTPParams* params, uint32_t nr, unsigned char**, unsigned int*);
-uint16_t ptp_canon_eos_getstorageids (PTPParams* params);
+uint16_t ptp_canon_eos_getstorageids (PTPParams* params, PTPStorageIDs* storageids);
uint16_t ptp_canon_eos_getstorageinfo (PTPParams* params, uint32_t p1);
uint16_t ptp_canon_eos_getpartialobject (PTPParams* params, uint32_t oid, uint32_t off, uint32_t xsize, unsigned char**data);
uint16_t ptp_canon_eos_setdevicepropvalueex (PTPParams* params, unsigned char* data, unsigned int size);
|