Blame README

Packit b0f24f
Building and Installing
Packit b0f24f
-----------------------
Packit b0f24f
Packit b0f24f
See the "INSTALL" file.
Packit b0f24f
Packit b0f24f
Packit b0f24f
Initiator and Responder
Packit b0f24f
-----------------------
Packit b0f24f
Packit b0f24f
libmtp implements an MTP initiator, which means it initiate
Packit b0f24f
MTP sessions with devices. The devices responding are known
Packit b0f24f
as MTP responders. libmtp runs on something with a USB host
Packit b0f24f
controller interface, using libusb to access the host
Packit b0f24f
controller.
Packit b0f24f
Packit b0f24f
If you're more interested in the MTP responders, gadgets like
Packit b0f24f
MP3 players, mobile phones etc, look into:
Packit b0f24f
- MeeGo:s Buteo Sync:
Packit b0f24f
  https://github.com/nemomobile/buteo-mtp
Packit b0f24f
  https://wiki.merproject.org/wiki/Buteo/MTP
Packit b0f24f
- Android has an MTP responder implementation:
Packit b0f24f
  https://android.googlesource.com/platform/frameworks/base/+/master/media/jni/
Packit b0f24f
- Ubuntu/Ricardo Salveti has mtp-server and libmtp-server going:
Packit b0f24f
  https://code.launchpad.net/~phablet-team/mtp/trunk
Packit b0f24f
  http://bazaar.launchpad.net/~phablet-team/mtp/trunk/files
Packit b0f24f
Packit b0f24f
Heritage
Packit b0f24f
--------
Packit b0f24f
Packit b0f24f
libmtp is based on several ancestors:
Packit b0f24f
Packit b0f24f
* libptp2 by Mariusz Woloszyn was the starting point used
Packit b0f24f
  by Richard A. Low for the initial starter port. You can
Packit b0f24f
  find it at http://libptp.sourceforge.net/
Packit b0f24f
Packit b0f24f
* libgphoto2 by Mariusz Woloszyn and Marcus Meissner was
Packit b0f24f
  used at a later stage since it was (is) more actively
Packit b0f24f
  maintained. libmtp tracks the PTP implementation in
Packit b0f24f
  libgphoto2 and considers it an upstream project. We will
Packit b0f24f
  try to submit anything generally useful back to libgphoto2
Packit b0f24f
  and not make double efforts. In practice this means we
Packit b0f24f
  use ptp.c, ptp.h and ptp-pack.c verbatim from the libgphoto2
Packit b0f24f
  source code. If you need to change things in these files,
Packit b0f24f
  make sure it is so general that libgphoto2 will want to
Packit b0f24f
  merge it to their codebase too. You find libgphoto2 as part
Packit b0f24f
  of gPhoto: http://gphoto.sourceforge.net/
Packit b0f24f
Packit b0f24f
* libnjb was a project that Richard and Linus were working
Packit b0f24f
  on before libmtp. When Linus took Richards initial port
Packit b0f24f
  and made an generic C API he re-used the philosophy and
Packit b0f24f
  much code from libnjb. Many of the sample programs are for
Packit b0f24f
  example taken quite literally from libnjb. You find it here:
Packit b0f24f
  http://libnjb.sourceforge.net/
Packit b0f24f
Packit b0f24f
Packit b0f24f
Contacting and Contributing
Packit b0f24f
---------------------------
Packit b0f24f
Packit b0f24f
See the project page at http://libmtp.sourceforge.net/
Packit b0f24f
We always need your help. There is a mailinglist and a
Packit b0f24f
bug report system there.
Packit b0f24f
Packit b0f24f
People who want to discuss MTP devices in fora seem to
Packit b0f24f
hang out on the forums at AnythingbutiPod:
Packit b0f24f
http://www.anythingbutipod.com/forum/
Packit b0f24f
Packit b0f24f
Packit b0f24f
Compiling programs for libmtp
Packit b0f24f
-----------------------------
Packit b0f24f
Packit b0f24f
libmtp has support for the pkg-config script by adding a libmtp.pc
Packit b0f24f
entry in $(prefix)/lib/pkgconfig. To compile a libmtp program,
Packit b0f24f
"just" write:
Packit b0f24f
Packit b0f24f
gcc -o foo `pkg-config --cflags --libs libmtp` foo.c
Packit b0f24f
Packit b0f24f
This also simplifies compilation using autoconf and pkg-config: just
Packit b0f24f
write e.g.
Packit b0f24f
Packit b0f24f
PKG_CHECK_MODULES(MTP, libmtp)
Packit b0f24f
AC_SUBST(MTP_CFLAGS)
Packit b0f24f
AC_SUBST(MTP_LIBS)
Packit b0f24f
Packit b0f24f
To have libmtp LIBS and CFLAGS defined. Needless to say, this will
Packit b0f24f
only work if you have pkgconfig installed on your system, but most
Packit b0f24f
people have nowadays.
Packit b0f24f
Packit b0f24f
If your library is installed in e.g. /usr/local you may have to tell
Packit b0f24f
this to pkgconfig by setting the PKG_CONFIG_PATH thus:
Packit b0f24f
Packit b0f24f
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
Packit b0f24f
Packit b0f24f
Packit b0f24f
Documentation
Packit b0f24f
-------------
Packit b0f24f
Packit b0f24f
Read the API documentation that can be generated with doxygen.
Packit b0f24f
It will be output in doc/html if you have Doxygen properly
Packit b0f24f
installed. (It will not be created unless you have Doxygen!)
Packit b0f24f
Packit b0f24f
For information about the Media Transfer Protocol, see:
Packit b0f24f
http://en.wikipedia.org/wiki/Media_Transfer_Protocol
Packit b0f24f
Packit b0f24f
The official 1.0 specification for MTP was released by the
Packit b0f24f
USB Implementers Forum in may, 2008. Prior to this, only a
Packit b0f24f
proprietary Microsoft version was available, and quite a few
Packit b0f24f
devices out there still use some aspects of the Microsoft
Packit b0f24f
version, which deviates from the specified standard. You can
Packit b0f24f
find the official specification here:
Packit b0f24f
http://www.usb.org/developers/devclass_docs/MTP_1.0.zip
Packit b0f24f
Packit b0f24f
Packit b0f24f
The Examples
Packit b0f24f
------------
Packit b0f24f
Packit b0f24f
In the subdirectory "examples" you find a number of
Packit b0f24f
command-line tools, illustrating the use of libmtp in very
Packit b0f24f
simple terms.
Packit b0f24f
Packit b0f24f
Please do not complain about the usability or documentation
Packit b0f24f
of these examples, they look like they do for two reasons:
Packit b0f24f
Packit b0f24f
1. They are examples, not tools. If they were intended for
Packit b0f24f
   day-to-day usage by commandline freaks, I would have
Packit b0f24f
   called them "tools" not "examples".
Packit b0f24f
Packit b0f24f
2. The MTP usage paradigm is that a daemon should hook
Packit b0f24f
   the device upon connection, and that it should be
Packit b0f24f
   released by unplugging. GUI tools utilizing HAL (hald)
Packit b0f24f
   and D-Bus do this much better than any commandline
Packit b0f24f
   program ever can. (See below on bugs.) Specificationwise
Packit b0f24f
   this is a bug, however it is present in many, many
Packit b0f24f
   devices.
Packit b0f24f
Packit b0f24f
That said, if you want to pick up and maintain the examples,
Packit b0f24f
please volunteer.
Packit b0f24f
Packit b0f24f
Packit b0f24f
FAQ: Common Problems
Packit b0f24f
--------------------
Packit b0f24f
Packit b0f24f
Some MTP devices have strange pecularities. We try to work around
Packit b0f24f
these whenever we can, sometimes we cannot work around it or we
Packit b0f24f
cannot test your solution.
Packit b0f24f
Packit b0f24f
* Android locked screen: some devices just report zero files
Packit b0f24f
  and no storages when the device screen is locked, it looks like
Packit b0f24f
  so:
Packit b0f24f
Packit b0f24f
  mtp-detect
