Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for cs800d #233

Open
johnhste opened this issue Jul 16, 2022 · 49 comments
Open

Add support for cs800d #233

johnhste opened this issue Jul 16, 2022 · 49 comments
Labels
NewDevice Request for support of a new device

Comments

@johnhste
Copy link

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
Copy link
Author

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 johnhste reopened this Jul 22, 2022
@johnhste
Copy link
Author

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

@hmatuschek hmatuschek added the NewDevice Request for support of a new device label Aug 3, 2022
@hmatuschek
Copy link
Owner

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.

@johnhste
Copy link
Author

johnhste commented Aug 3, 2022

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

@hmatuschek
Copy link
Owner

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.

@johnhste
Copy link
Author

johnhste commented Aug 3, 2022

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
Copy link
Author

johnhste commented Aug 3, 2022

USBMS is the protocol

@johnhste
Copy link
Author

johnhste commented Aug 3, 2022

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

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

@johnhste
Copy link
Author

johnhste commented Aug 3, 2022

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

@hmatuschek
Copy link
Owner

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.

@johnhste
Copy link
Author

johnhste commented Aug 3, 2022

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

@hmatuschek
Copy link
Owner

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.

@johnhste
Copy link
Author

johnhste commented Aug 3, 2022

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

@hmatuschek
Copy link
Owner

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.

@johnhste
Copy link
Author

johnhste commented Aug 4, 2022

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

@hmatuschek
Copy link
Owner

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

@johnhste
Copy link
Author

johnhste commented Aug 4, 2022

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

@johnhste
Copy link
Author

johnhste commented Aug 4, 2022

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

@johnhste
Copy link
Author

johnhste commented Aug 4, 2022

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

@hmatuschek
Copy link
Owner

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

@johnhste
Copy link
Author

johnhste commented Aug 4, 2022

Wow looks like you made a lot of progress

@johnhste
Copy link
Author

johnhste commented Aug 5, 2022

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

@johnhste
Copy link
Author

johnhste commented Aug 5, 2022

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

@hmatuschek
Copy link
Owner

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.

@johnhste
Copy link
Author

johnhste commented Aug 5, 2022

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
   ~ 

@hmatuschek
Copy link
Owner

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.

@johnhste
Copy link
Author

johnhste commented Aug 5, 2022

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
Copy link
Author

johnhste commented Aug 5, 2022

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.

@hmatuschek
Copy link
Owner

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.

@johnhste
Copy link
Author

johnhste commented Aug 5, 2022

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

@hmatuschek
Copy link
Owner

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.

@johnhste
Copy link
Author

johnhste commented Aug 5, 2022

a1 00 03 00 00 00 00 a4
10100001 0 11 0 0 0 0 10100100
i might have had the binary wrong

@hmatuschek
Copy link
Owner

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

@johnhste
Copy link
Author

johnhste commented Aug 5, 2022

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

@johnhste
Copy link
Author

johnhste commented Aug 5, 2022

cs test comm.zip
here is the capture of that cmd

@hmatuschek
Copy link
Owner

I've looked at the capture and the command payload is missing. Maybe sg_raw cannot be used to send those commands.

@johnhste
Copy link
Author

johnhste commented Aug 6, 2022

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

cs800d sg_raw 1.zip

@johnhste
Copy link
Author

johnhste commented Aug 6, 2022

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 ....

@johnhste
Copy link
Author

johnhste commented Aug 6, 2022

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 ..

@johnhste
Copy link
Author

johnhste commented Aug 6, 2022

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

@hmatuschek
Copy link
Owner

Ok, this is a good sign. Now we only need to get it working using libusb.

@johnhste
Copy link
Author

johnhste commented Aug 8, 2022

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.

@johnhste
Copy link
Author

johnhste commented Aug 8, 2022

i forgot to include the usb cap.
id is 6 this time
cs750 cap 1.zip
e

@johnhste
Copy link
Author

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.

@hmatuschek
Copy link
Owner

Looks almost good. Just the length.

@johnhste
Copy link
Author

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.

@johnhste
Copy link
Author

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

@johnhste
Copy link
Author

I forgot to say USB id 9

@johnhste
Copy link
Author

read first block.zip
i got it to work.
usb id 17

jazzcat pushed a commit to jazzcat/qdmr_old that referenced this issue Mar 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NewDevice Request for support of a new device
Projects
None yet
Development

No branches or pull requests

2 participants