Author: Michael Minn <mmptp@michaelminn.com>
July 20, 2003
MMPTP is a Linux kernel module and command line program for accessing images from digital cameras using the PTP standard (Picture Transfer Protocol), formerly known as PIMA 15740:2000.
While MMPTP has been coded to support the Kodak DX-3500, DC-4800, DC-240 and all other USB Imaging Class 1.0 PTP cameras, it has only been tested with the DX-3500 under a standard workstation installation of Red Hat Linux 7.2 (2.4 kernel). I have also been told it works with the Sony DSC-P5 and Kodak DX3600 and on Slackware 8.1. The author welcomes contributions from anyone willing to test and/or modify the software with other PTP devices and/or other distributions of Linux.
MMPTP is free software; you can redistribute it and/or modify it under the terms of version 2 the GNU General Public License as published by the Free Software Foundation.
Many thanks to Jose Luis Sanchez for his work getting the program to function with DX-3500 expansion cards and in cleaning up some module compilation problems.
The standard used to be available online, however since the merger of the
Digital Imaging Association (DIA) & The Photographic and Imaging Manufacturers Association (PIMA)
into International Industry Imaging Association (I3A)
the standard is only available (as of this writing) for a $35 fee, which can be waived for students.
See the
Version 2003.07.20:
Read timing now waits 5*HZ (five seconds) rather than just HZ (one second).
Added linux/modversions.h to module source so depmod doesn't give unresolved symbol errors.
Replaced purb_t (which is missing in newer kernels) with struct urb* to avoid compile errors.
Version 2002.09.22:
Fixed problem with camera stalling when trying to get a "directory" (MMPTP_FORMAT_ASSOCIATION) object
on DX-3500 with an installed memory expansion card.
Replaced printk by 'new fashion' info and err macros. Added modinfo data.
Modified Makefile to compile 'out of the box' on 2.4 kernel series and newest glibc.
MMPTP_FORMAT_TIFF (format code 0x3802) renamed to MMPTP_FORMAT_TIFF_EP
to avoid clash with format code 0x380d.
Version 2002.02.18:
Initial release that compiles under Red Hat 7.2 and supports only the Kodak DX3500 camera.
MMPTP consists of a simple kernel module (mmptp.o) and a simple command line program (mmptp)
to download information from the PTP device. Download a tarball from
the version list above and AS SUPERUSER decompress the tarball and make install:
The make install will place the kernel module in the /lib/.../drivers/usb directory.
The exact directory depends on the version of the kernel you are running. It
places the command line executable file in /usr/local/bin.
The MMPTP device file (used by the command line program to exchange information
with the kernel module) is defined in the Makefile with the constant MMPTP_DEVICE_FILE
as /dev/usb/mmptp. Device files (nodes) each have unique "Major Numbers"
that distinguish them from other devices and permit multiple files to point
to the same device driver by using the same Major Number. MMPTP uses Major Number
181, defined with the constant MMPTP_MAJOR_NUMBER in the Makefile. This number was
chosen arbitrarily and might conflict with another device driver on your system.
If so, you can make uninstall, change the Makefile MMPTP_MAJOR_NUMBER to another unused
major number, and recompile/reinstall.
You will also need to add the following line to the bottom of /etc/modules.conf
so the MMPTP module to load when you try to access the device.
This file is a cross-reference used by the kernel to determine what module should be
loaded to support a given resource - in this case the MMPTP device
you defined earlier with major number 181 which is handled by the MMPTP module.
MMPTP can be uninstalled by typing "make uninstall" in the
mmptp source code directory you created above. If you modified the
/etc/modules.conf as described above, you will need to manually edit the file
and delete the added line.
MMPTP is a command line program with a few simple but powerful commands.
It is invoked by typing "mmptp" at a console or in a console window
with exactly one option.
MMPTP will display a syntax message if more than
one option or no options are given. Much of the device information is
specific to the PTP protocol and not necessarily useful to the casual user.
More information on the PTP protocol can be downloaded from the
PIMA PTP page.
Attempting to run MMPTP with no device connected will simply issue an
error message that the host is down.
-i: Prints information about the connected device and can be used
to verify that MMPTP is recognizing a device that has been connected properly.
Some of this information is self-explanatory and some is PTP specific and not
normally useful to the casual user.
-s: Prints information about specific storage media available on a device.
With digital cameras, storage media includes the internal memory and any memory
cards or sticks that can be connected to or inserted in the device.
If a particular storage medium is not connected (e.g. a memory card is not inserted),
MMPTP will simply list the medium as not connected. As with device info,
some of this information is self-explanatory and some is PTP specific and not
normally useful to the casual user.
-l: Lists images currently stored on the device in a short, useful format.
-L: Lists images currently stored on the device in a long, cumbersome format.
As with device info, some of this information is self-explanatory and some is
PTP specific and not normally useful to the casual user.
-d: Downloads all images from the device into the current working directory.
Images are stored with a filename in the format YYYY-MM-DD_HH-MM-SS.jpg which explicitly
indicates the date and time when the picture was taken. MMPTP does not use the
internal filenames assigned by the device. There is no option for
downloading only specific images - all images must be downloaded at once.
The following information is given for those who are interested in
how MMPTP works and for those who are learning about working with the Linux USB
subsystem and/or the USB PTP protocol.
Jphoto is another project for working with
USB PTP devices. However, it requires Java(tm) and and the
JUsb library.
Wanting to avoid having to burden my modest laptop with Java and
being dependent on libraries that might not exist in the future,
I decided to write my own.
The Linux USB subsystem/API and the PTP protocol are both relatively simple but I
have found them difficult to program due to limited documentation. This information
is therefore provided to help ease the way for others. But, ultimately, the
source code is the best explanation for how the software works.
Kernel modules can be used for a number of purposes, but are perhaps most valuable
for device drivers. As such, they are kernel code that is executed when
data is written/read from a device file. The best resource for module programming is the book,
Linux Device Drivers by Alessandro Rubini and published by
O'Reilly.
Device files are also called nodes, they are created with the mknod
command and they are kept in the /dev directory.
While device files are distinguished to normal users with text names (i.e. /dev/lp1)
they are distinguished in the kernal by MAJOR NUMBER. Each kernel module
handles all device files that have a specific major number. One kernel module
can handle multiple major numbers, but different device files with the same
major number must all be handled by a single kernel module.
There are two functions that must be provided in each kernel module:
init_module(void), which is run when the module is loaded; and
cleanup_module(void), which is run when the module is unloaded. In
MMPTP, init_module() registers itself with the Linux file system and
specifies the file operation functions that are called
when the user accesses the device. init_module() also registers itself
with the USB subsystem so that it's probe functions will be called whenever
a new device is connected to determine whether it will serve that device.
cleanup_module() deregisters itself from the file system and the USB subsystem.
When a new device is connected to the USB port, it identifies itself with
a device descriptor that specifies numeric codes for the manufacturer and
the specific device. The Linux USB subsystem then calls the probe functions
for all registered USB device drivers to determine which (if any) of the loaded
modules serves the newly connected device. If no driver is found, the
device information is simply stored and no user interaction can take place
with the device. Also, if a driver module is loaded later, the module's probe
function is called for each currently connected (but unsupported) USB device.
This permits the driver to be loaded either before or after the USB device
is connected. There is also a disconnect function that is called when a
USB device is disconnected. The probe and disconnect functions are
specified when the driver is registered with the USB subsystem.
MMPTP's probe function is mmptp_probe() and its disconnect function
is mmptp_disconnect(). mmptp_probe() is passed a device information
structure when it is called by the USB subsystem. It checks the
vendor code and product code against hard-coded values for the devices
it supports. If a match is found, mmptp_probe() sets global variables
with the information needed to communicate with the device while it is connected.
mmptp_disconnect() then NULLs those global variables so no further communication
can occur.
Communication with Linux USB block devices (like PTP cameras)
is done with a block of data called a URB (universal resource block)
through endpoints. Endpoints are similar to file descriptors in that
data is either read from or written to endpoints. There are separate
endpoints for output or input - they are never bidirectional.
When data is sent to a USB device, it is copied into a URB and the
usb_submit_urb() function is called with a output endpoint. MMPTP then
waits on a wait queue for a response. A callback function specified in
the URB wakes up MMPTP and a status byte in the URB indicates whether
the information was successfully sent to the device. Similarly, when
reading, MMPTP submits a URB to an input endpoint and waits for a response
that contains data sent from the device.
As with Linux USB, the formal documentation for the PTP Protocol is rather difficult
to read for a novice. As a generalized and exhaustive standard, it proved difficult to determine
exactly the specific USB PTP protocol for simple operations. It turns out to be relatively simple.
Information is exchanged in containers that may be sent across one or more URB's.
If the contents of the container is too large for a single URB, it is sent in
multiple successive URB's. The rule is that if a URB is received with it's maximum
amount of data, a successive URB must be read to continue receiving data for
a container. The final URB will either have less than the maximum amount of data
or no data at all.
Containers are exchanged with a USB PTP device in transactions. A transaction
consists of the write of a command (operation) container and read of
a data container and a response code container or just a response code container.
PTP transactions are always initiated by the computer and responded to by the USB device.
The MMPTP container structure is mmptp_container. A container consists of 12 bytes
of header information followed by a variable length "payload".
The header indicates the size of the container, the type of container (whether
it is a command, a container of data or a container with a response),
a code specifying the command or response status and a transaction ID.
Containers must be exchanged with the device within a session.
MMPTP opens a session when it is invoked and closes the session
when it completes execution. Sessions must have unique numeric identifiers
and MMPTP uses the Linux time() integer to identify sessions.
Containers sent between the computer and the USB device are given
sequential numeric transaction ID's that start with 1 at the beginning of each session.
A PTP device will have one or more storage mediums which are accessed by numeric
storage handles. On each storage medium, there will be zero or more image objects
that are referenced by numeric object handles. Requests can be made to the device
to return arrays of storage or object handles.
When an error occurrs (such as attempting to get information on an unconnected
memory card), the PTP device will "stall" the endpoint. While there
is a specific procedure for clearing the stall, I couldn't figure out how to
make it work under Linux. usb_clear_halt() didn't work.
The Linux USB subsystem can only be accessed from kernel modules. There are existing
libraries that provide indirect user access to the USB subsystem, but they
are not currently part of standard Linux distributions. As such, MMPTP provides
a simple kernel module for reading/writing containers from/to PTP devices.
The MMPTP executable handles the formatting and manipulation of the container contents.
For example, to download images from the device, MMPTP uses the following procedure:
2. Version History & Download
3. Installation
tar -zxvf mmptp*.gz
cd mmptp
make install
alias char-major-181 mmptp
4. Operation
mmptp -i | -s | -l | -L | -d
5. Implementation Notes
5.1 Linux USB
5.2 PTP Protocol