|
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 |
|