-- Leo's gemini proxy

-- Connecting to m0yng.uk:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini;lang=en

Reverse Engineering the Baofeng dm1702 codeplug - M0YNG.uk

Created 2020-06-17

Modified 2020-08-03

Tagged

Amateur Radio

DMR

Codeplug


A note from the future that goes at the start


I started working on this nearly two month ago, and I've not had time to get any further with it. So I'm going to post this now, incomplete as it is, in the hopes it might be useful to someone else, or my future self if I get back to it at some point.


Some background


Recently I was too tempted by the seemingly very good price of the Baofeng dm1702 DMR radio.


I paid £65 for the radio, which included delivery, which seemed reasonable considering the features


2m + 70cm

Tier II DMR

Analogue FM

GPS

5w output

Programming over standard USB!


I didn't do enough research though, I just assumed that there would be tools available to help me code it up in Linux, as there are for so many DMR radios, but sadly all I can find right now is some stuff to write data to and from the radio[1], which works, but doesn't help me change any settings like dmrconfig[2] does for my Anytone.


1: https://github.com/OK2MOP/MD1702-tools

2: https://github.com/sergev/dmrconfig/


So I resorted to the official software, which only works in windows, which means I had to kick my offline VM into gear. But oh my, is that software bad, like, really, really bad.


When editing a table of channels, you can't tab between them, it sorts by name so adding a new row goes wherever the default text fits in the sorting order, etc. etc. etc.


It is so bad I decided to break out a hex editor and try to work out what is going on in the codeplug itself.


An initial look


Now, I'm not an expert at reverse engineering anything, so I don't expect to be able to actually do this task…


A first look wasn't promising, there is lots of empty space, lots of `FFFF`, lots of repeating data that doesn't appear to store anything meaningful.


Next I made one small change to the codeplug, and tried to diff it, here I have changed my hotspot frequency from `438.8MHz` to `136.12345MHz` on RX and `444.67899` on TX:


$ diff  <(xxd codeplug-justfreq.data) <(xxd codeplug.data)
833c833
< 00003400: 4523 6113 9978 4644 4000 0000 0000 1100  E#a..xFD@.......
> 00003400: 4523 6113 9978 4644 4200 0000 0000 1100  E#a..xFDB.......

Thanks to a great tip from SP6MR[3] who identified the values as being stored as `unsigned 32bit` I started to get somewhere. Maybe.


3: https://mastodon.radio/@sp6mr/104358359395259741


A change of tense


You might notice a tense change now, as I'm writing this post as I work, mostly to keep notes for myself!


We can also see that changing the TX power level from low to high changes the value after the frequency from `40` to `42`


< 00003400: 4523 6113 9978 4644 4000 0000 0000 1100  E#a..xFD@.......
> 00003400: 4523 6113 9978 4644 4200 0000 0000 1100  E#a..xFDB.......

Changing the timeslot from `2` to `1` and the last chunk changes from `11` to `10`


< 00003400: 4523 6113 9978 4644 4000 0000 0000 1100  E#a..xFD@.......
> 00003400: 4523 6113 9978 4644 4200 0000 0000 0100  E#a..xFDB.......

But wait! changing the colour code from `1` to `2` makes that `11` or `10` into `12` or `02`, so we must be storing the timeslot in one bit, counting from zero


< 00003400: 4523 6113 9978 4644 4000 0000 0000 1100  E#a..xFD@.......
> 00003400: 4523 6113 9978 4644 4200 0000 0000 1200  E#a..xFDB.......

Which makes me wonder about our conclusion for the TX power&hellip;


< 00003400: 4523 6113 9978 4644 4000 0000 0000 1100  E#a..xFD@.......
> 00003400: 4523 6113 9978 4644 0000 0000 0000 1200  E#a..xFD........

Based on that, the `40` is actually `4` for DMR/Digital and `0` for analogue, with the other bit storing the TX power level as `0` or `2`.


We also see another line change much further through the file:


< 0001e020: 000e 0009 000b 0100 000d 0100 0000 ffff  ................
> 0001e020: 000e 0009 000b 0100 000d 0000 0000 ffff  ................

Only one bit seems to change though, so I don't know what it's for (yet?)


Next I changed it back to a digital channel, and set the "TX Contact Name"


