Reverse engineering the Puxing PX888K programming format (3: Patch submission and coding style)

The driver I have written has now been accepted by the CHIRP project repository and while I have made sure that it passes the testing suite of the project, as well as that the code adheres to the pep8 guidelines, now the real trials can begin: Actual use. But until the bug reports start rolling in I'm going to feel invincible for a bit. Click-click.

I may have one or two things to say about pep8 though, mostly regarding the line length limit. After a few levels of indentation it starts to put limits of what one can put in string literals, string literals which may be error messages which one would want to understand, and be able to grep for. The Linux kernel coding style documentation has my back on this, or rather, it's probably fair to say that it's the actual source of my thoughts on the matter.

Another thing I think is detrimental when hard-lining at 80 characters is when calling the same or a similar function a lot of times with slightly altered parameters, such as populating a menu.

From a readability standpoint, I think that something like this (please disregard the lazy table formatting):

...is more readable than this:

...as long as the functions are related and have similar signatures. The first params are all in the same column, as are the seconds, and so on. But if some of the params are string litterals you will soon be at the end of your line length allowance, especially since you're likely to do it at some level of indentation.
At some point it would make more sense to move the data away from the code, and instead just loop over a two-dimensional array or a map, calling the desired functions. I guess that would be the standard answer to these concerns actually: You are not supposed to have that many magic numbers (or magic strings as it were) in your code! I don't disagree with this, but it does depend on whether or not the rest of the project uses this method.

Another point is how much code can be shown at once, the first example takes four rows of my editor to display, allowing me to see more code above and below it, compared to the second example that requires twelve rows. And this in the days of widescreen monitors too. Of course, if you have one of those tiltable monitors I envy you, although all of the one's I've used have had a narrow enough viewing angle that my left and right eye ended up seeing slightly different colors which irritated me to no end.


Reverse engineering the Puxing PX888K programming format (2: Making sense of the data)

I have found out that the reverse engineering was the easy part. It should however come as no surprise, since if communications protocol and data format are simple, and they are, the whole thing becomes a iterative process of changing a single setting to a new value, and diff the old communications dump against the new, to see what bits have changed.

Using jpnevulator to listen in on the data transfer between the stock software and the radio, the program can listen to multiple serial ports at the same time, and neatly display which port sends what when. This way the back and forth between the stock software and the radio can be easily viewed and the protocol is quickly figured out. There is a short initial handshake in the beginning, followed by either reading or writing the whole image in chunks of 64 bytes.
The protocol, but just as much an image to break the text
The next step was to implement a few scripts that could play the part of the radio, but dump the memory written to an image file, instead of writing to the radio each time, and reverse engineer from the snooped data which contains the communications commands which, we are no longer interested in. The script can also read from an image file, making it possible to poke at the bits and see what changes in the stock software. Functions for reading and writing to the radio are also implemented, which is useful since the stock software does not cover all settings available on the radio. The scripts are available on github.

After a data communications failure, it also became apparent that there are features not available in the stock software I had, as well as the radio: Something went wrong and I found myself with a radio with a locked keypad. It turns out that this is a feature rather than a bug, and a newer version of the stock software includes the possibility of changing this setting. The new software version also makes the feature Relay without disable tail available, which I have no idea what it does, and I can't find it documented anywhere. The closest thing I have found when searching is that it may enable or disable Squelch tail elimination, but I don't have the equipment to test this feature currently.

Another setting that is poorly documented is Wait time which can be set to 0.3, 0.5 or any integer in the range 1-12. I do not know what it is waiting for. It does not seem to be any of backlight timeout, keypad lock timeout, or any delay regarding when PTT ID or other data signals are sent. Possibly it could have something to do with when the battery save functionality sets in, but I don't know how to test this reliably. A bit of keyword searching lead me to a French forum which hinted at, and is corroborated with my own following tests, that it is how long it waits in before it resumes scanning, when using carrier based scanning.

A bigger challenge, the "but" continuation of the "easy" in the beginning of this text is writing a CHIRP plugin. It would be easy enough to pour data between a csv file tailored for this radio, and this radio only, and the binary image would be easy. It is a different matter entirely to fit this into a system that also needs to cover how other radios work, and what their features are. But the point of doing this is to make it possible to copy settings between radios that would otherwise be each programmed by their own software platform, all incompatible with each other. I can certainly get behind that kind of endeavor. Another part is that doing this project with the goal of writing a CHIRP plugin is probably the best way to have it reach other users of this particular model and have them benefit.


Reverse engineering the Puxing PX888K programming format (1: The joy of soldering)

A while ago I bought a Puxing PX888K VHF+UHF radio HT. Like for many other radios, it's possible to change the configuration from a computer. Like for many others, the program is severely lacking in polish and only available for windows. To its defense though, it works more or less as good (or bad) running it through wine on Linux, as it does on windows. But it offers nothing like export/import CSV, or even though the channel list looks like an Excel sheet, it is not possible to copy or paste rows.

The perhaps default open-source radio programming software distribution CHIRP does not at this time support this radio model. Maybe, if I'm successful in my work, that can be changed.

First things first. To decode the data, I need to get the data. To get the data I need to listen on the communication wires, so a junction box was built. Given that I'm building with what I find in my parts bins, rather than routing a proper board and ordering parts, the final result does perhaps look more grown than designed. ...And that's not really false marketing.

junction box and schematic junction box back
The amount of switches comes from the fact that one of the serial cables I use for snooping is straight, while the other is a null modem cable, as I wrote, I'm working with what I have here.
Also, I want to keep my options open.

Since the radio is programmed with 5V signals, and the snooping ports work at RS232 levels, a level converter is needed. Again, lots of switches for connectivity options, and mixing SMT and through-hole devices oh my.

level converter and
simplified schematic
level converter back
A quick gander with the logic analyzer and a few attempts to read shows that the data is transmitted as regular serial 9600,8,N,1

action shot
To be continued...