This page documents the format of the Tytera DM380/Retevis RT-3 codeplug binary file. This is not an official format definition but it has been determined by changing settings with the “CPS RT3” program version V1.30.0.
This specification is used by the rdt2csv conversion utility to export/import codeplugs in the CSV format.
The codeplug, with extension “.rdt”, is a binary file of a fixed size of 262709 bytes. All information inside is allocated at fixed positions.
Data inside the codeplug is divided in records. Every record has its own format. Some records are available in single instance (for example, the record describing the “General Settings”), while other records are repeated (for example, records describing the “Channel Information” have one record for each channel).
Multiple records are always allocated in sequence within the codeplug file. Records are always octet aligned.
For each set of records, the description below will give
- the offset in octets where the first record starts
- the length, in octets, of each record
- the number of records available in the file
The records are divided in fields. Each field represent an edit box, a check box or other field in the editor card. Fields can be as small as one bit or as long as 16 octets.
The field table will give the offset in bits of the field within the record and the length in bits of the field. So, bit #0 will be the MSB of the first octet of the record; bit #7 will be the LSB of the first octet, while bit #8 will be the MSB of the second octet and so on.
Fields are encoded according an encoding type among those specified below.
The BCD (Binary Coded Decimal) format divides a decimal number in digits and codes each digit in a group of 4 bits. In this case encoding is little-endian.
For example, value 12345678 is encoded as 0x78 0x56 0x34 0x12.
Same as BCD, but encoded big-endian.
For example, value 12345678 is encoded as 0x12 0x34 0x56 0x78.
This is a BCD format with exception used only in CTCSS/DCS fields specification.
Tones are of three types: CTCSS (like 127.9) DCS-N (like D155N) and DCS-I (like D155I).
They are coded as two-octets little-endian BCD but with an exception: the two most significant bits of the second octet are to be extracted and used as follow: 00=CTCSS, 10=DCS-N, 11=DCS-I.
Once removed, the remaining BCD value is the number.
CTCSS 77.0 = x70 x07 CTCSS 254.1 = x41 x25 DCS D023N = x23 x80 DCS D023I = x23 xC0
This is normal binary little-endian encoding. If size is less or equal to 8 bits, the field is always contained in a single octet. If the size is greater the 8 bits, then size is always a exact multiple of 8 bits and the field will be octet aligned.
Unicode encoding is a sequence of little-endian 16-bit values.
Although it can host any 16-bit Unicode value, only values <= than 255 (U+00FF) are shown correctly.
The Unicode strings are always allocated to their maximum size; if shorter than their maximum size, unused characters are zeroed.
If the maximum size is used, no zero terminator is available.
Ascii encoding is made of simple one-octet long characters.
The Ascii strings are always allocated to their maximum size; if shorter than their maximum size, unused characters are zeroed.
If the maximum size is used, no zero terminator is available.
Tables supporting multiple records (for example Channel Information, Scan List, Zone Information, etc) have always all records allocated. So, if Channel Information supports a maximum of 1000 entries, in the codeplug file there will always be 1000 entries.
The unused entries are marked with one or more octets that are set to a given value when the record is not used.
When setting the a record to empty, the safest strategy is to set it to its “initial condition”. The “initial condition” is the configuraton used by the “CPS RT3” editor program when creates a new “default1.rdt” empty codeplug.
Some types of records are initialized to zero, while other are initialized to 0xFF. In every case, the Unicode and Ascii strings are to be initialized to zero.
The “Default zero value” in the table below specifies this detail.
When a record is deleted, the CPS RT3 editor does not clear its contents to its initial state but simply sets one or bytes to a prefixed value. Therefore, the decoder must check these octets only to determine whether a record is active or deleted.
The bits to be checked are described in the “deletion markers” table of every record descriptor below.
The tables below describe all the available records and their internal format.
This is a great job!
Thanks for sharing your work.
I see there are still a few uncharted segments.
Here is a small hint on the content:
Incidentally, if you want to use a CS-700 file with the MD-380, open the payload in a hex editor and substitute these bytes.
Offset 125 126 127 128 129 130
CS700 HEX 44 36 38 30 00 FF
CS700 ASCII D 6 8 0 .
MD-380 HEX 44 52 37 38 30 00
MD-380 ASCII D R 7 8 0 .
Hi, Thank you for you software. Btw, could you please add a cmd line param to allow to ignore duplicated entries and export files anyway?
Also I think you are actually checking duplicates on channels list even for deleted channels, I have a codeplug file that I can’t really export as it detects duplicates for every deleted memory (i.e. say I have 200 memories, it detects duplicates on “lines” 201 to 1000) and I can get no exported files 🙁
Ooops, please delete my post above (and this one), I intended to post it at your rdt2csv page instead, I will post it there to keep things on right place… sorry…
This is a terrific resource. Thanks for publishing it. On your Channel Information format, I think your CompressedUdpHdr are reversed.
I had the following errors building on Ubuntu 16.04 LTS, gcc v 5.4.0, x86_64
gcc -O2 -pedantic -Wall -Werror -DNDEBUG -c main.c -o out/main.o
main.c: In function ‘analyzeCommandLine’:
main.c:146:23: error: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Werror=format=]
fprintf (stderr, "Error in parameter %d (%s): separator already defined on a previous parameter with -sc or -tab\n", PARNO, *argv);
main.c:159:23: error: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Werror=format=]
fprintf (stderr, "Error in parameter %d (%s): %s already defined in previous parameter\n", PARNO, *argv, (config->updateMode == modeExport ? "-e" : "-u"));
main.c:163:23: error: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Werror=format=]
fprintf (stderr, "Error in parameter %d (%s): missing .rdt file name\n", PARNO, *argv);
main.c:172:23: error: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Werror=format=]
fprintf (stderr, "Error in parameter %d (%s): out of memory\n", PARNO, *argv);
main.c:198:23: error: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Werror=format=]
fprintf (stderr, "Error in parameter %d (%s): %s\n", PARNO, *argv, err);
cc1: all warnings being treated as errors
Makefile:89: recipe for target 'out/main.o' failed
make: *** [out/main.o] Error 1
I cast parameter 3 (PARNO) to int, as follows (example):
146 fprintf (stderr, "Error in parameter %d (%s): separator already defined on a previous parameter with -sc or -tab\n",(int)PARNO, *argv);
Build was successful. However I can't verify if this breaks any other architecture, or 32bit Linux.
Thanks for your work! Very useful tool.
Thank you for reporting. I published the fixes and tested under a recent x64 linux compiler.
Now sources are published on GitHub at the address https://github.com/Macrocoding/rdt2csv
Vy73 de Davide IZ2UUF
Thanks for posting this information – it was a huge help to me in a project I’m working on.
I’ve mapped out some other areas of the file, including where the ‘Buttons Definition’ and ‘Menu Item’ data are stored. If it’s of use to you or anyone else visiting this page, some details can be gleaned from here:
(As I’m not interested in the ‘Privacy Setting’, ‘Digit Emergency System’, or ‘DTMF Signaling’ areas, I’m just going to leave them alone.)
Thanks for all your work on this. I used it in developing a codeplug editor, . In the process, I found an error in the Digital Contacts deletion marker. Three 0xff bytes at the beginning of the record signify a CallId of 16777215, which is the call id of CallType “all”. The actual deletion marker I saw is two 0 bytes at a bit offset of 32, representing a zero-length contact name. Thanks again.
Thank you for reporting: I have updated this table and the rdt2csv source files as well.
vy73 de Davide IZ2UUF
This had been a very good effort for the time. So that others may not spend time using this method, if you use the TYT CPS V1.30 in Windows 10, you should be able to export files to a spreadsheet, modify them and then import them back in. I have been successful doing this since the “export” and “import” buttons were added to the CPS software. Now if we could just get the Chinese to program it to include all the other nice things that a spreadsheet has we could enjoy getting hundreds of hours back to enjoy playing radio!