< 0001e020: 000e 0009 000b 0100 000d 0100 0000 ffff  ................
> 0001e020: 000e 0009 000b 0100 000d 0005 0000 ffff  ................

It seems that the 6th chunk has some bits that changes to a number referring to the contact (somehow).


Around `0001F000` we see what looks like the name of contacts


0001f000: ffff 5357 204f 6869 6f20 4b34 5553 4400  ..SW Ohio K4USD.
0001f010: 0000 ffa2 7a00 04ff ffff 3331 3035 3537  ....z.....310557
0001f020: 204d 6169 6e00 0000 0000 ff1d bd04 04ff   Main...........
0001f030: ffff 3331 3639 204d 6964 5765 7374 0000  ..3169 MidWest..
0001f040: 0000 ff61 0c00 04ff ffff 4172 6561 2038  ...a......Area 8
0001f050: 2033 3130 3938 0000 0000 ff7a 7900 04ff   31098.....zy...
0001f060: ffff 3331 3020 5441 4300 0000 0000 0000  ..310 TAC.......
0001f070: 0000 ff36 0100 04ff ffff 3331 3120 5441  ...6......311 TA
0001f080: 4300 0000 0000 0000 0000 ff37 0100 04ff  C..........7....
0001f090: ffff 3331 3220 5441 4300 0000 0000 0000  ..312 TAC.......
0001f0a0: 0000 ff38 0100 04ff ffff 3331 3030 2055  ...8......3100 U
0001f0b0: 5341 0000 0000 0000 0000 ff1c 0c00 04ff  SA..............
0001f0c0: ffff 3933 204e 2041 6d65 7269 6361 0000  ..93 N America..
0001f0d0: 0000 ff5d 0000 04ff ffff 3331 3339 204f  ...]......3139 O
0001f0e0: 6869 6f20 5769 6465 0000 ff43 0c00 04ff  hio Wide...C....
0001f0f0: ffff 576f 726c 6445 6e67 6c69 7368 2039  ..WorldEnglish 9

Each Name seems to be 16 characters long, and have something after the text. This repeats for 800 calls, ending at `00023B40`, where we have `FF` until `00024000` where we get `00` until `00025020`.


Changing the call ID causes a change, but it's not clear how the data is stored, it doesn't appear to be `unsigned 32bit`. Here I've changed the ID from `310` to `111`


< 0001f070: 0000 ff36 0100 04ff ffff 3331 3120 5441  ...6......311 TA
> 0001f070: 0000 ff6f 0000 04ff ffff 3331 3120 5441  ...o......311 TA

Based on Andy Valencia's keen eyes[4] the ID is being stored in "endian shuffled order", as can be seen here with the ID `11111111` as `c7, then 8a, and a9`, read each two together, but backwards and we get `0xa98ac7`


4: https://mst.vsta.org/@vandys/104360442782305975


0001f070: 5354 ffc7 8aa9 04ff ffff 3331 3120 5441  ST........311 TA

If we change the ID to `11111113` we have even more confidence we're doing it right


0001f070: 5354 ffc9 8aa9 04ff ffff 3331 3120 5441  ST........311 TA

Structure of a contact


At this point, I think the structure of a contact is:


16 bytes text (Name)

1 byte padding/space (`FF`)

3 bytes in "endian shuffled order" (call ID)

1 byte either `03` (Private Call) `04` (Group Call) or `05` (All Call)

3 bytes padding/space (`FF FF FF`)


Making 24 bytes in total per contact.


Structure of a memory


4 bytes unsigned 32bit (RX Frequency)


4 bytes unsigned 32bit (TX Frequency)


`0` for analogue, `4` for digital.


Add `2` if "RX Only" (`2` or `6`) * Add `1` if Squelch is "Stringent"

A bit for power, Channel Spacing, and "Lone Worker"


`0` for low power, `4` for high power. * If "Lone Worker" `8` for low and `a` for high power. * `0` Low + Narrow spacing (Analogue) OR Low Digital Power * `1` Low + Wide spacing (Analogue) * `2` High + Narrow spacing (Analogue) * `3` High + Wide spacing (Analogue) * `4` High Digital Power * `8` Low + Narrow spacing (Analogue) + Lone Worker OR Low Digital Power + Lone Worker * `9` Low + Wide spacing (Analogue) + Lone Worker * `a` High + Narrow spacing (Analogue) + Lone Worker OR High Digital Power + Lone Worker * `b` High + Wide spacing (Analogue) + Lone Worker

