We're hiring!

Permissively-licensed MTP device implementation

Andrzej Pietrasiewicz avatar

Andrzej Pietrasiewicz
May 16, 2019

Share this post:

Introducing cmtp-responder - a permissively licensed Media Transfer Protocol (MTP) responder implementation which allows embedded devices to provide MTP services and supports a core set of MTP operations.

What is MTP?

MTP is an accepted way of exposing storage capability of embedded devices. The host involved in MTP communication is called an MTP Initiator, while the device is called an MTP Responder. This post is about one such MTP Responder.

Although MTP does not enforce underlying transmission medium, a predominant approach is to utilize USB and this post is about MTP using USB for data transport.

Why bother?

There are other ways to expose storage capability of an embedded device, such as USB Mass Storage, but the latter requires an underlying filesystem. On the other hand, with MTP, the exposed contents is not enforced to even reside on any filesystem - it is sufficient for an MTP-compliant device to provide a listing of available files and folders in such a way that each entity can be uniquely identified and to provide means of transferring the entities between a host and the device. These characteristics make MTP attractive for device makers. And indeed, for example virtually all modern Android devices do provide MTP as the primary means to expose their storage capabilities.

Ok, I want one

Here comes the problem we intend to solve: there is no MTP implementation available which would provide at least basic functionality, introduce as little dependencies as possible and whose license would allow using it for various purposes. There is a piece of software called uMTP-responder and while it covers well the first two requirements, it is provided under GPLv3 terms which might be a problem in some applications. On the other hand, software such as buteo-mtp is permissively licensed, but it is written in C++ (might or might not be an issue) and introduces dependency on qt and buteo sync framework.

People have been trying to upstream in-kernel mtp implementation but for various reasons those patches have not been accepted.

Can I have at least the basic functionality, little dependencies and permissive license at the same time?

Yes, you can!

That is exactly the rationale for our cmtp-responder project.

That being said, we haven't started from scratch. There is a permissively licensed (Apache 2.0) mtp-responder implementation in Tizen. It is written in C. While we appreciate the work Tizen has put into creating mtp-responder, we must acknowledge that the original Tizen's code is hard to reuse, because it depends on a lot of Tizen-specific libraries. We forked it to make cmtp-responder depend only on generic libraries (glib-2.0 and systemd). This of course implies removing all the Tizen-specific features. The source code of cmtp-responder can be found here.

The purpose of cmtp-responder is to provide a reusable minimal MTP implementation for everyone to reuse. The long-term goal is to make this project the implementation of choice for a variety of projects, including commercial products, and make this project as feature-complete as possible while maintaining generality and minimal dependencies.

At the time of this writing cmtp-responder supports these basic functionalities:

  • listing the contents of the MTP "store"
  • transferring the contents of the MTP "store" (including subfolders) from the device to the host
  • transferring files and folders from the host to the MTP "store".

In particular, at the time of this writing cmtp-responder does not support renaming the entries in its "store" and editing them in place - you can, however, overwrite an existing item with new contents from the host.

cmtp-responder is designed to be used on top of systemd. It uses underlying storage located in a selected folder of the device filesystem. For interacting with the kernel it uses FunctionFS - please see this post to learn about using FunctionFS.

We have tested cmtp-responder with both Linux and Windows hosts and it seems it is ready to play with it, hence this release announcement.

I want to play with cmtp-responder!

Below are your instructions.

Getting cmtp-responder

The source code is located here. You can clone it the usual way.

Building cmtp-responder

cmtp-responder can be built both for x86_64 and for armhf hosts.

To build for x86_64 issue cmake CMakeLists.txt followed by make.

To cross-compile for armhf you need to have your cross-compilation environment available. Covering how to prepare such an environment is beyond the scope of this post. One of your options is to have multiarch correctly set up. Then you need to issue PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig/ cmake -DCMAKE_TOOLCHAIN_FILE=armhf-toolchain.txt followed by make.

Please note that in both cases you need glib-2.0 and systemd development libraries for the chosen architecture installed. On debian-based systems they are called libglib2.0-dev and libsystemd-dev.

Building FunctionFS USB descriptors and strings

In the post you can read more about FunctionFS USB descriptors and strings. To have cmtp-responder's build system generate those for you you need to add -DCMAKE_BUILD_DESCRIPTORS=1 to cmake invocation. The result will be descs and strs files in the toplevel source directory for USB descriptors and strings, respectively. This will work only when compiling for x86_64 host!

Deploying cmtp-responder

In the systemd directory in the source tree there are example systemd unit files needed to make cmtp-responder work and a scheme file for the gt tool needed to compose the USB gadget. Adapting the instructions found in the post to the needs of deploying cmtp-responder is left as an excercise to the readers.

Comments (2)

  1. maya:
    Mar 20, 2020 at 10:06 AM

    What do you mean by the part "This will work only when compiling for x86_64 host"? This cannot be built for arm device?

    Reply to this comment

    Reply to this comment

  2. Andrzej Pietrasiewicz:
    Mar 20, 2020 at 02:04 PM

    The cmtp-responder's build system, as it is now, builds descriptors and strings binary blobs only when building for x86_64. Note, however, that the resulting binary blobs are the same for both architectures, i.e. they depend on the USB standard rather than particular architecture.

    Reply to this comment

    Reply to this comment

Add a Comment

Allowed tags: <b><i><br>Add a new comment:

Search the newsroom

Latest Blog Posts

Venus on QEMU: Enabling the new virtual Vulkan driver


A step-by-step guide on how to enable 3D acceleration of Vulkan applications in QEMU through the new Venus experimental Vulkan driver for…

Run your own CI pipeline with GStreamer's new monorepo


Maintaining a non-trivial set of GStreamer patches can be tricky. Thanks to the recent move to a single, unified git repo, you can now easily…

Improving test coverage for cameras in KernelCI


Earlier this year, I joined Collabora as an intern to work on improving testing in libcamera and automating it through KernelCI. Having…

A tale of two toolchains and glibc


With the LLVM toolchain seeing increasing development and adoption alongside the older, more established GNU toolchain, projects needing…

An xrdesktop summer of code


This summer, Christoph Haag and I had the pleasure of taking part in Google Summer of Code as mentors for xrdesktop, the Open Source project…

Adding VP9 and MPEG2 stateless support in v4l2codecs for GStreamer


Earlier this year, from January to April 2021, I worked on adding support for stateless decoders for GStreamer as part of a multimedia internship…

Open Since 2005 logo

We use cookies on this website to ensure that you get the best experience. By continuing to use this website you are consenting to the use of these cookies. To find out more please follow this link.

Collabora Ltd © 2005-2021. All rights reserved. Privacy Notice. Sitemap.

Collabora Limited is registered in England and Wales. Company Registration number: 5513718. Registered office: The Platinum Building, St John's Innovation Park, Cambridge, CB4 0DS, United Kingdom. VAT number: 874 1630 19.