Packit b0f24f
  Device 0 (VID=04e8 and PID=6860) is a Samsung Galaxy models (MTP).
Packit b0f24f
  Attempting to connect device(s)
Packit b0f24f
  Error 1: Get Storage information failed.
Packit b0f24f
  Device: SHV-E210K
Packit b0f24f
  LIBMTP_Get_Storage(): No data available
Packit b0f24f
  OK.
Packit b0f24f
Packit b0f24f
  This is probably so as not to allow the MTP access to be used
Packit b0f24f
  as a "backdoor" into the device. Unlock the device before listing
Packit b0f24f
  files, set the autolock to some large value or disabled if it
Packit b0f24f
  disturbs you, you are causing this to yourself, or should we say
Packit b0f24f
  that your vendor is prioritizing security and privacy over
Packit b0f24f
  ease-of-use. (You may talk to your vendor about this.)
Packit b0f24f
Packit b0f24f
* mtp-* tools doesn't work because someone else is already hogging
Packit b0f24f
  the device
Packit b0f24f
Packit b0f24f
  This is a common problem, the most common case could be that
Packit b0f24f
  gphoto2 (which can also talk PTP/MTP) is taking over the device
Packit b0f24f
  as soon as it's plugged in. Some distributions are configured that
Packit b0f24f
  way. Counter it like this:
Packit b0f24f
Packit b0f24f
  gvfs-mount -s gphoto2
Packit b0f24f
Packit b0f24f
  Then re-attach the device.
Packit b0f24f
Packit b0f24f
  Sometimes some gvfs daemons are running on the
Packit b0f24f
  system and hogging the device, try stopping them
Packit b0f24f
  with something like these commands:
Packit b0f24f
Packit b0f24f
  killall gvfs-mtp-volume-monitor
Packit b0f24f
  killall gvfs-gphoto2-volume-monitor
Packit b0f24f
Packit b0f24f
  Then plug in the device and issue "mtp-detect" to figure out if
Packit b0f24f
  this may be the case.
Packit b0f24f
Packit b0f24f
* Generic MTP/PTP disconnect misbehaviour: we have noticed that
Packit b0f24f
  Windows Media Player apparently never close the session to an MTP
Packit b0f24f
  device. There is a daemon in Windows that "hooks" the device
Packit b0f24f
  by opening a PTP session to any MTP device, whenever it is
Packit b0f24f
  plugged in. This daemon proxies any subsequent transactions
Packit b0f24f
  to/from the device and will never close the session, thus
Packit b0f24f
  Windows simply does not close sessions at all.
Packit b0f24f
Packit b0f24f
  For example this means that a device may work the first time
Packit b0f24f
  you run some command-line example like "mtp-detect" while
Packit b0f24f
  subsequent runs fail.
Packit b0f24f
Packit b0f24f
  Typical sign of this illness: broken pipes on closing sessions,
Packit b0f24f
  on the main transfer pipes(s) or the interrupt pipe:
Packit b0f24f
Packit b0f24f
    Closing session
Packit b0f24f
    usb_clear_halt() on INTERRUPT endpoint: Broken pipe
Packit b0f24f
    OK.
Packit b0f24f
Packit b0f24f
  This means that device manufacturers doesn't notice any problems
Packit b0f24f
  with devices that do not correctly handle closing PTP/MTP
Packit b0f24f
  sessions, since Windows never do it. The proper way of closing
Packit b0f24f
  a session in Windows is to unplug the device, simply put.
Packit b0f24f
Packit b0f24f
  Since libmtp actually tries to close sessions, some devices
Packit b0f24f
  may fail since the close session functionality has never been
Packit b0f24f
  properly tested, and "it works with Windows" is sort of the
Packit b0f24f
  testing criteria at some companies.
Packit b0f24f
Packit b0f24f
  You can get Windows-like behaviour on Linux by running a udev-aware
Packit b0f24f
  libmtp GUI client like Rhythmbox or Gnomad2, which will "hook"
Packit b0f24f
  the device when you plug it in, and "release" it if you unplug
Packit b0f24f
  it, and you start/end you transfer sessions by plugging/unplugging
Packit b0f24f
  the USB cable.
Packit b0f24f
Packit b0f24f
  The "Unix way" of running small programs that open the device,
Packit b0f24f
  do something, then close the device, isn't really working with
Packit b0f24f
  such devices and you cannot expect to have command line tools
Packit b0f24f
  like the mtp examples work with them. You could implement new
Packit b0f24f
  example programs that just call to a mediating daemon like the
Packit b0f24f
  Windows MTP stack does. (And change all programs using libmtp
Packit b0f24f
  directly today.)
Packit b0f24f
Packit b0f24f
  If this bug in your device annoys you, contact your device
Packit b0f24f
  manufacturer and ask them to test their product with some libmtp
Packit b0f24f
  program.
Packit b0f24f
Packit b0f24f
* Samsung Android 2.3.x devices: these have a special MTP stack
Packit b0f24f
  with some specific bugs that we have maybe nailed down now.
Packit b0f24f
  It suffers from an "immediate connect" syndrome, i.e. you have
Packit b0f24f
  to connect to the device within 7 seconds of plugging in, or it
Packit b0f24f
  will go numb. This also goes for command-line activity with
Packit b0f24f
  the example programs, so this device is better used with a
Packit b0f24f
  GUI tool like Rhythmbox, gnomad2...
Packit b0f24f
Packit b0f24f
* Generic USB misbehaviour: some devices behave badly under MTP
Packit b0f24f
  and USB mass storage alike, even down to the lowest layers
Packit b0f24f
  of USB. You can always discuss such issues at the linux-usb
Packit b0f24f
  mailing list if you're using Linux:
Packit b0f24f
  http://www.linux-usb.org/mailing.html
Packit b0f24f
Packit b0f24f
  If you have a problem specific to USB mass storage mode, there
Packit b0f24f
  is a list of strange behaving devices in the Linux kernel:
Packit b0f24f
  http://lxr.linux.no/linux/drivers/usb/storage/unusual_devs.h
Packit b0f24f
  You can discuss this too on the mentioned list, for understanding
Packit b0f24f
  the quirks, see:
Packit b0f24f
  http://www2.one-eyed-alien.net/~mdharm/linux-usb/target_offenses.txt
Packit b0f24f
Packit b0f24f
* Generic certificate misbehaviour. All devices are actually
Packit b0f24f
  required to support a device certificate to be able to
Packit b0f24f
  encrypt Windows Media (WMA/WMV) files. However there are
Packit b0f24f
  obviously a lot of devices out there which doesn't support
Packit b0f24f
  this at all but instead crash. Typical printout:
Packit b0f24f
Packit b0f24f
  Error 2: PTP Layer error 02ff: get_device_unicode_property(): failed
Packit b0f24f
  to get unicode property.
Packit b0f24f
Packit b0f24f
  This should only affect "mtp-detect", there is no other
Packit b0f24f
  application currently retrieveing the certificate (not that we
Packit b0f24f
  know anyway).
Packit b0f24f
Packit b0f24f
* Kernel bug on Linux. Linux 2.6.16 is generally speaking required
Packit b0f24f
  to use any MTP device under USB 2.0. This is because the EHCI
Packit b0f24f
  driver previously did not support zero-length writes to endpoints.
Packit b0f24f
  It should work in most cases however, or if you connect it
Packit b0f24f
  to an UHCI/OHCI port instead (yielding lower speed). But
Packit b0f24f
  please just use a recent kernel.
Packit b0f24f
Packit b0f24f
* Zen models AVI file seeking problem: the Zens cannot parse the
Packit b0f24f
  files for the runlength metadata. Do not transfer file with e.g.
Packit b0f24f
  mtp-sendfile, use mtp-sendtr and set the length of the track to
Packit b0f24f
  the apropriate number of seconds and it will work. In graphical
Packit b0f24f
  clients, use a "track transfer" function to send these AVI files,
Packit b0f24f
  the Zens need the metadata associated with tracks to play back
Packit b0f24f
  movies properly. Movies are considered "tracks" in the MTP world.
