I decided to give up on my so called "XiCam" project. The end goal was to control a digital camera via USB from a laptop or Android tablet. When I first attached my camera to my notebook, it appeared that the drivers would only treat the camera as a mass-storage device. When attached to a Windows computer, however, a window pops up asking for permission to install Samsung's Intelli-Studio program, which apparently includes the capability to update new firmware to the attached camera. This told me two things: 1) There is more information which can be received from the camera than appears from Linux systems and 2) the capability exists to update firmware from a host PC.
However, even if I managed to get the firmware from the camera, there is still no guarantee that I'll be able to understand it once I've disassembled the code. And even after spending the effort in figuring it out, then I may still not be able to hack it to control exposure time or trigger the camera via USB. I decided I was better off, for my own sanity, to just buy a different camera when I'm ready to take pictures at that level.
It turns out, without any special settings or using my home made mounting bracket, I can still get decent pictures. Here's a picture I took of Jupiter this morning:
(mis-) adventures in coding. I created this more to document my little pet projects than anything else. It's public in case anyone wants to learn from my experience, or more likely my mistakes!
Showing posts with label usb devices linux. Show all posts
Showing posts with label usb devices linux. Show all posts
Friday, November 8, 2013
Tuesday, November 5, 2013
USB Protocol
When you plug a USB device into a port on your computer (aka the "host"), the hardware signals the USB host controller that a new device has been attached. The host controller then sends a command to the newly attached device via the default endpoint in an attempt to find out what the device is (vendor ID, product ID, product type, etc.). Then it decides what drivers need to be used to work with that device.
I had originally thought, based on the simple configuration, that the only features available to control via USB was access to the data on the flash drive. I now believe that this is simply how the driver treats the device. If I were running Windows, I would be prompted to install the Intelli-Studio software, which is apparently built into the device. If I ever wanted to update the firmware, I would have to do that through Intelli-Studio. This means two things. First, the capability to grab software from the camera exists. Second, the capability to replace the camera firmware via USB also exists.
Just as before, I monitored the USB debugging data from port 2 by issuing the command:
in one terminal window and,
in another. I plugged the camera into the USB port, but no messages were produced until I actually turned the camera on.
The term "Ci:2:000:0" translates to "Input control packet to USB bus 2, device zero, endpoint zero". Eventually I start getting USB events like this,
This submission/callback pair is the device telling the host controller what it is. The first byte is length (0x12=18 bytes), the next is bDescriptorType (0x01=1), USB minor and major version (0x00, 0x02 or "2.0"), The next word contains the device class (0x00), subclass (0x00), protocol (0x00) and maxPacketSize (0x40=64 bytes). The next word contains the vendor and product ID numbers (0x04e8 = Samsung, 0x1306 = ST100 digital camera). Then comes device version (minor, major, in this case 0.0), manufacturer (the '1' here means SAMSUNG, though I'm not sure yet how the USB host controller knows this) and the '2' designates that it is a digital camera. The 3 indicates the serial number. These must be pointers to information strings or something like that. Finally, the '0x01" at the end tells the number of device configurations that are available.
The next submission/callback pair describes the first (and only) configuration.
which corresponds to this:
which corresponds to this:
So what happened to endpoint one? And what does this mean?
0x30=decimal 48, 0x03=index 3, 0x53='S', 0x61='a', 0x6d='m', 0x73='s', 0x75='u', 0x6e='n', 0x67='g', 0x20=' ', 0x44='D', 0x69='i', 0x67='g', 0x69='i', 0x74='t', 0x61='a', 0x6c='l'
0x14=decimal 20, 0x03=index 3, 0x53='S', 0x41='A', 0x4d='M', 0x53='S', 0x55='U', 0x4e='N', 0x47='G', 0x20=' ', 0x20=' '
0x1c=decimal 28, 0x03=index 3, 0x45='E', 0x30='0', 0x32='2', 0x20=' '
So these must be the info strings, although the string "camera" doesn't show up. The first byte must be the string size in bytes (wide char format), the second byte the number of info strings, in this case '3', then the actual strings ("Samsung Digital", "SAMSUNG ", and "E00000000002 ").
$ sudo cat /sys/kernel/debug/usb/usbmon/2u > bus2data.txt
$ tail -f bus2data.txt
The first group of messages appear to be communication between the host controller and the USB port hub,
ffff880137cc2840 2476103001 S Ci:2:000:0 s 80 06 0100 0000 0040 64 < ffff880137cc2840 2476103172 C Ci:2:000:0 0 18 = 12010002 00000040 e8040613 00000102 0301
ffff880137cc2840 2476234892 S Ci:2:007:0 s 80 06 0100 0000 0012 18 < ffff880137cc2840 2476235047 C Ci:2:007:0 0 18 = 12010002 00000040 e8040613 00000102 0301
ffff880137cc2840 2476235204 S Ci:2:007:0 s 80 06 0200 0000 0009 9 < ffff880137cc2840 2476235293 C Ci:2:007:0 0 9 = 09022000 010100c0 00
Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 32 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 0mA
The next pair is the first (and only) interface,
ffff880137cc2840 2476235412 S Ci:2:007:0 s 80 06 0200 0000 0020 32 < ffff880137cc2840 2476235547 C Ci:2:007:0 0 32 = 09022000 010100c0 00090400 00020805 50000705 02020002 00070582 02000200
Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 32 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 0mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 8 Mass Storage bInterfaceSubClass 5 SFF-8070i bInterfaceProtocol 80 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0
ffff880137cc2840 2476235709 S Ci:2:007:0 s 80 06 0300 0000 00ff 255 < ffff880137cc2840 2476235792 C Ci:2:007:0 0 4 = 04030904 ffff880137cc2840 2476235826 S Ci:2:007:0 s 80 06 0302 0409 00ff 255 < ffff880137cc2840 2476235917 C Ci:2:007:0 0 48 = 30035300 61006d00 73007500 6e006700 20004400 69006700 69007400 61006c00 ffff880137cc2840 2476235936 S Ci:2:007:0 s 80 06 0301 0409 00ff 255 < ffff880137cc2840 2476236042 C Ci:2:007:0 0 20 = 14035300 41004d00 53005500 4e004700 20002000 ffff880137cc2840 2476236055 S Ci:2:007:0 s 80 06 0303 0409 00ff 255 < ffff880137cc2840 2476236167 C Ci:2:007:0 0 28 = 1c034500 30003000 30003000 30003000 30003000 30003000 32002000 ffff880137cc2a80 2476236645 S Co:2:007:0 s 00 09 0001 0000 0000 0 ffff880137cc2a80 2476236792 C Co:2:007:0 0 0 ffff8801122bfc00 2477238949 S Ci:2:007:0 s a1 fe 0000 0000 0001 1 < ffff8801122bfc00 2477260196 C Ci:2:007:0 0 1 = 01
0x14=decimal 20, 0x03=index 3, 0x53='S', 0x41='A', 0x4d='M', 0x53='S', 0x55='U', 0x4e='N', 0x47='G', 0x20=' ', 0x20=' '
0x1c=decimal 28, 0x03=index 3, 0x45='E', 0x30='0', 0x32='2', 0x20=' '
So these must be the info strings, although the string "camera" doesn't show up. The first byte must be the string size in bytes (wide char format), the second byte the number of info strings, in this case '3', then the actual strings ("Samsung Digital", "SAMSUNG ", and "E00000000002 ").
Sunday, November 3, 2013
Getting USB Debugging Info from the Linux Command Line.
Not ready to give up on this just yet. Having a closer look at the command line tools that are available.
Ubuntu has a USB debugging feature, which on my installation was running automatically. You can monitor the communication on the various USB buses by,
Here's a sample of the output,
I still don't understand some of the intermediate messages, but I found a resource that explains a couple of them. I made this legend from the description on that webpage.
The upshot is that there seems to be a means to send a variety of commands over the same "configuration". However, I haven't been able to find any resource that describes the commands and arguments that would be recognized by the device. I thought about just sending 256 different command signals to see what comes back, but I think I'd risk sending a factory reset signal or something that might render the camera useless. I'd rather have a camera that doesn't do everything I want but works than have no camera at all.
seans@snowpack:~$ sudo lsusb -v ... Bus 002 Device 005: ID 04e8:1306 Samsung Electronics Co., Ltd Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x04e8 Samsung Electronics Co., Ltd idProduct 0x1306 bcdDevice 0.00 iManufacturer 1 SAMSUNG iProduct 2 Samsung Digital Camera iSerial 3 E00000000002 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 32 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 0mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 8 Mass Storage bInterfaceSubClass 5 SFF-8070i bInterfaceProtocol 80 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Device Qualifier (for other device speed): bLength 10 bDescriptorType 6 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 bNumConfigurations 1 Device Status: 0x0001 Self Powered
seans@snowpack:~$ sudo cat /sys/kernel/debug/usb/usbmon/2u > bus2data.txt
ffff88009bf78240 752186120 S Bo:2:005:2 -115 31 = 55534243 18070000 08000000 80010c4a 01000010 00000008 00000000 000000 ffff88009bf78240 752186154 C Bo:2:005:2 0 31 > ffff880062803c00 752186180 S Bi:2:005:2 -115 8 < ffff880062803c00 752186403 C Bi:2:005:2 -32 0 ffff88009bf78240 752186412 S Co:2:005:0 s 02 01 0000 0082 0000 0 ffff88009bf78240 752186527 C Co:2:005:0 0 0 ffff88009bf78240 752186548 S Bi:2:005:2 -115 13 < ffff88009bf78240 752207425 C Bi:2:005:2 0 13 = 55534253 18070000 08000000 01 ffff88009bf78240 752207452 S Bo:2:005:2 -115 31 = 55534243 19070000 12000000 80010c03 00000012 00000000 00000000 000000 ffff88009bf78240 752207652 C Bo:2:005:2 0 31 > ffff880062803c00 752207718 S Bi:2:005:2 -115 18 < ffff880062803c00 752207778 C Bi:2:005:2 0 18 = 70000500 0000000a 00000000 20000000 0000 ffff88009bf78240 752207788 S Bi:2:005:2 -115 13 < ffff88009bf78240 752207901 C Bi:2:005:2 0 13 = 55534253 19070000 00000000 00 ffff88009bf78240 752698083 S Bo:2:005:2 -115 31 = 55534243 1a070000 00000000 00000c00 00000000 00000000 00000000 000000 ffff88009bf78240 752698157 C Bo:2:005:2 0 31 > ffff88009bf78240 752698391 S Bi:2:005:2 -115 13 < ffff88009bf78240 752698527 C Bi:2:005:2 0 13 = 55534253 1a070000 00000000 00 ffff88009bf78240 754234230 S Bo:2:005:2 -115 31 = 55534243 1b070000 08000000 80010c4a 01000010 00000008 00000000 000000 ffff88009bf78240 754234295 C Bo:2:005:2 0 31 > ffff8801380f9f00 754234315 S Bi:2:005:2 -115 8 < ffff8801380f9f00 754234415 C Bi:2:005:2 -32 0 ffff88009bf78240 754234438 S Co:2:005:0 s 02 01 0000 0082 0000 0 ffff88009bf78240 754234528 C Co:2:005:0 0 0 ffff88009bf78240 754234540 S Bi:2:005:2 -115 13 < ffff88009bf78240 754255617 C Bi:2:005:2 0 13 = 55534253 1b070000 08000000 01 ffff88009bf78240 754255664 S Bo:2:005:2 -115 31 = 55534243 1c070000 12000000 80010c03 00000012 00000000 00000000 000000 ffff88009bf78240 754255906 C Bo:2:005:2 0 31 > ffff880132d0b3c0 754255925 S Bi:2:005:2 -115 18 < ffff880132d0b3c0 754256032 C Bi:2:005:2 0 18 = 70000500 0000000a 00000000 20000000 0000 ffff88009bf78240 754256047 S Bi:2:005:2 -115 13 < ffff88009bf78240 754256155 C Bi:2:005:2 0 13 = 55534253 1c070000 00000000 00
The upshot is that there seems to be a means to send a variety of commands over the same "configuration". However, I haven't been able to find any resource that describes the commands and arguments that would be recognized by the device. I thought about just sending 256 different command signals to see what comes back, but I think I'd risk sending a factory reset signal or something that might render the camera useless. I'd rather have a camera that doesn't do everything I want but works than have no camera at all.
Saturday, November 2, 2013
Okay, so maybe I'm a glutton for punishment or just dumb. But I decided I didn't like the Windows installation after all. Mainly because I didn't feel like dealing with the "bonus" software and the friendly reminders to register for software I haven't used in four years. Also, I think trying to run Ubuntu in a VM was a little too much to ask for the HP. Long story short, I reinstalled Ubuntu 12.04 and made a promise to myself that I wouldn't try to install (or uninstall) any packages related to the USB.
Side note: I could have installed an earlier version of Eclipse using apt-get, but I wanted to go with the Kepler edition, so I downloaded the tarball instead. After installing the Android SDK, I was surprised to find that adb wasn't working. I kept getting file not found errors, even though I could clearly see it was there. Problem was I didn't have 32-bit executable support installed yet. Ran apt-get intall ia32-libs, which installed a whole bunch of crap. But this did, in fact, solve the problem.
Back to business. At first glance it doesn't look like I'll be able to control the camera at the level I want, at least from the USB. Here's what I get from the command line:
(note: I removed all the extra crap related to the host controllers and USB mouse). A more experienced eye might see something else. But what I see is that I'll only be able to access files through USB. I need to do a little research to see exactly what each term means, but I believe "T" designates a device, either root hub or hardware device, "D" designates the USB version, number of available configurations and a few other things I don't know. I get the vendor number and product ID, but I don't understand "Rev" (revision? if so, why zero?). "S" must designate some generic string descriptor. I don't believe the serial number that's given there. "C" seems to designate the start of a specific configuration, not sure what the asterisk is for. "#Ifs is the number of sub-configurations, in this case there's just the one. "I" indicates the sub-configuration and "E" are endpoints. This allows one input (I) and one output (O) bulk endpoint, designed for transferring large amounts of data. Seems like this device is configured at "full speed" (480 MBps).<p>
I did some searching on the interwebs and found that, at least for other digital cameras, any "hacking" of the firmware had to be done via memory chip. I can see how this might work for this camera, since it does seem to do some check of the SD chip when turning it on. As of now there's no firmware provided for this particular model, but I'll keep my eyes peeled.
Side note: I could have installed an earlier version of Eclipse using apt-get, but I wanted to go with the Kepler edition, so I downloaded the tarball instead. After installing the Android SDK, I was surprised to find that adb wasn't working. I kept getting file not found errors, even though I could clearly see it was there. Problem was I didn't have 32-bit executable support installed yet. Ran apt-get intall ia32-libs, which installed a whole bunch of crap. But this did, in fact, solve the problem.
Back to business. At first glance it doesn't look like I'll be able to control the camera at the level I want, at least from the USB. Here's what I get from the command line:
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 002 Device 003: ID 090c:137b Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) Bus 005 Device 002: ID 046d:c52f Logitech, Inc. Wireless Mouse M305 Bus 002 Device 004: ID 04e8:1306 Samsung Electronics Co., Ltd seans@snowpack:~$ sudo cat /sys/kernel/debug/usb/devices ... T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 4 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=04e8 ProdID=1306 Rev= 0.00 S: Manufacturer=SAMSUNG S: Product=Samsung Digital Camera S: SerialNumber=E00000000002 C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 0mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=05 Prot=50 Driver=usb-storage E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms ...
I did some searching on the interwebs and found that, at least for other digital cameras, any "hacking" of the firmware had to be done via memory chip. I can see how this might work for this camera, since it does seem to do some check of the SD chip when turning it on. As of now there's no firmware provided for this particular model, but I'll keep my eyes peeled.
Friday, November 1, 2013
Getting Basic Information from a USB Device
Top-level stuff (no code required)
From command line:
gives manufacturer ID : product ID and one-line description
gives more detailed info about device configurations
sample
From command line:
[strattonsr@bishop]$ lsusb
gives manufacturer ID : product ID and one-line description
[strattonsr@bishop]$ cat /sys/kernel/debug/usb/devices
gives more detailed info about device configurations
sample
T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 2
P: Vendor=04e8 ProdID=6860 Rev= 4.00
S: Manufacturer=SAMSUNG
S: Product=SAMSUNG_Android_SCH-I535
S: SerialNumber=d6190436
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 96mA
I:* If#=0 Alt= 0 #EPs= 3 Cls=06(still) Sub=01 Prot=01 Driver=(none)
E: Ad=81(I) Atr=02(Bulk) MsPS= 512 Ivl=0ms
E: Ad=01(O) Atr=02(Bulk) MxPS=512 Ivl=125us
E: Ad=82(I) Atr=03(Int.) MxPS= 28 Ivl=4ms
C: #Ifs Cfg#= 2 Atr=c0 MxPwr= 96mA
A: FirstIf#= 1 IfCount= 2 Cls=02(comm.) Sub=02 Prot=01
I: If#= 0 Alt= 0 #EPs= 3 Cls=06(still) Sub=01 Prot=01 Driver=
E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=125us
E: Ad=82(I) Atr=03(Int.) MxPS= 28 Ivl=4ms
I: If#= 1 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=01 Driver=
E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
I: If#= 2 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=
E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 2
P: Vendor=04e8 ProdID=6860 Rev= 4.00
S: Manufacturer=SAMSUNG
S: Product=SAMSUNG_Android_SCH-I535
S: SerialNumber=d6190436
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 96mA
I:* If#=0 Alt= 0 #EPs= 3 Cls=06(still) Sub=01 Prot=01 Driver=(none)
E: Ad=81(I) Atr=02(Bulk) MsPS= 512 Ivl=0ms
E: Ad=01(O) Atr=02(Bulk) MxPS=512 Ivl=125us
E: Ad=82(I) Atr=03(Int.) MxPS= 28 Ivl=4ms
C: #Ifs Cfg#= 2 Atr=c0 MxPwr= 96mA
A: FirstIf#= 1 IfCount= 2 Cls=02(comm.) Sub=02 Prot=01
I: If#= 0 Alt= 0 #EPs= 3 Cls=06(still) Sub=01 Prot=01 Driver=
E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=125us
E: Ad=82(I) Atr=03(Int.) MxPS= 28 Ivl=4ms
I: If#= 1 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=01 Driver=
E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
I: If#= 2 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=
E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
Subscribe to:
Posts (Atom)