`8` for "Auto Scan Start", or `0` for not (only used if scan list set)


`1` for the "Scan List" reference, or `0` if none


`00` Is for "TX Admit"


`00` "Always" (Analogue or Digital) * `01` "Analogue Channel Free" * `02` "Analogue CTCSS/CDCSS Correct" * `03` "Analogue CTCSS/CDCSS Incorrect" * `08` "Digital Channel Free" * `10` "Digital Color Code Free"

`8` for "Emergency Alarm Indication", `c` if also "Emergency Alarm ACK", `e` if also "Emergency Call Indication", `2` if not "Alarm" but "Call"


`1` for the "Emergency System" reference, or `0` if none


`0` - Doesn't appear to change


`0` - Doesn't appear to change


`0` for "Private Call Confirmed" off, `2` for on. `3` for "Short Data Significance Bit" in "Confirming Mode", `1` if "Private Call Confirmed" is off


`0` - Doesn't appear to change


`0` for Slot 0, `1` for Slot 2, `3` for "Double Capacity Mode"


`0` - `f` for the colour code


`0` for no encryption, `8` for encryption on


`0` - `f` for the Encryption Key reference


3410 offset


`00` - `ff` "GPS System" reference

`00` - `ff` "RX Group List" Reference

`1` - Doesn't appear to change

`0` or `8` ??

`ff ff` "CTCSS/CDCSS Decode" in endian shuffled order (e.g. `70 06` for `67.0`, `41 25` for `254.1`) `ffff` if none.

`ff ff` Same again for Encode.

`1` for VOX, `0` if not

`0` - Doesn't appear to change

`8` for "PTT ID Display", `0` for off

`000` - Doesn't appear to change

`0` if "Talk Around Status" is OFF, `1` if OFF. Add `4` if ENABLED (`4` and `5`)

`000` - Doesn't appear to change

`0000 0000` - Doesn't appear to change


0001e020 offset


3 bytes `0`

`0100`

`0000`

`0`

`0`

`00` - `ff` "TX Contact Name" reference


Make a memory by hand


In theory we know enough to try making a memory by hand now, I'm going to try GB3CG[5], a local analogue repeater on 2m.


5: https://www.grg.org.uk/gb3cg/


145.725MHz TX

145.125MHz RX

โ€˜Jโ€™ 118.8 Hz CTCSS

Analogue

High Power + Narrow spacing

TX admit always

everything else off


I think it will look like this:


0025 5714 0025 5114 0200 0000 0000 0000
0000 1881 1188 1000 0000 0000 0000 0000

I manually edited the codeplug in Okteta and wrote it to the radio, and it half worked!


CTCSS was wrong, it was enabled but had the wrong value, so I changed it on the radio and read back the changes


< 00003410: 0000 1881 1188 1000 0000 4000 0000 0000  ..........@.....
> 00003410: 0000 1888 1188 1100 0000 4000 0000 0000  ..........@.....

When I remove just the RX CTCSS we get


< 00003410: 0000 1881 1188 1000 0000 4000 0000 0000  ..........@.....
> 00003410: 0000 18ff ff88 1100 0000 4000 0000 0000  ..........@.....

When I remove just the TX CTCSS we get


> 00003410: 0000 18ff ffff ff00 0000 4000 0000 0000  ..........@.....

This suggests that I've not got the CTCSS structure quite right, but what's really happened is I've messed up understanding the structure. The one above is actually the revised version, not what I originally had. Byte 3 on this line needs to be something else, and I'd missed it completely so everything was offset.


-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-

๐Ÿ–ค Black Lives Matter

๐Ÿ’™๐Ÿค๐Ÿ’œ Trans Rights are Human Rights

โค๏ธ๐Ÿงก๐Ÿ’›๐Ÿ’š๐Ÿ’™๐Ÿ’œ Love is Love


Copyright ยฉ 2024 Christopher M0YNG - It is forbidden to use any part of this site for crypto/NFT/AI related projects.

Code snippets are licenced under the Hippocratic License 3.0 (or later.)

Page generated 2024-03-24 by Complex 19

-- Response ended

-- Page fetched on Sat May 18 19:00:14 2024