Packit b0f24f
Packit b0f24f
* Some devices that disregard the metadata sent with the MTP
Packit b0f24f
  commands will parse the files for e.g. ID3 metadata. Some still
Packit b0f24f
  of these devices expect only ID3v2.3 metadata and will fail with
Packit b0f24f
  a modern ID3v2,4 tag writer, like many of those found in Linux
Packit b0f24f
  applications. Windows Media Player use ID3v2.3 only, so many
Packit b0f24f
  manufacturers only test this version.
Packit b0f24f
Packit b0f24f
* The Zen Vision:M (possibly more Creative Zens) has a firmware bug
Packit b0f24f
  that makes it drop the last two characters off a playlist name.
Packit b0f24f
  It is fixed in later firmware.
Packit b0f24f
Packit b0f24f
* For Creative Technology devices, there are hard limits on how
Packit b0f24f
  many files can be put onto the device. For a 30 GiB device (like
Packit b0f24f
  the Zen Xtra) the limit is 6000, for a 60 GiB device the limit
Packit b0f24f
  is 15000 files. For further Creative pecularities, see the
Packit b0f24f
  FAQ sections at www.nomadness.net.
Packit b0f24f
Packit b0f24f
* Sandisk sansa c150 and probably several other Sandisk devices
Packit b0f24f
  (and possibly devices from other manufacturers) have a dual
Packit b0f24f
  mode with MTP and USB mass storage. The device will initially
Packit b0f24f
  claim to be mass storage so udev will capture is and make the
Packit b0f24f
  use of MTP mode impossible. One way of avoiding it could be to
Packit b0f24f
  be to blacklist the "usb-storage" module in
Packit b0f24f
  /etc/modprobe.c/blacklist with a row like this:
Packit b0f24f
  "blacklist usb-storage". Some have even removed the
Packit b0f24f
  "usb-storage.ko" (kernel module file) to avoid loading.
Packit b0f24f
Packit b0f24f
* Sandisk Sansa Fuze has three modes: auto, MTP or mass storage
Packit b0f24f
  (MSC). Please set it to MTP to avoid problems with libmtp.
Packit b0f24f
Packit b0f24f
* The iriver devices (possibly all of them) cannot handle the
Packit b0f24f
  enhanced GetObjectPropList MTP command (0x9805) properly. So
Packit b0f24f
  they have been banned from using it.
Packit b0f24f
Packit b0f24f
* iriver devices have problems with older versions of libmtp and
Packit b0f24f
  with new devices libmtp does not know of as of yet, since it
Packit b0f24f
  has an oldstyle USB device controller that cannot handle zero
Packit b0f24f
  writes. (Register your device with us!) All their devices are
Packit b0f24f
  likely to need a special device flag in the src/libusb-glue.c
Packit b0f24f
  database.
Packit b0f24f
Packit b0f24f
* The Samsung Yepp T9 has several strange characteristics, some
Packit b0f24f
  that we've managed to work around. (For example it will return
Packit b0f24f
  multiple PTP packages in a single transaction.)
Packit b0f24f
Packit b0f24f
* The early firmware for Philips HDD players is known to be
Packit b0f24f
  problematic. Please upgrade to as new firmware as you can get.
Packit b0f24f
  (Yes this requires some kind of Windows Installation I think.)
Packit b0f24f
Packit b0f24f
* Philips HDD 1630/16 or 1630/17 etc may lock themselves up,
Packit b0f24f
  turning inresponsive due to internal corruption. This typically
Packit b0f24f
  gives an error in opening the PTP session. Apparently you can
Packit b0f24f
  do a "repair" with the firmware utility (Windows only) which
Packit b0f24f
  will often fix this problem and make the device responsive
Packit b0f24f
  again.
Packit b0f24f
Packit b0f24f
* Some devices that implement GetObjectPropList (0x9805) will
Packit b0f24f
  not return the entire object list if you request a list for object
Packit b0f24f
  0xffffffffu. (But they should.) So they may need the special
Packit b0f24f
  DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL.
Packit b0f24f
Packit b0f24f
* Some (smaller) subset of devices cannot even get all the
Packit b0f24f
  properties for a single object in one go, these need the
Packit b0f24f
  DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST. Currently only the
Packit b0f24f
  iriver devices seem to have this bug.
Packit b0f24f
Packit b0f24f
* The Toshiba Gigabeat S (and probably its sibling the
Packit b0f24f
  Microsoft Zune and other Toshiba devices) will only display
Packit b0f24f
  album information tags for a song in case there is also
Packit b0f24f
  an abstract album (created with the album interface) with
Packit b0f24f
  the exact same name.
Packit b0f24f
Packit b0f24f
* The Zen Vision:M has an older firmware which is very corrupt,
Packit b0f24f
  it is incompatible with the Linux USB stack altogether. The
Packit b0f24f
  kernel dmesg will look something like this, and you have to
Packit b0f24f
  upgrade the firmware using Windows:
Packit b0f24f
  usb 4-5: new high speed USB device using ehci_hcd and address 5
Packit b0f24f
  usb 4-5: configuration #1 chosen from 1 choice
Packit b0f24f
  usb 4-5: can't set config #1, error -110
Packit b0f24f
Packit b0f24f
* The Sirus Stiletto does not seem to allow you to copy any files
Packit b0f24f
  off the device. This may be someone's idea of copy protection.
Packit b0f24f
Packit b0f24f
* The Samsung P2 assigns parent folder ID 0 to all unknown file
Packit b0f24f
  types.(i.e. moves them to the root folder)
Packit b0f24f
Packit b0f24f
* The Sandisk Sansa Clip+ needs a firmware upgrade in earlier
Packit b0f24f
  versions in order to work properly.
Packit b0f24f
Packit b0f24f
Packit b0f24f
New Devices
Packit b0f24f
-----------
Packit b0f24f
Packit b0f24f
If you happen upon a device which libmtp claims it cannot
Packit b0f24f
autodetect, please submit the vendor ID and device ID
Packit b0f24f
(these can be obtained from the "lsusb" and "lsusb -n"
Packit b0f24f
commands run as root) as a bug, patch or feature request
Packit b0f24f
on the Sourceforge bug tracker at our homepage. If it
Packit b0f24f
gives a sensible  output from "mtp-detect" then please attach
Packit b0f24f
the result as well as it teach us some stuff about your
Packit b0f24f
device. If you've done some additional hacking, join our
Packit b0f24f
mailinglist and post your experiences there.
Packit b0f24f
Packit b0f24f
If you want to be able to hack some more and you're not
Packit b0f24f
afraid of C hacking, add an entry for your device's
Packit b0f24f
vendor/product ID and a descriptive string to the database
Packit b0f24f
in the file src/music-players.h.
Packit b0f24f
Packit b0f24f
If you want to poke around to see if your device has some
Packit b0f24f
special pecularities, you can test some special device
Packit b0f24f
flags (defined in src/device-flags.h) by inserting them
Packit b0f24f
together with your device entry in src/music-players.h.
Packit b0f24f
Flags can be tested in isolation or catenated with "|"
Packit b0f24f
(binary OR). If relatives to your device use a certain
Packit b0f24f
flag, chances are high that a new device will need it
Packit b0f24f
too, typically from the same manufacturer.
Packit b0f24f
Packit b0f24f
The most common flag that needs to be set is the
Packit b0f24f
DEVICE_FLAG_UNLOAD_DRIVER that detach any Linux kernel
Packit b0f24f
drivers that may have attached to the device making
Packit b0f24f
MTP access impossible. This is however not expected to
Packit b0f24f
really work: this is a problem being tracked as of
Packit b0f24f
now (2007-08-04). See the "last resort" solutions below
Packit b0f24f
if you really need to get your dual-mode device to work
Packit b0f24f
with MTP.
Packit b0f24f
Packit b0f24f
Another flag which is easy to identify is the
Packit b0f24f
DEVICE_FLAG_NO_ZERO_READS, which remedies connection
Packit b0f24f
timeouts when getting files, and some timeouts on e.g.
Packit b0f24f
successive "mtp-connect" calls.
Packit b0f24f
Packit b0f24f
If your device is very problematic we are curious of how it
Packit b0f24f
works under Windows, so we enjoy reading USB packet sniffs
Packit b0f24f
that reveal the low-level traffic carried out between
Packit b0f24f
Windows Media Player and your device. This can be done
Packit b0f24f
using e.g.:
Packit b0f24f
Packit b0f24f
* USBsnoop:
Packit b0f24f
  http://benoit.papillault.free.fr/usbsnoop/
