
I recently came into possession of a C22 handheld transceiver from Retevis.
The C22 is an alternative version of the C62, which is believed to be the same (or a very similar) radio, just with different firmware (with its interface using cyrillic script)1. Both C22 and C62 are advertised as analog FM handhelds with some super-duper fancy AI noise cancelling technology. A fellow ham, Ferdy EB5DQ, recently shared a video on YouTube2 showing the C62 with a cryptic “Digital” mode enabled. The mode is undocumented and can only be enabled through the CPS.
Since there is no dedicated integrated circuit that could handle any specific digital mode inside the unit, it is believed that the microcontroller has a direct access to the baseband (in and out). This in turn means the radio is potentially M17 capable, out of the box, without any modifications. This was the main reason to investigate into this topic further. Since the likelihood is significant, I kindly asked the manufacturer for a free sample. My request was rejected, so I bought one with my own funds. C62/C22 are probably rebranded UV58N handhelds, originally released by Chierda Communications Company, Ltd.3
This article shows basic statistical analysis used against an unknown signal to extract its parameters, such as the frame repetition rate and determining the synchronization word(s) used.
Identifying the modulation
Let’s have a look at the RF spectrum first.

It is similar to that of NXDN or M17. Typical, pointy, trapezoidal shape, indicating some narrow n-FSK mode. Now let’s peek at the frequency demodulator output, captured with an SDR. The sample rate is 48kHz.

There’s a distinct “preamble” being a brief period of a continuous wave RF signal, right around the carrier frequency. What follows is obviously a 4FSK signal. Sometimes, there are artifacts – short periods of CW, probably caused by buffer underflows and/or other bugs. Keep in mind that the digimode was not intended to be used by anyone.

Plotting an eye diagram for a section of this raw signal can determine if the applied filtering is not a Nyquist-type (if the signal to noise ratio was high). The only unknown parameter for the eye plot is the “samples per symbol”. Since the sample rate is 48kHz, let’s start with setting it at 10, resulting in 4800 symbols per second (9600 bits per second).

Bingo. Looks good, our assumptions appear to be correct, but if gaussian or raised-cosine filters were used, the intersymbol interference would be minimal, which is not the case. Usually, square root Nyquist filtering is used (e.g. square root raised cosine – RRC). That’s our next best shot, so let’s apply a filter of this kind with varying bandwidth excess (alpha), trying to assess what value gives the best-looking (wide open) eye diagram.

I found out that \(\alpha=0.2\) gives the best eye plot.
The deviation of the outer symbols (+/-3) is 1600Hz.
Finding out the frame rate

Now that we have the baseband waveform captured and filter parameters figured out, let’s calculate the waveform’s autocorrelation values for different time shifts. Since the symbol period is much shorter than the expected frame period, we can use either, filtered or raw waveform.

We see a high, distinct peak at 80ms (corresponding to 12.5Hz). This would match dPMR, but the symbol rate doesn’t fit (different symbol rate).
Determining the synchronization word (syncword)
What we know so far is that the symbol rate is 4800 symbols per second and the frame rate is 12.5Hz. This gives 384 symbols per frame. Let’s plot the standard deviation value for each of the 384 symbol locations. The syncword symbols should stay the same throughout the transmission, giving them very low standard deviation values (again – assuming the SNR is high, as noise affects the measurement; in our case it’s a valid assumption). We can use a simple MATLAB/Octave script here (the input file was generated with GNU Radio, see the article’s last section for details):
fp = fopen("symbol_dump_floats_4800sps.raw", "r");
x = fread(fp, inf, 'float32', 'l');
x = x(150:end); %omit the part where synchronizer isn't sync'd yet
sdev = zeros(384);
for i=1:384
arr = zeros(384, 60);
for j=1:60
arr(i, j) = x(i+(j-1)*384);
end
sdev(i) = std(arr(i,:));
end
plot(sdev(:,1));
xlabel("symbol num");
ylabel("std dev");
The resulting plot is shown below:


We see that the syncword is 24 symbols long (48-bit). The sequence looks like this.

The recovered sequence is {+3, +3, -3, +3, +3, +3, +3, -3, +3, -3, -3, -3, +3, -3, +3, -3, +3, +3, +3, -3, -3, -3, -3, -3}.
GNU Radio flowgraph
GNU Radio is a great tool for all kinds of digital signal processing needs, spanning from basic to most sophisticated. The symbol stream used in this analysis was obtained using the flowgraph shown below.

- Their firmware is not swappable. ↩︎
- https://www.youtube.com/watch?v=_nXv7kfvw2s ↩︎
- https://www.chierda.com/product/uv58-nbdr-uv-dual-band-ham-radio ↩︎
Leave a Reply