qdmr icon indicating copy to clipboard operation
qdmr copied to clipboard

Add support for cs800d

Open johnhste opened this issue 3 years ago • 49 comments
trafficstars

another new radio issue i am willing to learn but haven't touched c++ at all. i attached a code plug and some wireshark captures from a windows vm to the radio.

cps radio read and write.zip cs800d.rdb.zip

johnhste avatar Jul 16 '22 03:07 johnhste

as an update to above the cs750 also appears to use the same coms method. I am attaching a capture of that as wel cs750 capture.CSV l

johnhste avatar Jul 21 '22 11:07 johnhste

cs800d write.CSV cs800d read.CSV I captured with windows process monitor a read and write event.

johnhste avatar Jul 22 '22 19:07 johnhste

The process monitor just captures calls to the windows API, I actually need some wireshark captures of the USB traffic to inspect the protocol used by the CPS to talk to the radio. If it is a serial over USB (USB-ACM) type of protocol, the chances are good that I can implement it without having the radio in my hands. However, it will still take some time to do it.

An introduction can be found under

https://wiki.wireshark.org/CaptureSetup/USB#windows

I usually run windows as a virtual machine and then capture the USB traffic at the Linux host. However, you should be able to capture it directly on the windows machine.

hmatuschek avatar Aug 03 '22 10:08 hmatuschek

The initial message has Wireshark captures in a zip file. I can redo it separately. if that would help

johnhste avatar Aug 03 '22 11:08 johnhste

Oh, sorry I haven't looked into it. However, it only contains capures of a USB mass-storage device. Does the radio appear as a usb flash drive? If not, try to select the specific device to capture in wireshark.

hmatuschek avatar Aug 03 '22 11:08 hmatuschek

here is a lsusb with the radio connected lsusb  ✔ Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 003 Device 003: ID 27c6:609c Shenzhen Goodix Technology Co.,Ltd. Goodix USB2.0 MISC Bus 003 Device 002: ID 0bda:5634 Realtek Semiconductor Corp. Laptop Camera Bus 003 Device 006: ID 0483:5720 STMicroelectronics Mass Storage Device Bus 003 Device 004: ID 8087:0025 Intel Corp. Wireless-AC 9260 Bluetooth Adapter Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 002: ID 13fe:6500 Kingston Technology Company Inc. USB DISK 3.2 Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub with the radio disconnected lsusb  ✔ Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 003 Device 003: ID 27c6:609c Shenzhen Goodix Technology Co.,Ltd. Goodix USB2.0 MISC Bus 003 Device 002: ID 0bda:5634 Realtek Semiconductor Corp. Laptop Camera Bus 003 Device 004: ID 8087:0025 Intel Corp. Wireless-AC 9260 Bluetooth Adapter Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 002: ID 13fe:6500 Kingston Technology Company Inc. USB DISK 3.2 Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

new captures for the radio cs800d write.zip cs800d read .zip

johnhste avatar Aug 03 '22 12:08 johnhste

USBMS is the protocol

johnhste avatar Aug 03 '22 12:08 johnhste

for the write the filter device is usb.device_address == 11

for the read the filter device is usb.device_address == 15

johnhste avatar Aug 03 '22 12:08 johnhste

Screenshot 2022-08-03 071642 device manager with radio connected

johnhste avatar Aug 03 '22 12:08 johnhste

Oh, weird. They use the flash-drive protocol to write to and read from the device. This is kind of interesting. To this end, I may only need to read/write files on that drive. Lets see.

hmatuschek avatar Aug 03 '22 13:08 hmatuschek

is there anything I could try on my end. I happen to have the radio and my laptop with me at work today.

johnhste avatar Aug 03 '22 13:08 johnhste

Thanks a lot, it somewhat makes sense to misuse the USB mass storage protocol. It is actually less weird then some other protocols I've seen. I.e., Radioddity uses something like a HID protocol, usually for USB keyboards and mouses. I'll have a look at it.

hmatuschek avatar Aug 03 '22 13:08 hmatuschek

thanks. if there is anything I can do to help just let me know.

johnhste avatar Aug 03 '22 18:08 johnhste

I've had a look at it and I can see how the codeplug is written into the device, reading however still is a mystery. I do not see any significant data being read from the device using the USBMS proto.

hmatuschek avatar Aug 04 '22 09:08 hmatuschek

wireshark in this image isn't the wall of usbms response data the read data from the radio

johnhste avatar Aug 04 '22 10:08 johnhste

Oh, yes sorry. Looked at the wrong USBMS device.

hmatuschek avatar Aug 04 '22 11:08 hmatuschek

No problem. I did that when trying to get the message written yesterday.

johnhste avatar Aug 04 '22 11:08 johnhste

I have been messing with pyusb and the radio haven't figured out how the message is arcitected.

johnhste avatar Aug 04 '22 14:08 johnhste