Packit b0f24f
Packit b0f24f
* The trial version of HHD Softwares software-only
Packit b0f24f
  USB monitor. You need to get a copy of version 2.37 since
Packit b0f24f
  the newer trial versions won't let you carry out the
Packit b0f24f
  needed packet sniffs. (As of 2007-03-10 a copy can be found
Packit b0f24f
  at: http://www.cobbleware.com/files/usb-monitor-237.exe)
Packit b0f24f
Packit b0f24f
There are other USB monitors as well, some more expensive
Packit b0f24f
alternatives use hardware and even measure electronic
Packit b0f24f
characteristics of the traffic (which is far too much
Packit b0f24f
detail for us).
Packit b0f24f
Packit b0f24f
Device sniffs are an easy read since the PTP/MTP protocol
Packit b0f24f
is nicely structured. All commands will have a structure such
Packit b0f24f
as this in the log, we examplify with a object list request:
Packit b0f24f
Packit b0f24f
PTP REQEUST:
Packit b0f24f
000120: Bulk or Interrupt Transfer (UP), 03.09.2007 12:49:25.9843750 +0.0
Packit b0f24f
Pipe Handle: 0x863ce234 (Endpoint Address: 0x2)
Packit b0f24f
Send 0x20 bytes to the device:
Packit b0f24f
 20 00 00 00 01 00 05 98 23 00 00 00 27 03 00 10    ......?#...'...
Packit b0f24f
 Length      TYPE  CMD   Trans#      Param1
Packit b0f24f
Packit b0f24f
 00 00 00 00 02 DC 00 00 00 00 00 00 00 00 00 00   .....Ü..........
Packit b0f24f
 Param2      Param3      Param4      Param5
Packit b0f24f
Packit b0f24f
[OPTIONAL] DATA PHASE:
Packit b0f24f
000121: Bulk or Interrupt Transfer (UP), 03.09.2007 12:49:26.0 +0.0156250
Packit b0f24f
Pipe Handle: 0x863ce214 (Endpoint Address: 0x81)
Packit b0f24f
Get 0x1a bytes from the device:
Packit b0f24f
 1A 00 00 00 02 00 05 98 23 00 00 00 01 00 00 00   .......?#.......
Packit b0f24f
 Length      TYPE  CMD   Trans#      DATA
Packit b0f24f
Packit b0f24f
 27 03 00 10 02 DC 04 00 00 30                     '....Ü...0
Packit b0f24f
Packit b0f24f
RESPONSE:
Packit b0f24f
000122: Bulk or Interrupt Transfer (UP), 03.09.2007 12:49:26.0 +0.0
Packit b0f24f
Pipe Handle: 0x863ce214 (Endpoint Address: 0x81)
Packit b0f24f
Get 0xc bytes from the device:
Packit b0f24f
 0C 00 00 00 03 00 01 20 23 00 00 00               ....... #...
Packit b0f24f
 Length      TYPE  CODE  Trans#
Packit b0f24f
Packit b0f24f
* One send (OUT to the device), two reads (IN from the device).
Packit b0f24f
Packit b0f24f
* All three byte chunks commands are
Packit b0f24f
  sent/recieved/recieeved by the function  ptp_transaction()
Packit b0f24f
  in the file ptp.c.
Packit b0f24f
Packit b0f24f
* It boils down to ptp_usb_sendreq(), optionally ptp_usb_senddata()
Packit b0f24f
  or ptp_usb_getdata() and finally ptp_usb_getresp() in the file
Packit b0f24f
  libusb-glue.c. Notice ptp_usb_sendreq() and ptp_usb_getresp()
Packit b0f24f
  are ALWAYS called. The TYPE field correspond to this, so the
Packit b0f24f
  TYPES in this case are "COMMAND" (0x0001), "DATA" (0x0002),
Packit b0f24f
  and "RESPONSE" (0x0003).
Packit b0f24f
Packit b0f24f
* Notice that the byte order is little endian, so you need to read
Packit b0f24f
  each field from right to left.
Packit b0f24f
Packit b0f24f
* This COMMAND has:
Packit b0f24f
  CMD 0x99805, we see in ptp.h that this is PTP_OC_MTP_GetObjPropList.
Packit b0f24f
  Transaction# 0x00000023.
Packit b0f24f
  REQUEST parameters 0x10000327, 0x00000000, 0x0000DC02, 0x00000000
Packit b0f24f
    0x00000000, in this case it means "get props for object 0x10000327",
Packit b0f24f
    "any format", "property 0xDC02" (PTP_OPC_ObjectFormat), then two
Packit b0f24f
    parameters that are always zero (no idea what they mean or their
Packit b0f24f
    use).
Packit b0f24f
Packit b0f24f
* The DATA has:
Packit b0f24f
  CMD 0x99805, we see in ptp.h that this is PTP_OC_MTP_GetObjPropList.
Packit b0f24f
  Transaction# 0x00000023.
Packit b0f24f
  Then comes data 0x00000001, 0x10000327, 0xDC02, 0x0004, 0x3000
Packit b0f24f
  Which means in this case, (and this is the tricky part) "here
Packit b0f24f
  you have 1 property", "for object 0x10000327", "it is property
Packit b0f24f
  0xDC02" (PTP_OPC_ObjectFormat), "which is of type 0x0004"
Packit b0f24f
  (PTP_DTC_UINT16), "and set to 0x3000" (PTP_OFC_Undefined, it
Packit b0f24f
  is perfectly valid to have undefined object formats, since it
Packit b0f24f
  is a legal value defining this).
Packit b0f24f
Packit b0f24f
* This RESPONSE has:
Packit b0f24f
  CMD 0x99805, we see in ptp.h that this is PTP_OC_MTP_GetObjPropList.
Packit b0f24f
  Return Code ("RC") = 0x2001, PTP_RC_OK, all went fine.
Packit b0f24f
  Transaction# 0x00000023.
Packit b0f24f
Packit b0f24f
If you want to compare the Windows behaviour with a similar
Packit b0f24f
operation using libmtp you can go into the src/libusb-glue.c
Packit b0f24f
file and uncomment the row that reads:
Packit b0f24f
Packit b0f24f
//#define ENABLE_USB_BULK_DEBUG
Packit b0f24f
Packit b0f24f
(I.e. remove the two //.)
Packit b0f24f
Packit b0f24f
This will make libmtp print out a hex dump of every bulk USB
Packit b0f24f
transaction. The bulk transactions contain all the PTP/MTP layer
Packit b0f24f
data, which is usually where the problems appear.
Packit b0f24f
Packit b0f24f
Packit b0f24f
Notes to assist with debugging new devices:
Packit b0f24f
-------------------------------------------
Packit b0f24f
Packit b0f24f
In debugging new hardware, we highly recommend that you only
Packit b0f24f
use the example mtp-* applications that come with libmtp, as other
Packit b0f24f
applications may have their own bugs that may interfere with your
Packit b0f24f
new device working correctly. Using another application instead of
Packit b0f24f
those that come with libmtp just adds another point of failure.
Packit b0f24f
Packit b0f24f
For debugging, there are 3 main options:
Packit b0f24f
Packit b0f24f
1. Use the env variable: LIBMTP_DEBUG to increase the
Packit b0f24f
verboseness of the debugging output for any application using
Packit b0f24f
libmtp. Relevant codes are:
Packit b0f24f
* 0x00 [0000 0000] : no debug (default)
Packit b0f24f
* 0x01 [0000 0001] : PTP debug
Packit b0f24f
* 0x02 [0000 0010] : Playlist debug
Packit b0f24f
* 0x04 [0000 0100] : USB debug
Packit b0f24f
* 0x08 [0000 1000] : USB data debug
Packit b0f24f
// Codes are hex and binary respectively. Simple add them togther
Packit b0f24f
// to get your desired level of output.
Packit b0f24f
Packit b0f24f
(Assuming bash)
Packit b0f24f
eg:
Packit b0f24f
$ export LIBMTP_DEBUG=12
Packit b0f24f
$ mtp-detect
Packit b0f24f
  // To get USB debug and USB data debug information.
Packit b0f24f
Packit b0f24f
$ export LIBMTP_DEBUG=2
Packit b0f24f
$ mtp-detect
Packit b0f24f
    // To get Playlist debug information.
Packit b0f24f
Packit b0f24f
Also note, an application may also use the LIBMTP_debug() API
Packit b0f24f
function to achieve the same options as listed above.
Packit b0f24f
Packit b0f24f
2. Use "strace" on the various mtp-* commands to see where/what
Packit b0f24f
is falling over or getting stuck at.
Packit b0f24f
* On Solaris and FreeBSD, use "truss" or "dtrace" instead on "strace".
Packit b0f24f
* On Mac OS X, use "ktrace" or "dtrace" instead of "strace".
Packit b0f24f
* On OpenBSD and NetBSD, use "ktrace" instead of "strace".
Packit b0f24f
Packit b0f24f
This will at least help pinpoint where the application is failing, or
Packit b0f24f
a device is reporting incorrect information. (This is extremely helpful
Packit b0f24f
with devices that have odd disconnection requirements).
Packit b0f24f
Packit b0f24f
The use of these tools may also pinpoint issues with libusb as
Packit b0f24f
implemented by each OS vendor or issues with the MTP implementation
Packit b0f24f
on the new device as well, so please be prepared for either case.
Packit b0f24f
Packit b0f24f
3. Use "gdb" or similar debugger to step through the code as it is
Packit b0f24f
run. This is time consuming, and not needed just to pinpoint where
Packit b0f24f
the fault is.
Packit b0f24f
Packit b0f24f
The use of gdb or another debugger may also miss or actually cause
Packit b0f24f
command and data timing issues with some devices, leading to false
Packit b0f24f
information. So please consider this a last resort option.
Packit b0f24f
Packit b0f24f
Also please read the "It's Not Our Bug!" section below, as it does
Packit b0f24f
contain some useful information that may assist with your device.
Packit b0f24f
Packit b0f24f
Packit b0f24f
Dual-mode devices does not work - last resort:
Packit b0f24f
----------------------------------------------
Packit b0f24f
Packit b0f24f
Some devices that are dual-mode are simply impossible to get
Packit b0f24f
to work under Linux because the usb-storage(.ko) kernel
Packit b0f24f
module hook them first, and refuse to release them, even
Packit b0f24f
when we specify the DEVICE_FLAG_UNLOAD_DRIVER flag. (Maybe
Packit b0f24f
it DOES release it but the device will immediately be probed
Packit b0f24f
at the USB mass storage interface AGAIN because it
Packit b0f24f
enumerates.)
Packit b0f24f
Packit b0f24f
Here is what some people do:
Packit b0f24f
Packit b0f24f
 1. Plug in the device.
Packit b0f24f
 2. USB-mass storage folder will open automatically.
Packit b0f24f
 3. Unmount the device.
Packit b0f24f
 4. Run mtp-detect. It will most likely fail the first time.
Packit b0f24f
 5. Run mtp-detect again, it might work this time, or fail. Keep running
Packit b0f24f
    till it works. 99% it works by the third try.
Packit b0f24f
 6. Once mtp-detect gives you an "Ok", open either Rhythmbox or Gnomad2,
Packit b0f24f
    everything should work.
Packit b0f24f
Packit b0f24f
Linux: Try this, if you have a recent Linux kernel,
Packit b0f24f
add the file (as root):
Packit b0f24f
Packit b0f24f
/etc/modprobe.d/no-usb-storage.conf
Packit b0f24f
Packit b0f24f
With the contents:
Packit b0f24f
Packit b0f24f
options usb-storage quirks=1234:4321:i
Packit b0f24f
Packit b0f24f
This will tell usb-storage to ignore this device when it's inserted
Packit b0f24f
so it is not hogged by the mass storage interfaces. Remove and re-insert
Packit b0f24f
the device and see if it works. Usually this does the trick.
Packit b0f24f
Packit b0f24f
For older systems, or as a bigger hammer, run (as root) something
Packit b0f24f
like:
Packit b0f24f
Packit b0f24f
> rmmod usb_storage ; mtp-detect
Packit b0f24f
Packit b0f24f
You can run most any command or a client like gnomad2 or
Packit b0f24f
Amarok immediately after the rmmod command. This works
Packit b0f24f
sometimes. Another even more brutal approach is this:
Packit b0f24f
Packit b0f24f
* Edit /etc/modprobe.d/blacklist
Packit b0f24f
* Add the line "blacklist usb-storage"
Packit b0f24f
* Reboot.
Packit b0f24f
Packit b0f24f
Now none of you USB disks, flash memory sticks etc will be
Packit b0f24f
working (you just disabled them all). However you *can* try
Packit b0f24f
your device, and it might have started working because there
Packit b0f24f
is no longer a USB mass storage driver that tries to hook onto
Packit b0f24f
the mass storage interface of your device.
Packit b0f24f
Packit b0f24f
If not even blacklisting works (check with
Packit b0f24f
"lsmod | grep usb-storage"), there is some problem with
Packit b0f24f
something else and you may need to remove or rename the file
Packit b0f24f
/lib/modules/<VERSION>/kernel/drivers/usb/storage/usb-storage.ko
Packit b0f24f
manually.
Packit b0f24f
Packit b0f24f
If you find the PerfectSolution(TM) to this dilemma, so you
Packit b0f24f
can properly switch for individual devices whether to use it
Packit b0f24f
as USB mass storage or not, please tell us how you did it. We
Packit b0f24f
know we cannot use udev, because udev is called after-the-fact:
Packit b0f24f
the device is already configured for USB mass storage when
Packit b0f24f
udev is called.
Packit b0f24f
Packit b0f24f
On Mac OS there is another ugly hack:
Packit b0f24f
Packit b0f24f
1. Open up a terminal window
Packit b0f24f
2. Type:
Packit b0f24f
sudo mv /System/Library/Extensions/IOUSBMassStorageClass.kext
Packit b0f24f
/System/Library/Extensions/IOUSBMassStorageClass.kext.disabled
Packit b0f24f
Packit b0f24f
and when prompted enter your password.
Packit b0f24f
Packit b0f24f
3. Restart.
Packit b0f24f
Packit b0f24f
To reverse this change, just reverse the filenames:
Packit b0f24f
Packit b0f24f
sudo mv /System/Library/Extensions/
Packit b0f24f
IOUSBMassStorageClass.kext.disabled /System/Library/Extensions/
Packit b0f24f
IOUSBMassStorageClass.kext
Packit b0f24f
Packit b0f24f
and restart.
Packit b0f24f
Packit b0f24f
Packit b0f24f
Calendar and contact support:
Packit b0f24f
-----------------------------
Packit b0f24f
Packit b0f24f
The Creative Zen series can read VCALENDAR2 (.ics) files
Packit b0f24f
and VCard (.vcf) files from programs like for example
Packit b0f24f
Evolution with the following limitations/conditions:
Packit b0f24f
Packit b0f24f
- The file must be in DOS (CR/LF) format, use the unix2dos
Packit b0f24f
  program to convert if needed
Packit b0f24f
Packit b0f24f
- Repeat events in calendar files do not seem to be supported,
Packit b0f24f
  entries will only appear once.
Packit b0f24f
Packit b0f24f
- Calendar (.ics) files should be stored in the folder "My Organizer"
Packit b0f24f
  when sent to the device (this directory should be autodetected
Packit b0f24f
  for use with calendar files, otherwise use the option
Packit b0f24f
  -f "My Organizer" to sendfile for this) Apparently this file can
Packit b0f24f
  also contain tasklists.
Packit b0f24f
Packit b0f24f
- Contact (.vcf) files should be stored in the folder "My Contacts"
Packit b0f24f
  when sent to the device. (-f "My Contacts")
Packit b0f24f
Packit b0f24f
- Some devices are picky about the name of the calendar and
Packit b0f24f
  contact files. For example the Zen Microphoto wants:
Packit b0f24f
Packit b0f24f
  Calendar: My Organizer/6651416.ics
Packit b0f24f
  Contacts: My Organizer/6651416.vcf
Packit b0f24f
Packit b0f24f
Packit b0f24f
Syncing in with Evolution and Creative Devices
Packit b0f24f
----------------------------------------------
Packit b0f24f
Packit b0f24f
Evolution can easily export .ics an .vcf files, but you currently
Packit b0f24f
need some command-line hacking to get you stuff copied over in
Packit b0f24f
one direction host -> device. The examples/ directory contains a script
Packit b0f24f
created for the Creative Zen Microphoto by Nicolas Tetreault.
Packit b0f24f
Packit b0f24f
Packit b0f24f
Lost symbols
Packit b0f24f
------------
Packit b0f24f
Packit b0f24f
Shared libraries can be troublesome to users not experienced with
Packit b0f24f
them. The following is a condensed version of a generic question
Packit b0f24f
that has appeared on the libmtp mailing list from time to time.
Packit b0f24f
Packit b0f24f
> PTP: Opening session
Packit b0f24f
> Queried Creative Zen Vision:M
Packit b0f24f
> gnomad2: relocation error: gnomad2: undefined symbol:
Packit b0f24f
> LIBMTP_Get_Storageinfo
Packit b0f24f
> (...)
Packit b0f24f
> Are these type of errors related to libmtp or something else?
Packit b0f24f
Packit b0f24f
The problem is of a generic nature, and related to dynamic library
Packit b0f24f
loading. It is colloquially known as "dependency hell".
Packit b0f24f
(http://en.wikipedia.org/wiki/Dependency_hell)
Packit b0f24f
Packit b0f24f
The gnomad2 application calls upon the dynamic linker in Linux to
Packit b0f24f
resolve the symbol "LIBMTP_Get_Storageinfo" or any other symbol
Packit b0f24f
(ELF symbol, or link point or whatever you want to call them, a
Packit b0f24f
symbol is a label on a memory address that the linker shall
Packit b0f24f
resolve from label to actual address.)
Packit b0f24f
For generic information on this subject see the INSTALL file and
Packit b0f24f
this Wikipedia page:
Packit b0f24f
Packit b0f24f
http://en.wikipedia.org/wiki/Library_(computing)
Packit b0f24f
Packit b0f24f
When Linux /lib/ld-linux.so.X is called to link the symbols compiled
Packit b0f24f
into gnomad2 (or any other executable using libmtp), it examines the
Packit b0f24f
ELF file for the libmtp.so.X file it finds first and cannot resolve
Packit b0f24f
the symbol "LIBMTP_Get_Storageinfo" (or whichever symbol you have a
Packit b0f24f
problem witj) from it, since it's probably not there. There are many
Packit b0f24f
possible causes of this symbol breakage:
Packit b0f24f
Packit b0f24f
1) You installed precompiled libmtp and gnomad2 packages (RPMs, debs
Packit b0f24f
    whatever) that do not match up. Typical cause: your gnomad2 package was
Packit b0f24f
    built against a newer version of libmtp than what's installed on your
Packit b0f24f
    machine. Another typical cause: you installed a package you found on
Packit b0f24f
    the web, somewhere, the dependency resolution system did not protest
Packit b0f24f
    properly (as it should) or you forced it to install anyway, ignoring
Packit b0f24f
    some warnings.
Packit b0f24f
Packit b0f24f
2) You compiled libmtp and/or gnomad2 from source, installing both or
Packit b0f24f
    either in /usr/local/lib and /usr/local/bin. This means at compile-time
Packit b0f24f
    gnomad2 finds the libmtp library in /usr/local/lib but at runtime, it
Packit b0f24f
    depends on the Linux system wide library loader (/lib/ld-linux.so.X) in
Packit b0f24f
    order to resolve the symbols. This loader will look into the file
Packit b0f24f
    /etc/ld.so.conf and/or the folder /etc/ld.so.conf.d in order to find
Packit b0f24f
    paths to libraries to be used for resolving the symbols. If you have
Packit b0f24f
    some older version of libmtp in e.g. /usr/lib (typically installed by a
Packit b0f24f
    package manager) it will take precedence over the new version you just
Packit b0f24f
    installed in /usr/local/lib and the newly compiled library in
Packit b0f24f
    /usr/local/lib will *not* be used, resulting in this error message.
Packit b0f24f
Packit b0f24f
3) You really did install the very latest versions (as of writing libmtp
Packit b0f24f
    0.1.5 and gnomad2 2.8.11) from source and there really is no
