-
Notifications
You must be signed in to change notification settings - Fork 2
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
Using gm30 on a UV13-Pro #1
Comments
I don't have a UV13-Pro but yes I'd say it's a fair bet the firmware reports a different variant than the Radioddity GM30. I added the assert statements into the code so I would know right away if the radio I was testing with ever responded differently than it had in the past. If you just want to see if the rest of the code will work you can remove or comment out that assert ( print("FW Variant:", fw_variant); import sys; sys.exit(1) Then run the script and see what the variant value is in the console output. |
Looks like it's a UV15999. Should I replace all instances of P13GMRS with that string? Tried this, and got a little further:
|
There should only be the one instance of |
You can pretty much remove all the export PYTHONOPTIMIZE="True" See this for more information on disabling asserts: |
If you get it to run and you share the output files captured by the |
I've disabled asserts using PYTHONOPTIMIZE as you suggest, and it's got further:
|
Ok so the
Well this is the
You could speed up this process if you capture all the data between the radio and the OEM CPS software during a read or write cycle. Either by capturing the USB traffic to the programming cable or assuming it's just a USB-to-serial adapter by capturing the serial data directly. In the meantime if you want to just skip the general memory for now you can comment out this line and try again: https://github.com/CtrlC-Root/gm30/blob/master/radioddity_gm30/radio_config.py#L56. The only one left is the DTMF settings (i.e. |
Also, I'm sure you're aware of this if you discovered this repository from the CHIRP issue tracker, but this project is very much a work in progress. I can reliably read GM30 radios and I've figured out how most of the settings are encoded in it's memory. Writing to them currently breaks them in a way that I can't recover from (you'll notice the write commands are disabled :D). From what I know of how the OEM market works for these radios Radioddity probably got a copy of the firmware from BaoFeng and made some random changes to "brand" it and/or improve various things. So it's probably pretty similar to the UV13 Pro but it could also be way different. No way to know until someone checks. |
I got this devices too:
But Attached is the result of Hopefully it could help you figure out the difference between this memory map and other (P)15UV devices assuming that GM30 is really about BF UV13 / P15UV... but is that assumption correct? NB: I couldn't get "P15UV-UV13 1.01" to work under wine (the mapping COM1 to /dev/ttyUSB0 doesn't seem to work). |
I have a Baofeng UV-17, and started reverse engineering the protocol but found this repository before I sunk too much time into it (found this by searching for "PSEARCH"). I've captured the messages from the P15UV-UV13 1.01 to the radio (but didn't get to capture the other direction) by using kvm to run windows. The radio responds to PSEARCH with "UV15999" which I assume means "newer than UV15" and you're supposed to use something else to determine the exact model number. After commenting out Then the bootmessage is at address 0xC010 and 0xC020, so I changed the "CONFIG_FILE_ADDRESS" for GENERAL_DATA to 0xC000 and it got a lot further, crashing trying to decode the frequency table. Hrm, now when I dump the memory it's at a different offset (0x4010), and now when I look it's at offset 0x4010 and 0xE010. I powered it off and on again, and now it's at 0x2010. Data at 0x0000-0x1FFF seems static, but the rest seems to change based on the devices whim. Is there something about how this maps memory that the state varies based on what's going on with the device? Do you have any advice before I spend some more time digging into this? |
I don't know for sure so this is all a guess based on what I've seen in the GM-30s (which may not be what other variants do). The configuration data is stored in a flash IC which is divided into equally sized segments (https://github.com/CtrlC-Root/gm30/blob/master/notes/addresses.txt#L1). There are several types of data (https://github.com/CtrlC-Root/gm30/blob/master/radioddity_gm30/radio_config.py#L14) and the last byte of each segment is used to identify what kind of data is stored there (https://github.com/CtrlC-Root/gm30/blob/master/radioddity_gm30/radio_config.py#L101). When you read data from the radio you need to read the last byte of each segment to see what kind of data is stored there (https://github.com/CtrlC-Root/gm30/blob/master/radioddity_gm30/radio_config.py#L95) and then parse it appropriately. The OEM CPS software does this as well (which you can see in USB/serial traces). When the CPS software saves the configuration data to a file it stores it at consistent offsets though (https://github.com/CtrlC-Root/gm30/blob/master/radioddity_gm30/radio_config.py#L43) for convenience. The When you write data to the radio (at least from what the CPS software seems to do) you overwrite it in the segments that are currently storing it, the firmware then does some kind of integrity check, and then the radio reboots. If that integrity check fails the firmware will pick new segments to use (for all data types), initialize them, and update the first bytes of the previous and new segments to mark them appropriately. I suspect this is why I am breaking radios when I try to write data to them; the integrity check is somehow failing, no doubt because I am missing some part of the protocol or data, so the firmware decides to switch to new segments and the data I wrote to the existing ones is ignored. Unfortunately it seems like the way the firmware is initializing the new segments is broken and at that point when the radio reboots the firmware breaks in all kinds of ways. If you go through the firmware upgrade process with the CPS and reinstall the same firmware version it will get further and the data will be valid enough that the radio boots but it's still broken in ways the CPS can't seem to fix (i.e. random icons are enabled on the screen in modes that don't make sense, can't select channels from memory, VFO mode uses wild frequency ranges). I suspect one of the segments (the I was basically working through the radio memory to figure out what every byte represents with the hope that I could start writing the segments I had fully figured out. Unfortunately this doesn't seem to work and I have now broken three of these in ways I can't fix. So I think the next step is to start reverse engineering the firmware, figure out what the post-write integrity check is doing, and go from there. I've kind of put this on hold until I have at least a few contiguous days to look into that because I don't want to stop part-way. So the tl;dr is: I am sure with enough patience you can (1) change something in the CPS (2) write to the radio with the CPS (3) dump the memory segments (either all of them or only the active ones) and (4) reverse engineer how most of it is stored. Unfortunately I think in order to change any of it we need to do it in a way that's valid and I'm not sure how the firmware checks for that. EDIT: It's the last byte in each segment that identifies it not the first. |
Ah that's really interesting. My radio seems to have \xFF in annoying, uninitialised areas which cause the program be upset. Setting the welcome message means it no longer complains about being unable to decode it. Reading the frequency table complains because channel b is set to 0xFF. I extended the validator to allow range(0,256) and now I can read the contents of my radio, and everything seems to decode correctly. So it seems that what you have does generally decode all these different radios, it's just a little strict on validation (which is reasonable). I can fully appreciate having time to work on writing (and it's a bit expensive if you keep bricking radios). When I have a little time I might take a bit of a look and see if I can help out figuring out what's going on, but you seem to have gotten amazingly far already. If/when you get some spare time, let us know and we'll see if we can help out in one way or another. |
I would not be surprised at all to see that each firmware (for each variant) is subtly different. On the GM-30s the welcome message is set by default at least. I would also not be surprised if the hardware is subtly different as well with no easy way to tell the revision from the outside. Looking at the Baofeng UV-17 I can see at least the LCD is different (color versus B/W on the GM-30) and the battery pins are in a different orientation (top versus bottom on the GM-30).
Well that's good to know. Yes the strictness was intended to support reverse engineering so if the firmware changed anything on subsequent reads/writes I would notice it right away and could investigate it. Again I'd expect the data layout and values to differ based on hardware/firmware revision.
Ok, well on a whim I pulled out the GM-30 I disassembled and identified all the ICs. It's using an ARM Cortex-M23 CPU which has a bootloader burned into ROM. The SWD debugging interface is also exposed via pads on the side of the PCB. Assuming there's nothing crazy happening with the PCB layout or the OTP settings in the CPU I expect it should be trivial to dump the entire firmware and get custom code running on it. I strongly suspect the firmware upgrade procedure is really just a thin layer (via USB to serial adapter in the PC cable) over the bootloader upgrade procedure the MCU datasheet mentions. I ordered some adapters so I can hook up a JLink debugger to the SWD interface which should arrive sometime this week. In the meantime I'm going to look into the firmware available from the OEM and see if I can figure out what's in it now that I know at least what instruction set and memory layout should be in use. What would be useful is to have a chart of all the variants somewhere so we can start documenting the differences (i.e. the variant the firmware responds with, any changes to the data layout or the protocol, etc). Not sure if the CHIRP project might have this somewhere or not. It's hard to keep track when the information is spread out across several issues. |
The above linked issue to the |
When dumping using the official program, the result is slightly different. But there is also a difference after 4k: where this tool dumps the First comes this particular header:
Followed by 3x 4k-sized blocks (the ones normally at 0x4000) like Then followed by the Then only the I don't know if the exe interprets the dumps and reorganize them before storing them to file, but if it's not, it could be interesting to consider this alternative dump format. |
The CPS uses a fixed layout for the data while the radios move the sections around in memory every time they are programmed. The layout for the CPS is defined at https://github.com/CtrlC-Root/gm30/blob/master/radioddity_gm30/radio_config.py#L43 and the layout in the radio's memory is detected at https://github.com/CtrlC-Root/gm30/blob/master/radioddity_gm30/radio_config.py#L95. |
I tried that tool and could not get it to work. I'll look at it again if I get stuck. For the moment I'd like to try and dump the firmware using the debug port inside the radio in order to avoid the obfuscation between the CPS and bootloader. |
I'm going to make some significant changes to this repository in the next few days as I start working on this again. I'm going to close this issue in favor of separate issues for each of the variants. |
Hi,
I've got a Baofeng UV13-Pro, and I've managed to get the Python script running using test_read.sh, but when I attempt:
./gm30 read -c config.bin
I get:
I assume this means it's seeing a different variant to that which is expected, is this correct?
Is there anything I can provide to help with diagnosing where the problem lies so that I can use the tool?
The text was updated successfully, but these errors were encountered: