Wednesday, October 31, 2018

Decoding STANAG 4285 using KiwiSDR and GNURadio

Below are some examples of STANAG 4285 signals on shortwave picked up by a KiwiSDR located in Scandinavia. These signals were decoded live using the new KiwiSDR GNURadio block gr-kiwisdr, see this blog post, and another GNURadio block I started to work on, called gr-digitalhf:
  • gr-digitalhf contains an adaptive decision feedback equalizer (DFE) and a local oscillator for Doppler correction, implemented in C++. These are separated from the description of the physical layer (synch preamble, frame format, constellation, ...) which is provided in Python. You may have a look at the description of STANAG 4285 here which is an almost literal translation of the standard document.
  • The DFE unscrambles a given symbol, computes a hard decision using the constellation valid for the unscrambled symbol, and then uses the scrambled symbol from the hard decision for computing the error. For this it only needs to have (1) an estimate of the Doppler (=frequency offset) correction and it needs to know (2) if a given symbol is known or unknown. Both, (1) and (2) are provided by the description of the physical layer in Python.
  • Currently the implementation is limited to providing soft decisions. The two final steps, deinterleaving and convolutional decoding, are still missing.
The aim of gr-digitalhf is to make it easy to adapt it to other digital modes based on N-ary PSK/QAM modulation which have a more complicated physical layer compared to STANAG 4285, like, e.g., MIL-STD-188-110A.

STANAG 4285 signal (BPSK unscrambled data, 600 baud) with severe multi-path.
Another STANAG 4285 signal (BPSK unscrambled data, 600 baud)
An example of a 1200 baud STANAG 4285 signal (QPSK unscrambled data)


Monday, October 22, 2018

KiwiSDR GNURadio block

A first version of a GNURadio interface gr-kiwisdr for the KiwiSDR is available on GitHub. It consists of a GNURadio source block which connects to a given KiwiSDR and provides a stream of IQ samples.

At this moment gr-kiwisdr is not yet complete but fully working. Missing items include support for
  • other modes than IQ mode (not sure if this is really useful)
  • user login and non-default AGC settings
  • stream tags containing GNSS timestamps

For connecting to the KiwiSDR websocket server boost.beast is used. Because the available boost versions, e.g., on Ubuntu, are fairly old and boost.beast is a recent addition to boost, gr-kiwisdr contains git submodules for boost.asio and boost.beast (both are header-only libraries).

Any feed-back is very much welcome.
As an example, the preamble cross-correlation of a STANAG 4285 signal is shown below. The two secondary cross-correlation peaks are there because the 80-symbol long STANAG 4285 preamble consists of repetitions of a 31-bit long pseudo-random sequence generated by a LFSR.

Real-time preamble cross-correlation for a STANAG4285 signal.


GRC flow-graph for the plot shown above.

Burst signal monitoring using kiwirecorder.py

Recently burst signals on 7001.8 kHz (center) were observed on KiwiSDRs in Scandinavia. Simimlar bursts can be observed on 4089.8 kHz.

The bursts repeat every 5 seconds and are PSK8 modulated with 2400 symbols/sec. All bursts seem to be identical and have a weak peak in the auto-correlation function at ±215 samples corresponding to 43 symbols.

The bursts were recorded using kiwirecorder.py with the option --squelch-threshold 10 which starts a new file for each burst. The --squelch-tail option is new and can be used to set the time the squelch remains open after the signal is below threshold.

Tuesday, October 16, 2018

STANAG 4285 signal on 442 kHz

A STANAG 4285 signal was detected on 472 kHz on the Kongsfjord KiwiSDR on 472 kHz:

First I thought it was a fake signal but it was also present on the SM2BYC KiwiSDR.

The bitstream obtained after convolutional decoding and deinterleaving consists of frames delimited by the LFSR sequence F1, using the notation of this blog post:

TDoA maps point to somewhere on the coast of Norway: