diff options
| author | FreeArtMan <dos21h@gmail.com> | 2019-07-30 17:02:16 +0100 | 
|---|---|---|
| committer | FreeArtMan <dos21h@gmail.com> | 2019-07-30 17:02:16 +0100 | 
| commit | 66acb55a10e3cbb1a38153f709cfc31fab5a5c27 (patch) | |
| tree | 749dc20dab73fb25341d6f5953acba7fdfa419cd /md | |
| parent | ccee69fc7c27b6b5f938b17eeb25d24d8edfde7f (diff) | |
| download | md-content-66acb55a10e3cbb1a38153f709cfc31fab5a5c27.tar.gz md-content-66acb55a10e3cbb1a38153f709cfc31fab5a5c27.zip  | |
WebUSB post second revision. Not yet ready for publishing
Diffstat (limited to 'md')
| -rw-r--r-- | md/writeup/webusb_example.md | 219 | 
1 files changed, 219 insertions, 0 deletions
diff --git a/md/writeup/webusb_example.md b/md/writeup/webusb_example.md new file mode 100644 index 0000000..a98216b --- /dev/null +++ b/md/writeup/webusb_example.md @@ -0,0 +1,219 @@ +title:WebUSB example +keywords:linux,webusb,usb,usbmon,ch341,pl2101 + +# WebUSB example +## Hardware requirements + +Modern browser have some cool API's like WebUSB that allows from browser  +acces USB stack. Here is a steps to try it out. As internet doesnt have +any basic example of stuff how things works, here is all info needed to +make first WebUSB requests running. On most basic devices out there. +USB serail interface is cheap to get on any online shop here is quite  +common chip models CH341,PL2303.  + +TODO +* describe how request decoded add py example code +* describe initialisation phase +* Describe how to send data on CH341 +* Describe how to recieve data on CH341 +* sniffed usbmon traffic desctiption + +## Gathering info + +Linux provides utilities to list all usb device connections.  + +``` +lsusb +``` + +Output will be something like: +``` +Bus 002 Device 027: ID 1bcf:0007 Sunplus Innovation Technology Inc. Optical Mouse +Bus 002 Device 026: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port +Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub +``` + +Our PL2303  device is connected and is on a bus 2.0 + + +When USB device is connected to bus linux logs some information. When USB +device is there in dmesg you can find out some info. +``` +dmesg | tail +``` +Most important part is to find device bus id in our case it is "2-1:1.0" + +``` +[190298.876894] usb 2-1: USB disconnect, device number 26 +[190298.877195] pl2303 ttyUSB0: pl2303 converter now disconnected from ttyUSB0 +[190298.877245] pl2303 2-1:1.0: device disconnected +[190301.871959] usb 2-1: new full-speed USB device number 28 using xhci_hcd +[190302.012793] usb 2-1: New USB device found, idVendor=067b, idProduct=2303, bcdDevice= 3.00 +[190302.012799] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 +[190302.012802] usb 2-1: Product: USB-Serial Controller +[190302.012804] usb 2-1: Manufacturer: Prolific Technology Inc. +[190302.013632] pl2303 2-1:1.0: pl2303 converter detected +[190302.014426] usb 2-1: pl2303 converter now attached to ttyUSB0 +``` + +## Setting up udev + +Use usb bus id to unbind driver. If its not done there will be no permission +error, or device busy error. Use one of lines to unbind device driver by usb  +bus id. + +``` +echo "2-2:1.0" > /sys/bus/usb/drivers/pl2303/unbind +echo "2-2:1.0" > /sys/bus/usb/drivers/ch341/unbind +``` + + +If you have other errors related to not able to connect to device then or no +permsision. Add file to udev rules in /etc/udev/rules.d directory + + +/etc/udev/rules.d/88-hello-usb.rules + +Here is examples of USB ids for PL2303 and CH341 +``` +SUBSYSTEMS=="usb", ATTR{idVendor}=="067b", ATTR{idProduct}=="2303", MODE:="0666" +SUBSYSTEMS=="usb", ATTR{idVendor}=="1a86", ATTR{idProduct}=="7523", MODE:="0666" +``` + +As rulles is not loaded after file are created or new entries are added. +Need to restart udev daemon so new rulles are added to current running rulles. + +``` +udevadm control --reload-rules && udevadm trigger + +``` + +## Programming + +Most of modern browsers provide javascript API for accesing USB its called +WebUSB API.  + +### Get request to access device  + +First thing that is needed to do is request devices. Popup windows to select +device will appear. + +```js +serial.requestPort = function() { +    const filters = [ +      { vendorId:0x067b, productId:0x2303 }, //cp210 +      { vendorId:0x1a86, productId:0x7523 }, //ch341 +    ]; +    return navigator.usb.requestDevice({ 'filters': filters }).then( +      device => new serial.Port(device) +    ); +  } +``` + +### Recieving data + +To recieve date control request need to be created. +Request constructed according to suported protocol that may differ +from device to device. + +PL2303 and CH3421 have totaly different interfeises. Steps to initialise +device also differs.  + +```js +serial.Port.prototype.vendorRead = function(value) { +    console.log("Read val="+value); +  	return this.device.controlTransferIn({ +      'requestType': 'vendor', +      'recipient': 'device', +      'request':serial.VENDOR_READ_REQUEST, +      'value':value, +      'index':0, +    },1); +  }; +``` + +### Sending data + +```js +serial.Port.prototype.vendorWrite = function(value,index) { +    console.log("Write idx "+index+" val = "+value) +  	return this.device.controlTransferOut({ +            'requestType': 'vendor', +            'recipient': 'device', +            'request': serial.VENDOR_WRITE_REQUEST, +            'value': value, +            'index': index, +    }); +  }; +``` + +### CH341 chip request table + +| | | +| --- | --- | + + +### PL2301 chip request table + +| Request name | value | +| --- | --- | +| CP210_VENDOR_WRITE_REQUEST  |  | +| CP210_VENDOR_READ_REQUEST   |  | +| CP210_GET_LINE_REQUEST      |  | +| CP210_SET_LINE_REQUEST      |  | +| CP210_SET_CONTROL_REQUEST   |  | +| CP210_BREAK_REQUEST         |  | + + +## Sniffing USB traffic + +Linux provides infrastructure to see USB transactions. Its allow to  +debug or sniff some USB trafic, so in case if there is some unknown +parts how USB initialisation is working, you have change to figure out +by seeing sequenc of commands sent to USB interface. + +### Setting usbmon + +``` +mount -t debugfs none_debugs /sys/kernel/debug +modprobe usbmon +ls /sys/kernel/debug/usb/usbmon +``` + +``` +T:  Bus=01 Lev=04 Prnt=43 Port=03 Cnt=02 Dev#= 45 Spd=12   MxCh= 0 +D:  Ver= 1.10 Cls=ff(vend.) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1 +P:  Vendor=1a86 ProdID=7523 Rev= 2.54 +S:  Product=USB2.0-Serial +C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr= 96mA +I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=02 Driver=ch341 +E:  Ad=82(I) Atr=02(Bulk) MxPS=  32 Ivl=0ms +E:  Ad=02(O) Atr=02(Bulk) MxPS=  32 Ivl=0ms +E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=1ms +``` + +``` +cat /sys/kernel/debug/usb/usbmon/1u > /tmp/1.mon.out +``` + +### Sniffed traffic example + +## Thx + +[daGrevis](https://github.com/daGrevis) - gave tips about using await/async in js   +[jurgenzz](https://github.com/jurgenzz) - help solving await/async issues   +[#developers.lv](https://developers.lv) - having patiens for listening to js nonsence from js-newbie   + +## Source + + + +## Links +[https://www.mankier.com/8/usbmon](https://www.mankier.com/8/usbmon)   +[https://www.kernel.org/doc/Documentation/usb/usbmon.txt](https://www.kernel.org/doc/Documentation/usb/usbmon.txt)   +[https://elinux.org/images/1/17/USB_Debugging_and_Profiling_Techniques.pdf](https://elinux.org/images/1/17/USB_Debugging_and_Profiling_Techniques.pdf)   +[https://developer.mozilla.org/en-US/docs/Web/API/USB](https://developer.mozilla.org/en-US/docs/Web/API/USB)   +[https://developer.mozilla.org/en-US/docs/Web/API/USBDevice](https://developer.mozilla.org/en-US/docs/Web/API/USBDevice)   +[https://github.com/ultibohub/Core/blob/master/source/rtl/ultibo/drivers/pl2303.pas](https://github.com/ultibohub/Core/blob/master/source/rtl/ultibo/drivers/pl2303.pas) +[https://github.com/torvalds/linux/blob/master/drivers/usb/serial/pl2303.c](https://github.com/torvalds/linux/blob/master/drivers/usb/serial/pl2303.c) +[https://www.beyondlogic.org/usbnutshell/usb1.shtml](https://www.beyondlogic.org/usbnutshell/usb1.shtml)  | 