Packit b0f24f
    pre-installed package of either on your machine. In that case I'm
Packit b0f24f
    totally lost, I have no idea what's causing this.
Packit b0f24f
Packit b0f24f
Typical remedies:
Packit b0f24f
Packit b0f24f
1) If you don't want to mess around with your system and risk these
Packit b0f24f
    situations, only use pre-packaged software that came with the
Packit b0f24f
    distribution or its official support channels. If it still breaks,
Packit b0f24f
    blame your distribution, they're not packaging correctly. Relying on
Packit b0f24f
    properly packaged software and not installing things yourself *is* the
Packit b0f24f
    Linux solution to the "dependency hell" problem.
Packit b0f24f
Packit b0f24f
2) Read about dynamically linked library handling until the stuff I wrote
Packit b0f24f
    about in the previous list sounds like music to your ears, inspect
Packit b0f24f
    your /lib, /usr/lib, /usr/local/lib, /etc/ld.so.conf and the
Packit b0f24f
    /etc/ld.so.conf.d, remove all pre-packed versions using RPM, APT,
Packit b0f24f
    YaST or whatever your distribution uses, compile libmtp and gnomad2
Packit b0f24f
    (or whatever) from source only and you will be enlighted.
Packit b0f24f
Packit b0f24f
I don't know if this helps you, it's the best answer we can give.
Packit b0f24f
Packit b0f24f
Packit b0f24f
API is obscure - I want plain files!
Packit b0f24f
------------------------------------
Packit b0f24f
Packit b0f24f
PTP/MTP devices does not actually contain "files", they contain
Packit b0f24f
objects. These objects have file names, but that is actually
Packit b0f24f
just a name tag on the object.
Packit b0f24f
Packit b0f24f
Folders/directories aren't really such entities: they are just
Packit b0f24f
objects too, albeit objects that can act as parent to other
Packit b0f24f
objects. They are called "associations" and are created in atomic
Packit b0f24f
fashion and even though there is an MTP command to get all the
Packit b0f24f
associations of a certain object, this command is optional
Packit b0f24f
so it is perfectly possible (and most common, actually) to create
Packit b0f24f
devices where the "folders" (which are actually associations) have
Packit b0f24f
no idea whatsoever of what files they are associated as parents to
Packit b0f24f
(i.e. which files they contain). This is very easy for device
Packit b0f24f
manufacturers to implement, all the association (i.e. finding out
Packit b0f24f
which files are in a certain folder) has to be done by the MTP
Packit b0f24f
Initiator / host computer.
Packit b0f24f
Packit b0f24f
Moving a file to a new folder is for example very simple in a
Packit b0f24f
"real" file system. In PTP/MTP devices it is often not even possible,
Packit b0f24f
some devices *may* be able to do that, if they support command
Packit b0f24f
0x1019 "Move Object", but actually the only reliable way of executing
Packit b0f24f
file movement is to upload the file to the host, download it with
Packit b0f24f
the new parent, then delete the old file. We have played with the
Packit b0f24f
idea of implementing this time consuming function as a fallback
Packit b0f24f
in case the device does not support command 0x1019, perhaps one day
Packit b0f24f
we will do that. (Some devices also support command 0x101a
Packit b0f24f
"Copy Object".)
Packit b0f24f
Packit b0f24f
Then the issue that in PTP/MTP it is legal for two files to have
Packit b0f24f
exactly the same path as long as their object IDs differ. A
Packit b0f24f
folder/association can contain two files with the exact same name.
Packit b0f24f
(And on the Creative devices this even works, too, though most devices
Packit b0f24f
implicitly fail at this.) Perhaps one could add some custom hook for
Packit b0f24f
handling that, so they become  /Foo.mp3 and /Foo.mp3(1) or something
Packit b0f24f
similar, but it's really a bit kludgy.
Packit b0f24f
Packit b0f24f
Playlists and albums aren't really files, thinking about
Packit b0f24f
them as files like the hacks in libgphoto2 is really backwards. They are
Packit b0f24f
called associations and are more like a symbolic link that links in a
Packit b0f24f
star-shaped pattern to all the files that are part of the album/playlist.
Packit b0f24f
Some devices (Samsung) thought that was too complicated and have a
Packit b0f24f
different way of storing playlists in an UTF-16 encoded .spl-like file
Packit b0f24f
instead! This is why playlists/albums must have their own structs and
Packit b0f24f
functions.
Packit b0f24f
Packit b0f24f
Plain file access also assumes to be able to write files of an
Packit b0f24f
undetermined size, which is simply not possible in a transactional
Packit b0f24f
file system like PTP/MTP. (See further below.)
Packit b0f24f
Packit b0f24f
Packit b0f24f
I Want Streaming!
Packit b0f24f
-----------------
Packit b0f24f
Packit b0f24f
Streaming reads is easy. Just connect the output file descriptor from
Packit b0f24f
LIBMTP_Get_File_To_File_Descriptor() (and a similar function for tracks)
Packit b0f24f
wherever you want.
Packit b0f24f
Packit b0f24f
People have connected this to TCP sockets for streaming web servers
Packit b0f24f
etc, works like a charm. Some devices will even survive if the callback
Packit b0f24f
functions return non-zero and cancel the download. Some devices will
Packit b0f24f
lock up and even require a reset if you do that. Devices are poorly
Packit b0f24f
implemented so that's life. If you want to stream off a device, the
Packit b0f24f
best idea is always to stream the entire file and discard the stuff
Packit b0f24f
at the end you don't want. It will incur a delay if you e.g. want to
Packit b0f24f
skip between tracks, sadly.
Packit b0f24f
Packit b0f24f
Then we get to the complicated things: streaming WRITES...
Packit b0f24f
Packit b0f24f
There is a function:
Packit b0f24f
LIBMTP_Send_File_From_File_Descriptor() (and similar for tracks)
Packit b0f24f
which will write a file to a device from a file descriptor, which may
Packit b0f24f
be a socket or whatever.
Packit b0f24f
Packit b0f24f
HOWEVER: this requires a piece of metadata with the .filesize properly
Packit b0f24f
set first.
Packit b0f24f
Packit b0f24f
This is not because we think it is funny to require that, the protocol
Packit b0f24f
requires it. The reason is that PTP/MTP is a transactional file system
Packit b0f24f
and it wants to be able to deny file transfer if the file won't fit on
Packit b0f24f
the device, so the transaction never even starts, it's impossible to
Packit b0f24f
start a transaction without giving file length.
Packit b0f24f
Packit b0f24f
People really want streaming so I tried a lot of hacks to see if they
Packit b0f24f
would work, such as setting file size to 0xffffffffU or something other
Packit b0f24f
unnaturally big and then aborting the file transfer when the stream ends.
Packit b0f24f
It doesn't work: either the device crashes or the file simply disappears
Packit b0f24f
since the device rolls back all failed transactions.
Packit b0f24f
Packit b0f24f
So this is an inherent limitation of the PTP/MTP protocol.
Packit b0f24f
Packit b0f24f
Packit b0f24f
I want to remote control my device!
Packit b0f24f
-----------------------------------
Packit b0f24f
Packit b0f24f
I have both good and bad news for you.
Packit b0f24f
Packit b0f24f
The good news is that the MTP protocol has well-defined commands to play
Packit b0f24f
back content on a device. Operation 0xD411 (PTP_DPC_MTP_PlaybackObject)
Packit b0f24f
will start playing back a file on the device (whatever that may mean if
Packit b0f24f
this is not a music or video file), and operation 0xD403 can set the
Packit b0f24f
playback volume to save your ears. Then there are operations to
Packit b0f24f
determine how far into the current file you currently are, so as to
Packit b0f24f
support say progress bars.
Packit b0f24f
Packit b0f24f
Since these commands have been around since the dawn of the MTP protocol
Packit b0f24f
and since it was developed in cooperation with Creative Technology, this
Packit b0f24f
is probably a requested feature from the Creative people who already had
Packit b0f24f
support for playback on their devices using the PDE protocol back then.
Packit b0f24f
Packit b0f24f
Anyway, here are the bad news:
Packit b0f24f
[logs]$ grep d411 *
Packit b0f24f
mtp-detect-trekstor-vibez.txt:   0xd411: Playback Object
Packit b0f24f
Packit b0f24f
Aha there is only one known device in the world which actually supports
Packit b0f24f
playback on the device. So either you go buy the Trekstor Vibez, or you
Packit b0f24f
can forget about this. You could always try asking your hardware vendor
Packit b0f24f
of choice to go implement this.
Packit b0f24f
Packit b0f24f
Since none of the core developers of libmtp has the Trekstor device, this
Packit b0f24f
is not yet implemented in libmtp.
Packit b0f24f
Packit b0f24f
Packit b0f24f
I make MTP devices!
Packit b0f24f
-------------------
Packit b0f24f
Packit b0f24f
If you are a device vendor there is a lot you can do for libmtp:
Packit b0f24f
Packit b0f24f
* Please consider assigning one of your employees as a contact person
Packit b0f24f
  for libmtp, have them sign up to the libmtp development list and answer