From my poking around it looks like it is sending the radio something then the radio is responding with information about the requested data

johnhste avatar Aug 04 '22 15:08 johnhste

I've created a branch cs800d, where I document my reverse engineering.

hmatuschek avatar Aug 04 '22 17:08 hmatuschek

Wow looks like you made a lot of progress

johnhste avatar Aug 04 '22 17:08 johnhste

would having remote access to a radio connected to my laptop help. we could set that up if you were interested.

johnhste avatar Aug 05 '22 11:08 johnhste

i was messing with sg_raw in terminal if i send ff 28 00 00 00 00 00 00 00 00 00 00 00 00 47 50 i get 1024 bytes of data all 0

johnhste avatar Aug 05 '22 11:08 johnhste

You have to send an actual command to the device as a request payload. I do not know sg_raw, but there is likely some means to do that. E.g., send

SCSI raw: ff 2a 00 00 00 00 00 00 00 00 00 00 00 00 47 50 Payload: a1 00 03 00 00 00 00 a4

and then send SCSI raw: ff 28 00 00 00 00 00 00 00 00 00 00 00 00 47 50

The device should then return some information about itself.

Btw, I've implemented a python script filtering and decoding the packets in the pcap files.

hmatuschek avatar Aug 05 '22 12:08 hmatuschek

sudo sg_raw -r 1k /dev/sg1 ff 2a 00 00 00 00 00 00 00 00 00 00 00 00 47 50  1 ✘ SCSI Status: Check Condition

Sense Information: Fixed format, current; Sense key: Illegal Request Additional sense: Invalid command operation code

Error 9 occurred, no data received    ~ 

johnhste avatar Aug 05 '22 12:08 johnhste

The first command does not trigger the device to send any data. You have to send the mentioned payload using the -i option. The second command then queries the result from the device. There some data is send back.

hmatuschek avatar Aug 05 '22 12:08 hmatuschek

sudo sg_raw -r 1k /dev/sg1 ff 2a 00 00 00 00 47 50 -i a1 00 03 00 00 00 00 a4  ✔ NVMe Result=0x2 No data received

johnhste avatar Aug 05 '22 12:08 johnhste

Usage: sg_raw [OPTION]* DEVICE [CDB0 CDB1 ...]

Options: --binary|-b Dump data in binary form, even when writing to stdout --cmdfile=CF|-c CF CF is file containing command in hex bytes --cmdset=CS|-C CS CS is 0 (def) heuristic chooses command set; 1: force SCSI; 2: force NVMe --enumerate|-e Decodes cdb name then exits; requires DEVICE but ignores it --help|-h Show this message and exit --infile=IFILE|-i IFILE Read binary data to send (i.e. data-out) from IFILE (default: stdin) --nosense|-n Don't display sense information --nvm|-N command is for NVM command set (e.g. Read); default, if NVMe fd, Admin command set --outfile=OFILE|-o OFILE Write binary data from device (i.e. data-in) to OFILE (def: hexdump to stdout) --raw|-w interpret CF (command file) as binary (def: interpret as ASCII hex) --readonly|-R Open DEVICE read-only (default: read-write) --request=RLEN|-r RLEN Request up to RLEN bytes of data (data-in) --scan=FO,LO|-Q FO,LO scan command set from FO (first opcode) to LO (last opcode) inclusive. Uses given command bytes, varying the opcode --send=SLEN|-s SLEN Send SLEN bytes of data (data-out) --skip=KLEN|-k KLEN Skip the first KLEN bytes when reading data to send (default: 0) --timeout=SECS|-t SECS Timeout in seconds (default: 20) --verbose|-v Increase verbosity --version|-V Show version information and exit

Between 6 and 260 command bytes (two hex digits each) can be specified and will be sent to DEVICE. Lengths RLEN, SLEN and KLEN are decimal by default. Bidirectional commands accepted.

johnhste avatar Aug 05 '22 12:08 johnhste

Create a binary file containing the payload

a1 00 03 00 00 00 00 a4

The file should not contain the hex string but its binary form. Lets call that file request.bin

Then

sg_raw -i request.bin /dev/sg1 ff 2a 00 00 00 00 00 00 00 00 00 00 00 00 47 50
sg_raw -r 1k /dev/sg1 ff 28 00 00 00 00 00 00 00 00 00 00 00 00 47 50

The second call should receive some data.

hmatuschek avatar Aug 05 '22 12:08 hmatuschek

a1 00 03 00 00 00 00 a4 10100001 sudo sg_raw -i request.bin /dev/sg1 ff 2a 00 00 00 00 00 00 00 00 00 00 00 00 47 50  99 ✘  21s 

transport error: Host_status=0x03 [DID_TIME_OUT]

SCSI Status: Good

johnhste avatar Aug 05 '22 13:08 johnhste