Open johnhste opened 2 years ago
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
cs800d write.CSV cs800d read.CSV I captured with windows process monitor a read and write event.
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.
The initial message has Wireshark captures in a zip file. I can redo it separately. if that would help
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.
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
USBMS is the protocol
for the write the filter device is usb.device_address == 11
for the read the filter device is usb.device_address == 15
device manager with radio connected
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.
is there anything I could try on my end. I happen to have the radio and my laptop with me at work today.
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.
thanks. if there is anything I can do to help just let me know.
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.
in this image isn't the wall of usbms response data the read data from the radio
Oh, yes sorry. Looked at the wrong USBMS device.
No problem. I did that when trying to get the message written yesterday.
I have been messing with pyusb and the radio haven't figured out how the message is arcitected.
From my poking around it looks like it is sending the radio something then the radio is responding with information about the requested data
I've created a branch cs800d, where I document my reverse engineering.
Wow looks like you made a lot of progress
would having remote access to a radio connected to my laptop help. we could set that up if you were interested.
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
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.
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 ~
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.
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
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.
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.
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
Ok, then it appears to be much harder to talk to the radio. However, after extracting the codeplug from the captures, it appears like the saved archive files are just one-to-one binary dumps of what is written to the device. So I can reverse engineer the codeplug without needing the device in my hands.
a1 00 03 00 00 00 00 a4 10100001 0 11 0 0 0 0 10100100 i might have had the binary wrong
Oh, yes. You have to generate a binary file from that hex string. Try
echo "a1 00 03 00 00 00 00 a4" | xxd -r -p - request.bin
request.bin.zip this is what i get sudo sg_raw -i request.bin /dev/sg1 ff 2a 00 00 00 00 00 00 00 00 00 00 00 00 47 50 ✔ 37s
transport error: Host_status=0x03 [DID_TIME_OUT]
SCSI Status: Good
cs test comm.zip here is the capture of that cmd
I've looked at the capture and the command payload is missing. Maybe sg_raw cannot be used to send those commands.
got it this morning have to tell it the length of the data packet. and i am telling it that the command is scsi not nvme by the -C1 command sg_raw -C1 -s 8 -i request.bin /dev/sg1 ff 2a 00 00 00 00 00 00 00 00 00 00 00 00 47 50 SCSI Status: Good
filter for usb usb.device_address == 5
on the request message if i use 256 like is in the original capture it does this sg_raw -r 256 /dev/sg1 ff 28 00 00 00 00 00 00 00 00 00 00 00 00 47 50 SCSI Status: Good
No data received
but if i add a few more bytes i get data.
sg_raw -r 260 /dev/sg1 ff 28 00 00 00 00 00 00 00 00 00 00 00 00 47 50 SCSI Status: Good
Received 260 bytes of data: 00 a1 80 03 01 01 01 43 53 38 30 30 44 00 00 00 00 ......CS800D.... 10 00 00 00 00 00 00 44 34 2e 33 2e 30 32 00 20 22 ......D4.3.02. " 20 08 03 07 13 00 00 44 30 30 30 30 30 31 00 00 00 ......D000001... 30 00 00 00 00 00 00 32 33 30 34 44 37 35 32 34 33 ......2304D75243 40 30 30 30 32 00 00 56 32 2e 32 00 00 00 00 4d 53 0002..V2.2....MS 50 2e 33 30 2e 33 34 00 00 00 00 00 00 00 00 05 01 .30.34.......... 60 00 00 00 00 17 00 00 00 00 00 10 08 07 00 4d 31 ..............M1 70 30 30 30 31 30 00 80 40 20 10 08 04 02 01 52 32 00010..@ .....R2 80 2e 30 35 44 00 00 01 00 00 00 00 00 00 00 00 00 .05D............ 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 100 00 00 00 00 ....
same command works on the cs750
g_raw -C1 -s 8 -i request.bin /dev/sg1 ff 2a 00 00 00 00 00 00 00 00 00 00 00 00 47 50 SCSI Status: Good
~ sg_raw -r 260 /dev/sg1 ff 28 00 00 00 00 00 00 00 00 00 00 00 00 47 50 SCSI Status: Good
Received 260 bytes of data: 00 a1 80 03 01 01 01 43 53 37 35 30 00 00 00 00 00 ......CS750..... 10 00 00 00 00 00 00 44 34 2e 33 2e 30 31 00 20 22 ......D4.3.01. " 20 08 05 07 36 00 00 44 30 30 30 30 30 31 00 00 00 ...6..D000001... 30 00 00 00 00 00 00 32 32 30 31 44 35 35 32 34 34 ......2201D55244 40 30 30 30 33 00 00 48 57 55 2d 35 00 00 00 53 34 0003..HWU-5...S4 50 2e 30 30 2e 30 39 00 00 00 00 00 00 00 00 00 00 .00.09.......... 60 00 00 00 00 16 00 00 00 00 00 e0 90 06 00 4d 31 ..............M1 70 30 30 31 30 30 00 80 40 20 10 08 04 02 01 44 32 00100..@ .....D2 80 2e 30 34 00 00 00 00 00 00 00 00 00 00 00 00 00 .04............. 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 100 00 00 00 00 ..
got it to work in a bash script. figured that would be easier than tying to get the python plugin that has almost no docs to work. script_1.zip
Ok, this is a good sign. Now we only need to get it working using libusb.
i found some code on git-hub. it at least seams to be a start on making this work not sure how to modify it to do what we want but shows it is possible. sb.zip i changed the USB vid and pid to the cs750 ones since that is a smaller radio i am using it as my test device.
i forgot to include the usb cap. id is 6 this time cs750 cap 1.zip e
cs750 cap 9.zip testcode.zip i made some progress but a little stumped on how to get it to push the correct amount of bytes. the usb id is 10 on the capture file.
Looks almost good. Just the length.
i am not sure how that is set i have been editing the function writeSettings_smartbend as a test. i set the length to 8. i thought that would do it but it seems to get its length from somewhere else in the code.
to me the command response data looks the same.
i still can't get it to respond with the data block i am expecting.
do you see anything obvious.
testdata.zip
I forgot to say USB id 9
read first block.zip i got it to work. usb id 17
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