Packit b0f24f
  questions and post new device ID:s as they are released to our
Packit b0f24f
  mailing list.
Packit b0f24f
Packit b0f24f
* If you want to help even more, assign someone to look deeper into
Packit b0f24f
  error reports on your specific devices, understand why your firmware
Packit b0f24f
  may require some special device flags and what can be done about it.
Packit b0f24f
Packit b0f24f
* Do you have spare devices you can give us? Send them to Richard (Mac
Packit b0f24f
  support) or Linus (Linux support). (So far nobody did that except for
Packit b0f24f
  Microsoft who sent us a Zune by proxy!)
Packit b0f24f
Packit b0f24f
Vendors do need help from libmtp too, especially we want to help
Packit b0f24f
vendors improve their MTP stacks, because they all suffer from the
Packit b0f24f
same problem: the lack of a proper conformance test has made many devices
Packit b0f24f
incompliant with the MTP specification as it is published today: most
Packit b0f24f
devices are just compliant with the Windows MTP stack, and don't work
Packit b0f24f
out-of-the-box with libmtp. We need someone on the inside to help in
Packit b0f24f
bug reporting vendors MTP stacks internally so these issues are raised.
Packit b0f24f
A good way to go toward better MTP compliance is to test with an
Packit b0f24f
alternative implementation of the stack. In e.g. IETF standardization
Packit b0f24f
it is compulsory for an RFC to have atleast two independent implementations
Packit b0f24f
for it to reach the status as standard.
Packit b0f24f
Packit b0f24f
Being compliant with libmtp is also more and more important for
Packit b0f24f
vendors: libmtp is being deployed in some embedded systems like
Packit b0f24f
set-top-boxes etc. It will be very irritating for customers if a device
Packit b0f24f
will not dock properly with some home entertainment equipment just because
Packit b0f24f
it is based on Linux and libmtp and not the Windows MTP stack.
Packit b0f24f
Packit b0f24f
Autodetect with gudev
Packit b0f24f
---------------------
Packit b0f24f
Packit b0f24f
Previously you would use HAL to detect devices being plugged in. Nowadays
Packit b0f24f
we use udev directly, or though the GNOME libgudev library. LIBMTPs
Packit b0f24f
default udev rules export the proper properties to detect any MTP device
Packit b0f24f
automatically, here is a verbose example derived from gnomad2:
Packit b0f24f
Packit b0f24f
#define G_UDEV_API_IS_SUBJECT_TO_CHANGE
Packit b0f24f
#include <gudev/gudev.h>
Packit b0f24f
const char * const gudev_subsystems[] = { "usb", NULL };
Packit b0f24f
GUdevClient *gudev_client;
Packit b0f24f
guint uevent_id;
Packit b0f24f
guint uevent_bus_hooked = 0;
Packit b0f24f
guint uevent_device_hooked = 0;
Packit b0f24f
Packit b0f24f
Packit b0f24f
static void uevent_cb(GUdevClient *client, const char *action, GUdevDevice *device, void *data)
Packit b0f24f
{
Packit b0f24f
  guint64 devicenum;
Packit b0f24f
  guint vendor;
Packit b0f24f
  guint model;
Packit b0f24f
  guint busnum;
Packit b0f24f
  guint devnum;
Packit b0f24f
  guint mtpdevice;
Packit b0f24f
Packit b0f24f
  devicenum = (guint64) g_udev_device_get_device_number(device);
Packit b0f24f
  g_print("%s event for %s (%"G_GINT64_MODIFIER"x)", action,
Packit b0f24f
          g_udev_device_get_sysfs_path (device), devicenum);
Packit b0f24f
Packit b0f24f
  /* get device info */
Packit b0f24f
  vendor = get_property_as_int(device, "ID_VENDOR_ID", 16);
Packit b0f24f
  model = get_property_as_int(device, "ID_MODEL_ID", 16);
Packit b0f24f
  busnum = get_property_as_int(device, "BUSNUM", 10);
Packit b0f24f
  devnum = get_property_as_int(device, "DEVNUM", 10);
Packit b0f24f
  mtpdevice = get_property_as_int(device, "ID_MTP_DEVICE", 10);
Packit b0f24f
Packit b0f24f
  if (vendor == 0 || model == 0) {
Packit b0f24f
    g_print("couldn't get vendor or model ID for device at (%x:%x)\n",
Packit b0f24f
            busnum, devnum);
Packit b0f24f
    return;
Packit b0f24f
  } else {
Packit b0f24f
    g_print("vendor = %x, model = %x, bus = %x, device = %x\n",
Packit b0f24f
            vendor, model, busnum, devnum);
Packit b0f24f
  }
Packit b0f24f
Packit b0f24f
  if (mtpdevice) {
Packit b0f24f
    g_print("device is MTP compliant\n");
Packit b0f24f
Packit b0f24f
    if (g_str_equal(action, "add") &&
Packit b0f24f
       uevent_bus_hooked == 0 &&
Packit b0f24f
       uevent_device_hooked == 0) {
Packit b0f24f
      g_print(MTP device plugged in!\n");
Packit b0f24f
      uevent_bus_hooked = busnum;
Packit b0f24f
      uevent_device_hooked = devnum;
Packit b0f24f
      scan_jukebox(NULL);
Packit b0f24f
    } else if (g_str_equal (action, "remove") &&
Packit b0f24f
       	   uevent_bus_hooked == busnum &&
Packit b0f24f
           uevent_device_hooked == devnum) {
Packit b0f24f
      g_print("MTP device removed!\n");
Packit b0f24f
      uevent_bus_hooked = 0;
Packit b0f24f
      uevent_device_hooked = 0;
Packit b0f24f
    }
Packit b0f24f
  }
Packit b0f24f
}
Packit b0f24f
Packit b0f24f
Packit b0f24f
Packit b0f24f
(...)
Packit b0f24f
  /*
Packit b0f24f
   * Monitor udev device events - we're only really interested in events
Packit b0f24f
   * for USB devices.
Packit b0f24f
   */
Packit b0f24f
  gudev_client = g_udev_client_new(gudev_subsystems);
Packit b0f24f
  uevent_id = g_signal_connect_object(gudev_client,
Packit b0f24f
                                      "uevent",
Packit b0f24f
                                      G_CALLBACK(uevent_cb),
Packit b0f24f
                                      NULL, 0);
Packit b0f24f
Packit b0f24f
SKETCH OF AN OVERVIEW
Packit b0f24f
---------------------
Packit b0f24f
Packit b0f24f
Draft agenda for a talk on MTP devices submitted for the Android
Packit b0f24f
builders summit, might come to recycle this:
Packit b0f24f
Packit b0f24f
- Protocol overview
Packit b0f24f
  - Transactional filesystem - no corruption due to unplugged cables!
Packit b0f24f
  - The host and the device can access the files simultaneously, the
Packit b0f24f
    device will always "own" the physical file system and proxy the
Packit b0f24f
    host (MTP initiator).
Packit b0f24f
- libmtp interface
Packit b0f24f
- relation to libgphoto2
Packit b0f24f
- User expectations fall short:
Packit b0f24f
  - Not really a mountable filesystem.
Packit b0f24f
  - Streaming does not work. (Size needs to be known beforehand due to
Packit b0f24f
    transactional nature.)
Packit b0f24f
  - GVFS MTP backend to the rescue.
Packit b0f24f
- Device sins
Packit b0f24f
  - Using the same VID/PID for several modes, some of which are not MTP.
Packit b0f24f
    HTC Zopo, HD2, Bird (0x0bb4/0x0c02). Thanks for that, now we cannot
Packit b0f24f
    detect the protocol from just VID+PID but have to examine the interfaces.
Packit b0f24f
  - Android bugs
Packit b0f24f
  - Samsungs special Android MTP stack
Packit b0f24f
  - SonyEricsson Aricent stack for Xperia Androids pre 4.0, broken headers!
Packit b0f24f
  - Flat access model vs hierarchical, how Android uses MTP as an hierachical
Packit b0f24f
    file system while it was previously a flat database.
Packit b0f24f
  - Old paradigm: scan the entire non-hierarchical storage for all content,
Packit b0f24f
    build a cache to speed up the (USB 1.1!) link. Usually all files were
Packit b0f24f
    stored in the root folder or a single folder named "/Music" or similar.
Packit b0f24f
  - Android introduced deeply nested folder hierarchies, not seen before
Packit b0f24f
    on MTP devices.
Packit b0f24f
  - Microsoft not using the complete metadata dump feature of the MTP
Packit b0f24f
    protocol (once introduced by creative) instead they walk directories
Packit b0f24f
    separately.
Packit b0f24f
  - So caching a big device will take long time and/or timeout.
Packit b0f24f
  - Go-MTPFS (FUSE) and GVFS MTP - doing the partial directory walk rather
Packit b0f24f
    than caching all files.
Packit b0f24f
  - Especially Android devices nowadays assume that
Packit b0f24f
    you want to index a folder at the time, whereas older MTP devices (such
Packit b0f24f
    as those from Creative) would assume that you wanted to index the entire
Packit b0f24f
    device as it was plugged in, and device firmware is now ever more tailored
Packit b0f24f
    toward per-folder filetree walking. This makes it harder for the library
Packit b0f24f
    to provide the right abstractions: do we provide an API for indexing the
Packit b0f24f
    whole device which is unacceptably slow on new devices, or do we provide
Packit b0f24f
    an API for indexing a directory at the time which will somehow work on
Packit b0f24f
    older devices too? Shall we deprecate the older API?
Packit b0f24f
- Detecting from vendor extension, can fix in newer extensions!
Packit b0f24f
- Autoprobing on Linux
Packit b0f24f
  - Color devices do not like autoprobing
Packit b0f24f
  - Devices need different PIDs for every alternative interface due to
Packit b0f24f
    the Windows USB stack.
Packit b0f24f
  - Multimode USB - one PID for each mode due to Windows limitations not
Packit b0f24f
    applicable to Linux, SONY devices have ~5 different PIDs for a single
Packit b0f24f
    device.
Packit b0f24f
  - Mode switch devices? Maybe we do this wrong.
Packit b0f24f
- MTPZ, came and went. Apparently deprecated by Microsoft with Windows
Packit b0f24f
  Phone 8.
Packit b0f24f
- Ideas??
Packit b0f24f