Turn your Linux computer into a huge Android USB Accessory

Google is promoting it’s Arduino-Like hardware to test and prototype with USB accessories. Meanwhile you are either waiting for your USB-Host board or deciding if you even want to get one at all. At that point we would like to share a way of how to write your first “Hello World” application using your Linux Desktop/Laptop (we use Ubuntu …).

Your Desktop/Laptop probably has a USB host controller. This opens you all doors to write accessory applications using “libusb”. We have written some C code as a template that let’s you act as Accessory on Linux side.


You can use it for instance to benchmark the data throughput and do all other kinds of crazy stuff. (Did I just hear “use your Nexus S as RFID reader”?)

Java Code to follow …


to compile on Ubuntu install the following packages:
apt-get source libusb
apt-get install libusb-dev
apt-get install libusb-1.0-0-dev

And compile using the line
gcc simplectrl.c -I/usr/include/ -o simplectrl -lusb-1.0 -I/usr/include/ -I/usr/include/libusb-1.0

The Java example can be found here.
Please note that the example is very rudimentary as well as threading just temporarily. During the next weeks we are going to require a better and more robust example which will be followed by some post with source code.

62 thoughts on “Turn your Linux computer into a huge Android USB Accessory

  1. Colin Madere

    Need to add a libusb_close(handle); where you close the interface before re-opening connection to device in accessory mode. For me, this was required or the I/O would not work (though the new connection and interface claiming would work with no errors).

  2. Manuel Di Cerbo Post author

    Thank you very much for your fix Colin. Seems I missed that command :) so your deinit looks like the following snippet?

    static int deInit(){
        if(ctrlTransfer != NULL)
        if(ctrlTransfer != NULL)
        if(handle != NULL)
            libusb_release_interface (handle, 0);
        return 0;
  3. Oscar

    Installed the source & libraries in Ubuntu 11.04 as described.

    gcc simplectrl.c -I/usr/include/ -o simplectrl -lusb-1.0 -I/usr/include/ -I/usr/include/libusb-1.0

    when compiling as above I get this:

    simplectrl.c: In function ‘deInit’:
    simplectrl.c:119:5: error: ‘ctrlTransfer’ undeclared (first use in this function)
    simplectrl.c:119:5: note: each undeclared identifier is reported only once for each function it appears in

    1. Manuel Di Cerbo Post author

      Hey Oscar

      you are completely right, I made a mistake in my latest edit…
      I re-corrected it now :)


      1. Rajaraman

        The first part in the mainPhase says:
        response = libusb_bulk_transfer(handle,IN,buffer,16384, &transferred,0);
        Should the second parameter be OUT instead of IN ?

  4. Manuel Di Cerbo Post author


    Okok I know I owe you the java code :D Got a bit lost :)
    It’s really nothing much and I will upload it tomorrow.


    1. Manuel Di Cerbo Post author

      Hey Michael

      I will work on the java code and upload it as soon as possible. I wanted to do that the other week but found that large parts of the code won’t work anymore with the example since I made changes to it. I wanted to create a “virtual” Android NFC scanner and then transfer data over USB and emulate the key presses to enter the code (via uinput). The code follows strictly the ADK guidelines from the official documentation. However, I will try to fix everything and make a tar today :)


  5. Colin Madere

    Manuel, sorry for my delayed response! As the other commenter noted, the transfer freeing was not valid for the posted code (I assumed it was part of a block you did not publish intentionally).

    The other thing I did was to sync up the buffer sizes on both sides and simplify things a bit to assume one command per read/write due to how Android ADK manages the data flow (or so I’m told…. I’m guessing your code is based on something that was not ADK-based, either pre-ADK work or non-Android?)

    As for the other commenter asking for the Java side, as Manuel stated, I just used the Android documentation and the ADK Sample application to somewhat easily create the Java Android side of things.

  6. alon

    I have some code that use libusb to control the pos printer on the android tablet, i can find and claim the usb device , but when i use ioctl function to send data to the usb device, it return the error epipe

    1. Manuel Di Cerbo Post author

      the code of the java part is heavily based on the sdk example and therefore it makes no sense to apply GPL. Use it under your own license :-)

  7. Mike Lenczewski

    I would just wait for these mobil phones and tablets to be usb hosts. making a micro controller be a USB host is pretty tough. Host mode on linux, is much better to make a userspace driver out of libusb. There is also pyusb too.

    I have a droid bionic, host mode, libusb, keyboard and mouse support, etc, etc, are all good to go out of the box. I even installed that pyusb on the python that seemed to be preinstalled. worked like a charm. Now to get cracking on some other projects

    1. Manuel Di Cerbo Post author

      Agree 100%, also a gadet should by design be powered by the mobile device. Makes a lot more sense :)

  8. Myriam

    Hello,I want a confirmation if adding the libusb in my embedded device, will it support Android Open Accessory?

    1. Manuel Di Cerbo Post author

      Hello Myriam

      Depending on what you want to try. So is your embedded device host? It will require a host USB driver. You can either use libusb or another USB library, or even make your own implementation using ioctl and such. In my opinion libusb will probably be the easiest.

  9. Myriam

    Thx for your reply Manuel,
    My embedded device is a gateway, i want to add support of Open Accessory on it.
    i think if i have to choose Libusb, i will try the cross compilation for my gateway..
    then i have to develope my own application to communicate with Android.
    So it is importante to me to know if libusb is the suitable solution ..

  10. Yasmine

    Hello, the program seems to work fine but i have the pb :
    Input/output error.
    what can i do to solve the issue ?

  11. gowda

    when i run ./simplectrl i get “Problem acquireing handle”. The android device is connected and i have modified the accessorry setup to start a sample app. how am i supposed to launch/run the simplectrl program?


    1. kushi

      Hi gowda,
      Please help, let me know?
      I just installed the packages & on Ubuntu that was running on virtual box on my windows. I installed the USBTest app on my Google nexus S, And just connect both with usb. But nothing happen on both.. :(
      I am not sure what can i do.. Is there any think i do for communicating with both?
      Please tell me the process How you did please….?

  12. MKP

    thanks for the example but I have a question – what USB mode (mass storage/media player/kies and optional debug mode) should be set on the phone when running this code? I tried kies and media player (with and without debugging enabled), but I’m getting LIBUSB_ERROR_PIPE durign “Setting up accessory” on my linux. I’m using Fedora 16 and Samsung Galaxy S with Android 2.3.6. and uploaded future.usb jar and xml file. Or maybe you have some other idea what can be going wrong?
    Thanks in advance for your help

    1. Manuel Di Cerbo Post author

      Hmmm this could be permission related. Does ADB work with your phone?

      All the best

  13. MKP

    Yes, ADB works normally (on standard user account too). I tried of course running it on Linux as a root, but nothing changed. I’m also waiting for a response from Samsung whether this should work or they had removed something when they was making the 2.3.6 release for my phone (it would be a bad surprise).

  14. Geetha


    I get the below error when I try to to run your program.

    Input/output error.
    Error during main phase.

    Thank you! Appreciate your help!

  15. Geetha


    I got the app working on Nexus. I was trying to do the same on Acer 3.2. But write was returning with “No such device” error. Can you please let me know the reason.

    Thank you!

  16. David Henning

    This is a great series of posts. Keep ‘em coming!

    Before I forget, your source has a typo in line 77. You transposed two letters in “Nexus” so the error link fails.

    I did get your code to compile and run (with sudo) on my Ubuntu machine without any problems. I tried it with two Android devices. The first was a Motorola Atrix running Android 2.3.6 and the second was a Motorola Zoom tablet running Android 3.1.

    On the Atrix, I get the LIBUSB_PIPE_ERROR that others have mentioned. I’m wondering if my Android OS (2.3.6) is too old.
    Pipe error.

    The Zoom gave this output:
    Verion Code Device: 1
    Accessory Identification sent
    Attempted to put device into accessory mode
    Error setting up accessory
    On the Zoom itself, I got that error dialog saying “No installed apps work with this USB accessory. Learn more about this accessory at neuxs-computing.ch” I assume I need to have an app that is waiting for communication with the ‘simplectrl’ app running on my Linux box.

    Did I miss something or have you written a simple test app that I can build for Android that will talk to ‘simplectrl?’

    1. Manuel Di Cerbo Post author

      Hi David,

      Thank you for your post :)

      You can find the Java part here:
      link http://android.serverbox.ch/wp-content/UsbTest.tar.gz

      For some devices you need to adjust VID and PID. Others do not implement the accessory libraries although they claim to be of version 2.3.6+/3.1+ since the OEM decided not to ship this part with the device.

      All the best

      1. kushi

        Hi Manuel,
        Please help, let me know?
        I just installed the packages & on Ubuntu that was running on virtual box on my windows. I installed the USBTest app on my Google nexus S, And just connect both with usb. But nothing happen on both..
        I am not sure what can i do.. Is there any think i do for communicating with both?
        Please tell me the process How you did please….?

  17. PavloT

    Who has problem with:

    check what libusb version installed into your system.

    Seems for libusb1.i686 following define:
    #define IN 0×85
    must be changed to
    #define IN 0×81

    Works on Fedora-16.

  18. David Henning

    Okay, I’m getting close.

    I have the Java ‘UsbTest’ app installing via the Eclipse debugger on my Motorola Xoom, which I now realize is actually running Android 4.0.3. However, to get it to compile, I had to comment out two lines of “@override.” before ‘public void onClick()’ and ‘public void onRun().’ Is that an indication I have something wrong in my SDK setup?

    Anyway, I forged ahead with those lines commented out.

    Then, I modified the parameters in the call to setupAccessory() in simplectrl.c to use the same manufacturer/model/version specified in the accessory-filter.xml file in the Android application.

    I also modified the accessory PID/VID numbers to match those of the hub on my Linux machine in the call to libusb_open_device_with_vid_pid() in setupAccessory().

    So, now, when I run simplectrl, the UsbTest app opens on my Xoom asking me to send a number to the accessory. However, simplectrl reports a LIBUSB_ERROR duing the mainPhase() function.

    Any thoughts?

    By the way, this whole thing is a gift from above. I’m happy to make a donation to your cause as this tutorial has saved me a lot of hours on the learning curve.

    1. Manuel Di Cerbo Post author

      Hey David!

      Glad you liked the tutorial :) We try to give back to the open source community as good as possible :)

      Regarding Overrides:
      This has to do with your host systems’ Java version and is not related to the current Android version.

      Regarding the Error:
      I recall that there was a bug with the code in the main phase (simplectrl.c) which was pointed out in the comments. Anyhow, you should verify if the IN endpoint is the correct one, check this using lsusb -v : on your host machine. There you should also see the interfaces.

      Also it would be probably much simpler if you switch to some python script utilizing a wrapper like pyusb.

      All the best

  19. David Henning

    I tried your suggestions, both looking up the endpoint with ‘lsusb -v’ and also trying pyusb. I think that my problem is not a code thing, but something in my Linux configuration because both the C code and the pyUSB fail at the same point (the bulk transfer) and in the same way. My only other theory is that there is a problem in the Android Java code.

    I found that my Xoom provides two IN endpoints designed for bulk transfers, 0×81 and 0×83. Both lsusb and some pyUSB programs I wrote confirmed this. I tried both of these endpoint addresses, but I always ended up getting a LIBUSB_ERROR_IO when it goes to do the bulk transfer.

    When I enabled the debug messaging with libusb, I get a message like:

    libusb:error [submit_bulk_transfer] submiturb failed error -1 errno=2

    Looking at the source code of libusb, that results from a failed ioctl() call down into the lower levels of the kernel.

    So, after much reading about USB and Python, I wrote a pyUSB program that follows similar steps to simplectrl and I pretty much see the exact same behavior. The control transfers to setup the accessory mode work great, the app wakes up, but the bulk transfer fails giving the following “Resource Busy” error trace:
    Traceback (most recent call last):
    File “bulk2.py”, line 70, in
    data = ep_in.read(16)
    File “/usr/local/lib/python2.6/dist-packages/usb/core.py”, line 301, in read
    return self.device.read(self.bEndpointAddress, size, self.interface, timeout)
    File “/usr/local/lib/python2.6/dist-packages/usb/core.py”, line 647, in read
    self._ctx.managed_claim_interface(self, intf)
    File “/usr/local/lib/python2.6/dist-packages/usb/core.py”, line 112, in managed_claim_interface
    self.backend.claim_interface(self.handle, i)
    File “/usr/local/lib/python2.6/dist-packages/usb/backend/libusb10.py”, line 519, in claim_interface
    _check(_lib.libusb_claim_interface(dev_handle, intf))
    File “/usr/local/lib/python2.6/dist-packages/usb/backend/libusb10.py”, line 403, in _check
    raise USBError(_str_error[ret], ret, _libusb_errno[ret])
    usb.core.USBError: [Errno 16] Resource busy

    I am in the process of setting up a couple newer Linux boxes anyway, so I will try this code on them, probably in the morning. (It’s 2AM here.)

    While I don’t quite have things working, I did manage to learn a whole lot about USB fundamentals, python, pyUSB and libusb, which will all be very valuable.

    If I get the pyUSB working. I will post it. I will be ugly Python probably. I’m new at that also.

  20. Dave Henning

    I tried another machine. This one is running Ubuntu 12.04 where before I had been running 10.10. The fact that my pyUSB and libusb code behave pretty similarly makes me wonder if I need to change something about the Java code or the Android device. I might see if I can get my hands on another device just to compare or upgrade the Android OS on my phone.

    Like I said before, in both cases the failure is pretty catastrophic in that after the failure of the bulk transfer attempt, the Android device does not even show up in lsusb.

    1. Manuel Di Cerbo Post author

      Hello Dave!

      That really doesn’t sound good. I can’t really think of any possible solution at the time. Maybe try another device with another Android version. Also, did you claim the correct USB interface before trying to transfer?

      All the best and hope you will be able to solve the issue

  21. David Henning

    Here is my pyUSB code that should talk to the USBTest app.

    It behaves just like simplectrl.c, which unfortunately on my machine reports a Resource Busy error when it goes to do the bulk transfer.

    If anyone wants to try this and let me know it works for them, I would appreciate it.

    Sorry, for the sloppy python. This is my first python program.

  22. Chris

    Hey there, thank you very much for your work.

    I am trying to get this running on my nexus s android 4.04, and it is erroring out where it tries to grab the handle of when it changes to accessory mode. The lsusb shows the change from 18d1:4e22 to 18d1:2d01. After it fails, the phone stays in accessory mode, and I tried to just change the initial handle acquire to use the accessory pid, yet it fails. On the phone, it recognizes a connected accessory and indeed opens the app. Any ideas?

    1. Manuel Di Cerbo Post author

      Hey Chris,

      One thing you could try is to induce a artificial delay after it re-enumerates, maybe this would help. Only a guess though :)

      All the best

  23. Chris

    I believe it does have artificial delay in the form of the 5 tries and sleep(1), right? Also, did you end up adding the libusb_close(handle)?

  24. Chris

    I was also wondering, how did you get the endpoint addresses? I mean, how did you know which ones to use?

    1. Manuel Di Cerbo Post author

      Hello Chris,

      I think there are only two Bulk Enpoints, one for IN transfers and one for OUT transfers if I remind correctly. As soon as I have a chance I will look into the matter.

      All the best

  25. Chris

    There are indeed one set of endpoints that we should use. If we have adb debugging on, there are 2 sets in fact, the first is for our use and the second set is for adb

  26. Jeno


    First of all it is a very useful tutorial. Thanks a lot for it.

    I faced with a problem when switch to the accessory mode.
    After the following line:
    the usb device is umounted and libusb_open_device_with_vid_pid() was failed.
    If I remount the device manually before calling libusb_open_device_with_vid_pid(), it works fine.

    Have anybody a suggestion, what can cause this? What do I wrong?
    How can I avoid the umount after switch to accessory mode?

    I’m working on Windows 7 and using Ubuntu via Virtual Box (I have tried it on Mac OS directly as well).
    I tested the code with Samsung Galaxy S III and Huawei Ascend G300.
    The code is modified so maybe it casuses the problem.



    1. zljun

      HI, jeno
      Have you maken Virtualbox remount the android device after it enters into accessory mode?
      Or do you have any approch to avoid Virtualbox unmounting the android device?

  27. Tai

    Thanks for your tutorial !
    It’s worked for me …
    My devices :
    HTC Wildfire 2.3.7
    Ubuntu 12.04


  28. PLP

    Great tutorial. I almost got it to work. First of all my phone is a Huawei G300 (custom ROM 4.0.3).
    The java app from this site does not start. I created another app. I just want to get the intent… I can take it from there :). But my app is not started when I run simplectrl.

    I get the error mentioned before
    Input/output error.

    However, my phone says it changed to Accessory mode and after an “lsusb -v” I can confirm this (according to Google the VID = 0x18d1 and PID = 0x2D01 means Accessory mode).

    On the phone I can also see a message
    - the message “title” matches what I send from the PC (simplectrl)
    - instead of the actual message I get “res/drawable-hdpi/ic_sysbar_home” (this is the actual text)
    - the message has 2 buttons: Cancel and, here is the wierd part, “res / drawable / ic_sysbar_ime.xml” (this is what is actually written on the button).

    When I press the “res / drawable / ic_sysbar_ime.xml” button it promts for a web browser.

    Any ideas ?
    Thank you very much.

  29. PLP


    Quick update. From time to time when I run simplectrl on my android I see that it crashes my system UI.
    Also one question. Shouldn’t
    response = libusb_control_transfer(handle,0×40,52,0,0,(char*)manufacturer,strlen(manufacturer),0);
    response = libusb_control_transfer(handle,0×40,52,0,0,(char*)manufacturer,strlen(manufacturer)+1,0);

    Thank you

  30. PLP

    Final update… maybe it might help someone.
    I realized that the simplectrl does indeed turn on Accessory mode.
    The problem was in my android phone. It seems that it did not want to show me the “open with” message box (alot of crashes with wierd messages). The crash happened only when Manufacturer, Model and Version number matched (PC vs application).
    I ended up flashing CyanogenMod 10 and now everything is working.

    Thank you once again for this great tutorial.

    1. Manuel Di Cerbo Post author

      Hey there,

      Thank you so much for sharing! I am glad everything works now with CM, some manufacturers just don’t cut it with the software part :)

      All the best for you and the project

    2. Kushi

      Hi PLP,

      I just compiled the andorid code in my nexux s running on android 4.1.2.
      i downloaded the simplectrl.c. And i compiled the C code with instructions above. (Actually am running in Mac with Virtual Machine as Ubuntu 12.0 . ) But when I run that file with ./ it is showing some thing like “Proble acquiring handle”. Not sure is this is an error? what I did wrong? Can you please tell me , How can i communicate with my Mac with andorid device?
      Please help me out… :(

      Thanks you Inadvance.. :)

  31. Andrei

    Hello! I tried to run your java code and build it against Google API 4.2.2 and got some errors :

    Description Resource Path Location Type
    The method getInstance(Context) is undefined for the type UsbManager UsbTest.java /UsbTest/src/ch/serverbox/android/usbtest line 153 Java Problem

    The method getAccessory(Intent) is undefined for the type UsbManager UsbReceiver.java /UsbTest/src/ch/serverbox/android/usbtest line 27 Java Problem

    Against which API do I need to build this ?
    Thank you in advance!

    1. Kamalkumar

      Hi Andreid,

      I think your issue is related with the kind of package you are using.
      I guess you are using the java source code provided in this post itself.
      If you are building against API 2.3.4 you can straight away use that code but from Honeycomb 3.1 onwards you need to use different package. I mean to say instead of com.android.future.usb package you have to use android.hardware.usb package and accordingly the function call will also change.
      To be more specific (after importing android.hardware.usb package)

      fd = UsbManager.getInstance(getApplicationContext()).openAccessory(a).getFileDescriptor();

      will change to something like

      fd = mUsbManager.openAccessory(a).getFileDescriptor();

      Kindly go through this tutorial for further information Choosing the Right USB Accessory APIs.

      Hope this will help…
      All the best !

  32. Dang Nguyen

    Hello,! I have two problems with this example code.
    When I run code on PC, it’s successful to connect to android device. Than app on android device start to rung for sending data to PC. But after connected to android device, the program on pc dies immediately and prints the message

    >$ sudo ./simplectrl
    >Verion Code Device: 2
    >Accessory Identification sent
    >Attempted to put device into accessory mode
    >Interface claimed, ready to transfer data
    >Input/output error.
    >Error during main phase

    It seems that the program ended when try to receive data from android device
    response = libusb_bulk_transfer(handle,IN,buffer,16384, &transferred,0);

    Do you have the same error? Please help me fix this problem!

    2. Can’t run program on pc several times without unplug usb cable
    If I run program on pc, it’s successful to connect to android device than and die immediately. When I try program on pc again, it can’t connect to android device if I don’t unplug and plug usb cable again. Program exit with error message
    >$ sudo ./simplectrl
    >Problem acquireing handle
    How can we fix this problem?
    Thank you in advance!


Leave a Reply

Your email address will not be published. Required fields are marked *


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>