MMPTP

Author: Michael Minn (michaelminn.com)

September 24, 2008


A command line program for accessing images on PTP digital cameras.

1. Introduction

MMPTP is a simple command line program for accessing images from digital cameras that use the PTP standard (Picture Transfer Protocol), formerly known as PIMA 15740:2000. MMPTP should work with all USB Imaging Class 1.0 PTP cameras (interface class 0x6), although I have only tested it with a handful of Kodak point-and-shoot cameras.

Since I started work on MMPTP in 2002, numerous other options for accessing digital cameras under Linux are now included with most serious Linux distributions. I keep MMPTP around because I prefer it's ability to download with names based on photo date rather than the meaningless internal names used by the cameras. Also, because the code is so simple and clear, I can easily diagnose problems. However, if you're a glutton for punishment, or have a non-PTP camera:

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. I welcome any questions, comments or positive suggestions.


2. Installation and Operation

Libusb: MMPTP uses libusb for user space access to USB devices (previous versions of MMPTP had a dedicated kernel module). libusb is included with all serious Linux distributions and supported for Linux, various BSDs and the Unix-based Mac OSs. If your distro does not have an package or if it is not installed, you can download a copy from the libusb web site

Download: MMPTP consists of a single C++ source code file which you can DOWNLOAD HERE.

Compile: Since MMPTP is a simple, single, small file, I have not included a Makefile or config script. It can be compiled with:

	g++ -g -lusb -o mmptp mmptp.cpp

Install: MMPTP compilation results in a single executable file which you can put anywhere. /usr/local/bin is a good place for programs of this sort. Because USB device access through libusb is limited to root users, the setuid bit must be set on the executable:

	chown root:root mmptp
	chmod 4755 mmptp
	mv mmptp /usr/local/bin

Operation: MMPTP has four modes of operation, which can also be listed by invoking MMPTP with no command line options. The camera must, of course, be connected to the USB port and turned on.

mmptp -l
List images that are stored on the camera

mmptp -d
Download all images from the camera. Each image is stored with a filename in yyyy-mm-dd_hh-mm-ss form representing the modification date stored in the camera. MMPTP downloads all images and does not have the ability to download only selected images

mmptp -i
Print information about the camera and its storage devices

mmptp -u
Lists all connected USB devices. This is useful for diagnostic purposes, although ls /proc/bus/usb/devices is more detailed.


3. PTP Implementation Details

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.

USB Basics: libusb provides userspace access to USB devices, making the writing of a kernel module unnecessary. Communication with USB devices is done with blocks of data called URBs (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. Devices have limitations on how long their URBs can be, so if the size of data exceeds the size of a single URB, the data must be broken into chunks and sent with multiple URBs. libusb hids this fragmentation from the userspace program in the functions usb_bulk_read() and usb_bulk_write().

PTP Containers: Messages to and from a PTP camera are sent in "containers", which are simply data messages that have a 12-byte container header. Integers are sent in Intel (little-endian, lsb first) form:

The container type field indicates that the container is one of four different types:

The transaction ID is a unique integer. MMPTP simply keeps a static counter that is initialized to 1 when MMPTP is started and is incremented each time a container is sent to the camera.

PTP Transactions: Operations in PTP are executed as "transactions." There are two kinds of transactons. The first is when no data is exchanged:

However, when data is downloaded from a camera, three containers are exchanged:

PTP Sessions: Before any camera operations can be performed (except quering device info), an OPENSESSION command container must be sent to the camera with a unique session ID. MMPTP uses the Unix time() to obtain a unique integer. When operations are complete, a CLOSESESSION command container is sent to the camera.

PTP Storage: A camera can have multiple storage devices and unique identifiers (handles) for the devices can be acquired with the GETSTORAGEIDS command. Within each storage device, identifiers for the individual files can be acquired with the GETOBJECTHANDLES command. Although cameras can have complete hierarchical file systems with multiple kinds of files, MMPTP simply downloads all files from all directories in all storage devices to the current directory without preserving subdirectories.

PTP Specification: Despite the relative simplicity of the protocol, the formal specification for PTP is a generalized and exhaustive document, and it can be difficult to extrapolate that information into the specific USB protocol. However, for exploiting any features beyond those described in MMPTP, the spec is essential. The current standard is officially available online from the International Industry Imaging Association (I3A) (formed by the merger of the Digital Imaging Association (DIA) & The Photographic and Imaging Manufacturers Association (PIMA)) for a fee (which can be waived for students). There are copies of the standard online in other locations (google "PIMA 15740-2000") and USB Implementors Forum (usb.org) provides a detailed description of how to use the USB Still Image Capture Device Class


4. Version History & Download

Current Version:
Removed session ID from CLOSESESSION operations - caused C875 to give no response
Added kludge to list_images() so multiple invocations do not cause lockup (no response)
Do not download files under 1K to skip unnecessary data files kept on some cameras
Add transaction_send_data() for testing of SET operations

Version 2007.11.07:
Added dynamic sizing of object download buffer to handle large video files.

Version 2006.11.14:
Increased timeout value for read so large video files can be read from the device without timing out

Version 2006.10.27:
Bug fix for no permission mask given on file creation open

Version 2006.10.14:
Initial release of an almost complete rewrite that uses libusb and eliminates the kernel module.

Version 2004.01.04: Fix for objects that have no capture date, such as .mov files and the LABELCTB.LCB and DCEMAIL.ABK data files. mmptp_container::payload increased to 16mb since videos can be larger than the 2mb buffer previously used. Payload size increase required getting mmptp_containers off the heap (dynamic allocation) rather than the stack since the large size caused a stack overflow (segmentation fault).

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.

Ever wonder why you drive on a parkway but park on a driveway?