summaryrefslogtreecommitdiff
path: root/md
diff options
context:
space:
mode:
Diffstat (limited to 'md')
-rw-r--r--md/writeup/webusb_example.md219
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)