# Reading and writing codeplugs

The major feature of the command line tool is certainly the ability to read and write codeplugs from and to the device. The majority of the action happens automatically. Like the detection of the radio. If something goes wrong, an error message will be written to `stderr`. A more detailed logging can be enabled by passing the `--verbose` flag.

To read a codeplug, the `read` command is used. The codeplug can be stored in several formats. The human readable extensible codeplug format (YAML) and as a binary memory dump of the codeplug memory on the device. `dmrconf` detects the format based on the file extension or by means of an additional flag. The latter is particularly important if the read codeplug should be written to `stdout` for piping it to another program for further processing.

    dmrconf read codeplug.yaml

Will simply read the codeplug from the detected device and stores it in the extensible codeplug format in the file `codeplug.yaml`. The format was detected by the file extension `yaml` which refers to the extensible codeplug format using YAML.

To store the memory dump of the codeplug memory of the radio, the file extension should be `dfu`.

As mentioned above, it is also possible to dump the decoded codeplug to `stdout` allowing to pipe the codeplug into another program for processing. This can be done by omitting the output filename. Then, however, the output format is not specified anymore. In this case, one the explicit format flags `--yaml` or `--bin` must be used to specify in which format the codeplug should be written. These flags can also be used to store a codeplug in a particular format in arbitrarily named files.

    dmrconf read --yaml | python my_script.py

This example reads the codeplug from the connected device and decodes it. The decoded codeplug is then piped to the python script `my_script.py`.

It is also possible decode binary codeplugs that has been read from the device earlier and stored as a memory dump (i.e., in a `dfu` file). This step is actually the second step automatically performed during reading. When reading a codeplug, in a first step the memory dump of the codeplug is read from the device. In a second step, the read binary codeplug is then decoded and dumped in a human readable format.

The `decode` command performs that second step. To do that, it needs two additional information: The radio type, from which this codeplug was read and the format to write the decoded format to. Like for the `read` command, the latter can be passed by the output filename extension or via an additional flag.

    dmrconf read codeplug.dfu
    dmrconf decode --radio=uv390 codeplug.dfu codeplug.yaml

This example performs the same actions like a simple `read` command (assuming a TyT MD-UV390 is connected). It first downloads the binary codeplug. This time, the memory dump is stored in a binary form (`dfu` file). The second command then decodes the binary codeplug into the extensible codeplug format (`yaml` file), assuming that the binary codeplug stems from a TyT MD-UV390.

Since version 0.8.1, it is now also possible to decode some manufacturer binary codeplug files as they are produced by the manufacturer CPS. To signal the decode command to treat the file as a manufacturer CPS file, you need to pass the `-m` or `--manufacturer` and the `--radio` option. The latter tells the `decode` command the format of the file. That is, the call

    dmrconf decode -m --radio=uv390 manufacturer_cps_file.rdt codeplug.yaml

Will decode the manufacturer CPS file `manufacturer_cps_file.rdt` assuming it is a file generated by the CPS for the TyT MD-UV390. Like for the normal decoding the output format must be specified either by file extension or flag.

Under normal circumstances, it makes no sense to first read the binary codeplug from the device and then decoding it in a separate step as the read command will do that for you.

However, if there is a bug in `dmrconf` that gets triggered by your codeplug on the device, the binary codeplug is an invaluable resource for debugging the application. Consider filing an issue at the bug tracker and include the binary codeplug as an attachment.

If you like, you can also send me your codeplug directly. I'll keep it confidentially.

To write a codeplug into the device, the `write` command is used. The codeplug can be read from several formats. The extensible codeplug format (`yaml` file) as well as the old table based format (`conf` file). It is not possible to write binary codeplugs without decoding them first. Like for the `read` command, `dmrconf` will detect the format based on the file extension or by passed flags.

    dmrconf write codeplug.yaml

This example will write the codeplug stored in the extensible codeplug format in `codeplug.yaml` to the connected device. Before writing the codeplug to the device, the connected device gets detected and the codeplug gets verified.

If the verification step fails, one or more error messages are written to `stderr` describing the issue with the codeplug. One verification step is the check whether all channel frequencies are within the frequency limits specified by the manufacturer. The latter check can be disabled using the `--ignore-frequency-limits` flag.

There are also some flags controlling the assembly of the binary codeplug. When the `--init-codeplug` flag is set, the codeplug will be generated from scratch using default values for all options not explicitly specified in the codeplug file. This might be used to initialize a brand new radio. However, any changes made to the radio are lost.

When this option is not set, the codeplug gets encoded and written in a two-step process. First the current binary codeplug is downloaded from the radio. Then the codeplug file is used to update the binary codeplug. The result is then written back to the device. This ensures that all settings made in the radio are kept, unless they are explicitly set in the codeplug file.

The `--auto-enable-gps` and `--auto-enable-roaming` flags will tell `dmrconf` to enable the GPS or roaming feature whenever any of the programmed channels use the GPS or a roaming zone. (This depends also on the ability of the radio.)

The aforementioned verification of the codeplug file can also be performed separately using the `verify`. This command also needs to know against which radio the codeplug should be verified. The radio must be specified using the `--radio` option.

    dmrconf verify --radio=d878uv codeplug.yaml

This command will verify the codeplug stored in `codeplug.yaml` in the extensible codeplug format against an AnyTone AT-D878UV. Like for the `write`, any issues are written to `stderr`.

Like for the `write` command, the verification can be altered using the `--ignore-frequency-limits` flag.

Is is also possible to perform the encoding step of the codeplug separately. This can be done with the `encode` command. Like for the `verify` command, the `encode` command also needs the radio for which the codeplug should be encoded. The input format of the codeplug is again specified by either the file extension of the codeplug file or by flags.

    dmrconf encode --radio=opengd77 codeplug.yaml codeplug.dfu

This call will encode the codeplug `codeplug.yaml` specified in the extensible codeplug format for a radio running the OpenGD77 firmware and stores the resulting binary codeplug in `codeplug.dfu`.

Like for the `write` command, the encoding can be controlled using the `--auto-enable-gps` and `--auto-enable-roaming` flags.