Monday, November 4, 2019

Update on the OQPSK signal from Chicago

This is an update to this and to this blog post.

(Updated 11/5/19)

While before the offset between the "X" and "Y" bit streams was 458,748 bits, recently this offset has changed (but see below) to 65,536=216 bits, i.e., a non-pseudo-random bit stream can be obtained as follows:

  m = 65536;
  b = bitxor(bY(1:end-m),~bX(1+m:end)); # (*)

Recently this signal was observed on 12190 kHz with quite a lot of selective fading, so the coherent demodulation is not perfect.

12190 kHz QQPSK demodulation

The bit stream obtained by using (*) shows a repeated pattern of 7 bits (0011101):

fixed bit patten

It can be easily verified that this bit pattern is generated by an LFSR:
   bn = bn-1 + bn-3 ,   (**)
where "+" denotes XOR. In fact the offset is the same as before. The fact that a LFSR-generated sequence is left after (**) is an artifact of using 1/7 original offset. This also makes the additional descrambling mentioned below obsolete.

At another time the same type of signal was observed on 10790 kHz, this time carrying data. Again the offset between the "X" and the "Y" bit streams was 216 bits. Using the LFSR (**) the resulting bit stream obtained from (*) can be descrambled, and then closely resembles the one found before: there are "frames" of 48-bits and the bits come in pairs, so in one given frames there are 24 "independent" (but see below) bits.

bit stream in terms of 48-bit frames

Treating each line in the above plot as one "symbol" it was found that 16 symbols occur with (about equally) high frequency and all other symbols with very low frequency:

48-bit symbol frequency
For now let's treat the symbols with low frequency as transmission errors (they might not be that).

The 16 symbols, when arranged in order, show an interesting pattern: in each group of four symbols 1) the last group of three bits is repeating, and 2) the first 7 groups of three bits are the same. In the table below the last number in brackets indicates the number of times a given symbol has occurred.

i= 1: 000_100_000_000_000_100_001_000 (497)
i= 2: 000_100_000_000_000_100_001_010 (494)
i= 3: 000_100_000_000_000_100_001_100 (531)
i= 4: 000_100_000_000_000_100_001_111 (487)

i= 5: 000_101_011_011_000_111_111_000 (470)
i= 6: 000_101_011_011_000_111_111_010 (561)
i= 7: 000_101_011_011_000_111_111_100 (536)
i= 8: 000_101_011_011_000_111_111_111 (506)

i= 9: 001_100_011_101_101_010_011_000 (494)
i=10: 001_100_011_101_101_010_011_010 (522)
i=11: 001_100_011_101_101_010_011_100 (495)
i=12: 001_100_011_101_101_010_011_111 (538)

i=13: 010_011_111_001_111_110_110_000 (508)
i=14: 010_011_111_001_111_110_110_010 (495)
i=15: 010_011_111_001_111_110_110_100 (485)
i=16: 010_011_111_001_111_110_110_111 (482)

The sequence of these symbols is not entirely random: the last three bits determine if the following symbol is in the group 13-16, 9-12, 5-8, or, 1-4:

Distributions of symbols following the one indicated in the subplot title.

This might indicate a form of Trellis coding, because not all possible transitions between symbols are allowed.

Any information about this kind of error correction is very much appreciated.

STANAG 4285 from FUX, Reunion

STANAG 4285 CARB (Channel Availability and Receipt Broadcast) messages from FUX, Reunion received on a KiwiSDR located in India:

gr-digitalhf screenshot








Sunday, October 27, 2019


Recently, some people have observed a DPGS signal on 318 kHz. Existing software displays its location as Shepelevskiy (Leningrad Oblast) ; however KiwiSDR TDoA shows a different likely location.
318 kHz DGPS

Friday, October 11, 2019

4800 symb/sec QPSK signal on 10165 kHz

... noted today on European KiwiSDR. This signal is likely from the same origin as the one described in this blog post and this blog post.

However this time the data stream seems to be pure pseudo-random, at least for all methods of analysis I have tried.

Update 10/12: The signal still carries pseudo-random data

Using GNURadio a perfect constellation diagram can be obtained:

QPSK constellation diagram

... except during times when the signal fades:

QPSK symbols vs. time

The used GNURadio flowgraph, adapted from this tutorial, is shown below.

GNURadio flowgraph

Wednesday, September 18, 2019

>3 kHz wide bursts around 6300 kHz

This morning, a number of >3kHz wide bursts were noticed around 6300 kHz on a KiwiSDR in Europe. 

Below, one such burst is shown in terms of 576 symbol frames (5 samples/symbol sampled at 24 kHz -> 4800 symb/sec). The color indicates abs(z): (1) there are 6 individual bursts grouped together, and (2) a repeating sequences of symbols is present in each burst.

one 4800 symb/sec burst consisting of 6 individual bursts

The repeating sequence of symbols, extracted from multiple bursts, is shown below. This sequence consists of 64 BPSK symbols

It can be verified that the first 63 of these bits are generated by an LFSR and that the last bit balances the number of 0s and 1s, i.e., including the last bit there are 32 0s and 32 1s.

Top: the color indicates arg(z); bottom arg(symb) for a few of the frames shown on top.
Each burst starts with the same, 64 symbol long preamble that is immediately followed by the known sequence of symbols described above.

Unfortunately, the signal suffered from selective fading, so the modulation of the other parts of the bursts could not be determined.

Sunday, September 8, 2019

8-ary constellation bursts at 12800 bps data rate (2)

This is a follow-up to this blog post.

With the help of a number of bursts were recorded (the -T option helps to save disk space) and then decoded using gr-digitalhf.

3-channel mode

At the time of observation, the signals were active on fA=3320 kHz, fB=3314 kHz, and fC=3329 kHz only, and the schedule was [(A,B,C), (A,B,C), ...]. On each frequency two consecutive bursts were observed, with the preambles exactly 2 seconds apart.

Shortened preamble for the 1st burst

The preamble for the 1st burst on each frequency is shortened w.r.t. nominal STANAG 4539 preamble:
S4539 preambles for the 1st and 2nd burst

The payload data is mostly the same within each (A,B,C) cycle

Arranging the 104 WALSH-encoded payload di-bits in frames of size 13×16, the plots below were obtained and the following observations can be made:
  • Except for the 2nd frame (marked in red) all other bits are the same within each (A,B,C) cycle
  • The parity of the 1st frame (marked in magenta) and of the 2nd frame is even
  • The parity of the 11×16 bits in frames 3-13 is even
  • Analyzing the bit stream obtained by concatenating 1st frames (omitting repetitions) it can be found that the rank deficiency for k=16 is 5, i.e, besides the one parity bit there are four more bits being used for error correction
  • Similarly the rank deficiency for concatenated 2nd frames at k=16 is 7. As the 1st two bits of each 2nd frame seem to be zero this might indicate a similar error correction for the 1st and the 2nd frame.

1st (A,B,C) cycle

2nd (A,B,C) cycle

Content of the 2nd frame

The 1st 8 bits of the 2nd frame seem to contain a (6-bit wide) counter:
  • the period of this counter is 30, i.e., after 5 (A,B,C) cycles, corresponding to 100 seconds, the sequence of count values repeats
  • the start times for the bursts mod 100 seconds repeat after 30 bursts as well
  • this counter is related to mod(number of the current UTC second, 100), see the plots below
  • the following is pure speculation: the current difference between TAI (International Atomic Time) and UTC (Coordinated Universal Time) is 37 seconds, so this counter×2 may be related to mod(TAI seconds, 100)

1st 8 bits of the second frame; the black areas indicate missing data

6-channel mode

The same observations are true when the system is using 6 HF channels, e.g.,
     fA1=4024 kHz, fB1=4030 kHz, and fC1=4039 kHz and
     fA2=4784 kHz, fB2=4790 kHz, and fC2=4799 kHz
The sequence of transmissions in this case was
     [(A2+C2), (A1+B1), (A2+B2), (B1+C1), (B2+C2), (A1+C1)], ...
i.e., two signals were active at the same time. The channels A1,B1,C1 were broadcasting two bursts each and A2,B2,C2 one burst. Also here the same payload data is used for all 12+6 bursts in one cycle, and the 2nd frame in each packet carries a number related to the time of transmission as shown above.

Chirp sounder measurements with KiwiSDRs (2)

Using the recent work on KiwiSDR waterfall recording (see kiwiclient/ it becomes possible to search for chirp sounder signals in KiwiSDR waterfall data, continuing the topic from this post. connects both to the 'SND' and the 'W/F' websocket streams. The 'W/F' stream contains sequence numbers for each waterfall line which are used to synchronize the waterfall to the audio data. These sequence numbers can also be used to attach to each waterfall line a corresponding GNSS time tag obtained from the 'SND' stream. As the waterfall data can arrive before or after the audio data, both are combined in a third thread using python Queues for thread-safe communication.

About half an hour of waterfall data was recorded on the AB1LD KiwiSDR using the highest KiwiSDR waterfall speed which turns out to provide waterfall data about for each SND frame, i.e, each 512/12000 seconds. Thanks to the owner for setting up this KiwiSDR and allowing unrestricted access!.

Then the recorded waterfall data (saved in a .npy formatted file) was rebinned in time to 1024/12000 second bins and exported as a .png file. Switching from python to octave, a search for chirp sounders was performed for chirp rates from 80  kHz/s to 130 kHz/sec in steps of 1 kHz/sec: for each chirp rate and for each start time the content of the waterfall bins was summed up along the corresponding line (Hough transform).

Two chirp sounders were found, each having a repetition rate of 720 seconds (12 minutes) with chirp rates of 82 kHz/sec and 100 kHz/sec, respectively. It might be interesting that this list of chirp sounders contains entries for three chirps sounders with 720 second periods located in Norfolk, VA, Kingsville, TX, and in Puerto Rico.

The plots below show zoomed waterfall diagrams around the chirps and on the bottom panel the result of the chirp search, i.e, the sums of waterfall bins along lines with a given slope.

1st chirp sounder detected using the AB1LD KiwiSDR

2nd chirp sounder detected using the AB1LD KiwiSDD

Saturday, August 24, 2019

M4RI library

This is just a quick note referencing the M4RI library that implements the "Method of four Russians (M4RM)", and the Strassen-Winograd algorithm, see these references.

Among other things, the M4RI library provides matrix inversion in GF(2) and computing the row-echelon form of a given matrix in GF(2) which is relevant for
  • finding the polynomial generating an LFSR sequence (see here and here), and
  • for detecting the presence of convolutional codes in a given bit stream by analyzing rank-deficiencies (see here and here).

M4RI seems to be available on most linux distributions. Although its latest release is from 2014, it looks quite mature and there are recent commits to the M4RI repository.

It is now being used in


The demodulated symbols of an ARINC635 HFDL burst are shown below in terms of 180-symbol long frames. Doppler offset correction and symbol timing estimation were done manually using GNU octave.

According to the ICAO ARINC635 HFDL physical layer description (see correction here and here), 30 data symbols alternate with 15 known symbols. The data symbols are scrambled with a 120-bit long scrambling sequence which explains the 180-symbol period. This scrambling sequence is generated by an LFSR, and it can be checked that the sequences A, M1, and T are generated by LFSRs as well.

It should be easy to implement this mode in gr-digitalhf.

HFDL burst
See also DK8OK's excellent posts about ARINC635 HFDL.

Thursday, July 4, 2019

Talk on KiwiSDR TDoA is available on YouTube

This is just a short note that my recent talk on KiwiSDR TDoA at the Software Defined Radio Academy 2019, which took place during the German Ham Convention in Friedrichshafen, Germany, is now available on YouTube.

For other talks from this meeting see

Tuesday, June 25, 2019

4800 symb/sec QPSK signal on 10160 kHz (2)

This in an update related to the last blog post. As before, all analysis is done in GNU octave.

In order to extract the bit stream from the signal on 10160 kHz we assume that it (D)QPSK modulated and use the gray code mapping [0,1,2,3] -> [0,1,3,2].

Assuming QPSK modulation

The extracted bits are shown below in terms of 894-bit long frames.

bit stream in terms of 24×41 frames (QPSK)

The rank-deficiency analysis of this bit stream indicates the presence of a convolutional code:

rank-deficiency (QPSK)

For obtaining the rank-deficiencies above, the bit stream has been aligned by using an offset for which the R(k)/k is minimal, i.e., at 10+m×24:

alignment of bit stream for the rank-deficiency analysis (QPSK)

As a result, the code rate is n/k=1/4, and the length of the dual code is 41. The latter is quite large and therefore hints at the use of some form of Turbo Code, or something similar to it.

Assuming DQPSK modulation

The extracted bits are shown below in terms of 894-bit long frames. Unlike for QPSK modulation the bits in positions [1,18,19,24]+m×24 are the same in each frame.

zoom of bit stream in terms of 24×41 frames (DQPSK)

Also assuming DQPSK modulation, the presence of a convolutional code is detected; it has code rate 7/12 and the length of the dual code is 41. (This might be a Turbo Code with 14 systematic bits and 5+5 parity bits)

rank deficiency (DQPSK)

alignment of bit stream for the rank-deficiency analysis (DQPSK)


It is unlikely by coincidence that the frame length is 24×41, the length of the dual code is 41, and the distance between the rank deficiencies is 24.

The fixed bits in each frame when assuming DQPSK modulation are likely being used for frame synchronization: in this case, 4 of the 14 systematic bits are used for frame alignment and there are 5+5 parity bits.

Obviously it would be interesting to figure out the full parameters of the convolutional coding.

Friday, June 14, 2019

4800 symb/sec QPSK signal on 10160 kHz

Currently there is a signal active on 10160 kHz. It is QPSK modulated with 4800 symb/sec. The autocorrelation function for the QPSK symbols has peaks at multiples of 492=12×41 symbols:

symbol autocorrelation

Arranging the QPSK symbols in frames of 492 symbols, some interesting structures can be seen

492 symbols / frame

When the symbols are arranged in terms of 12-symbol long frames, some columns of the resulting matrix have a periodicity of 41 in the squared symbols.

TDoA geo-location indicates a location close to Luxembourg.


Friday, May 31, 2019

THALES Salamandre HFXL bursts

In the last days THALES Salamandre HFXL signals were again active, as was also noticed by Antonio.

TDoA points to the area around Paris. However, judging from the observed field strengths, there were transmitters at (at least) two locations active.


A 72-frame long HFXL burst is shown below (most bursts consist of 9 frames). The symbols were obtained by manually correcting for the doppler offset and searching for the correct symbol timing using GNU octave. The burst consists of frames with 287 symbols where the last 31 symbols are +-sign miniprobes.

HFXL burst

The preamble consists of three parts where the 1st two parts are following MIL-STD-188-110 App. C and the 3rd part is a proprietary extension. It encodes 10 di-bits D0,...,D9 containing information about the used modulation schema and other signal parameters.

HFXL preamble

It is known that the first few di-bits encode information about the used modulation schema:
[D0, D1, D2] = [(1,M0), (1,M1), (1,M2)]
In order to study these bursts more systematically the extended HFXL preamble was implemented in gr-digitalhf as an extension of the 110C mode. A number of recorded HFXL signals were analyzed and the constellations shown below were found (not shown: BPSK). Note that the BPSK and QPSK modes are scrambled to 8PSK symbols.

HFXL constellations after descrambling

The table below shows a map between [M0,M1,M2] and the channel symbols after descrambling. 64QAM mode was not observed and is therefore missing in the table below.
 M0,M1,M2  Channel symbols after descrambling
 0, 0, 0   BPSK
 1, 0, 0   QPSK
 0, 1, 0   8PSK
 1, 1, 0  16QAM
 0, 0, 1  32QAM
 1, 0, 1   ----
 0, 1, 1   QPSK chips with phases [+1,-1,-1,+1]
 1, 1, 1   ----
At first is was puzzling that two combinations of [M0,M1,M2] correspond to QPSK descrambled symbols. Having a closer look at (0,1,1) bursts, it can be seen that it consists of QPSK symbols Si spread out using [+1,-1,-1,+1] chips, i.e.,
..., Si,-Si,-Si,Si, Si+1,-Si+1,-Si+1,Si+1, ...
making it a very robust mode to transmit data.

QPSK (0,1,1) mode

The bits extracted from the 72-frame long burst shown above have a mean of 0.377; assuming that the probability for a bit to be 1 is 0.5 this translates into 24.6% of the payload consisting of zeros. If this is correct then one should see long strings of 0 bits.

Assuming that the 72 frames in this burst consist of two blocks of 36 frames, and that an interleaver of the form specified in MIL-STD-188-110 App. D is used, the maximum run lengths for all interleaver increments are shown below. For both interleaver blocks there is a maximum for an interleaver increment of 469.

maximum run length as a function of interleaver increment

Assuming that the correct interleaver increment is 469, the deinterleaved bits are shown below:
  • there are four gaps, each about 215 bits long
  • the probability of a bit to be 1 if it is not in one of these gaps is 46.1% for the 1st block and 46.9% for the 2nd block
  • the distribution of the deinterleaved bits for both blocks is similar and shows an interesting pattern

deinterleaved bits for interleaver increment 469

As this analysis is based on a single burst with 72 frames, it might be a mere coincidence. In addition it is worth noticing that using the same interleaver increment, assuming that all 72 frames are a single interleaver block,  the double of the bit patterns above is obtained.

deinterleaved bits for interleaver increment 469

Wednesday, May 29, 2019

MIL-STD-188-110 App.C QAM

Recently MIL-STD-188-110 App C  (STANAG 4539) signals were found on a KiwiSDR. This made it possible to complete the corresponding decoder in gr-digitalhf which includes an adaptive channel filter, descrambling, deinterleaving, and convolutional decoding. For the QAM modes descrambling is done by applying an XOR operation on the soft decisions. 

QAM32 constellation obtained after decoding with gr-digitalhf
Using the path metrics of the convolutional decoder it was verified that the whole chain of decoding steps is correct: without puncturing the path metric \(M\) for \(n\) encoded bits at rate \(1/2\) is \(2n\) if there are no errors, so it makes sense to use \(Q=M/2n\) as a measure of data quality. When there is puncturing, e.g., to rate \(3/4\) with puncturing pattern [11, 10], the expected path metric is \(3.5/4\): three out of four bits are transmitted and the probability for the puncture to be correct is \(1/2\). Therefore in this case \(Q\) has to be rescaled by the factor \(4/3.5=8/7\).

Friday, May 10, 2019

Blind detection of convolutional codes

This post continues the topic started in this blog post, i.e., the detection of the presence of convolutional coding in a given bit stream.

The method outlined below is not new and a good reference it is this paper: M. Marazin, R. Gautier, G. Burel “Blind recovery of k/n rate convolutional encoders in a noisy environment

The basic idea is to arrange a given bit stream \(b_i\) in matrices \(R_k\) \begin{equation} B_k = \begin{pmatrix} b_0 & b_1 & b_2 & \cdots & b_{k-1}\\ b_k & b_{k+1} & b_{k+2} & \cdots & b_{2k-1}\\ \vdots & \vdots & \vdots & \ddots & \vdots \end{pmatrix} \end{equation} and then to determine the rank of \(R_k = \mathsf{rank}(B_k)\) as a function of \(k\). Note that for computing the rank \(B_k\) is treated as a matrix with values in \(\mathbb{F}_2\).

If the bit stream is completely random, all matrices \(B_k\) will likely have rank \(R_k=k\). However, the redundancy introduced by convolutional coding shows up as some matrices not having full rank, i.e., there are dependent rows in some \(B_k\) and therefore \( R_k < k \) for some \(k\).

Starting from a \(k=7,\;r=1/2\) mother code, rank deficiency plots are shown below for different puncturing patterns, together with the expected behavior.

Note that this method detects any redundancy (error coding) in a given bit stream and therefore can be generalized to other coding schemes.

Rank deficiencies for the k=7 r=1/2 mother code.
Rank deficiencies for a k=7 r=2/3 code obtained by puncturing.
Rank deficiencies for a k=7 r=3/4 code obtained by puncturing.
Rank deficiencies for a k=7 r=4/5 code obtained by puncturing.

MIL-STD-188-110D mini-probe base sequences

The mini-probes specified in MIL-STD-188-110D, Appendix D have interesting structures. Let us start with the two exceptions, \(n = 13\) and \(n = 19\):

\(n = 13\): (TABLE D-XXII)

This is the well-known Barker-13 sequence, i.e., \begin{equation} [+1, +1, +1, +1, +1, −1, −1, +1, +1, −1, +1, −1, +1]\;. \end{equation}

\(n = 19\): (TABLE D-XXIV)

This sequence is based on Legendre-19: \begin{equation} [1,\, -\mathsf{Legendre}(k/19)]\;. \end{equation}

\(n = m^2\): (TABLES D-XXIII, D-XXV - D-XXXVI)

All other mini-probe base sequences have lengths \(n=m^2\) for \(4\le m \le 17\) and can be obtained from the following formula, \begin{equation} MP(k;m) = \exp\left\{-2\pi i m \left\lfloor{\frac{k}{m}}\right\rfloor \frac{k}{n} \right\}\;, \end{equation} where \(\left\lfloor{x}\right \rfloor \) denotes floor function which returns the greatest integer \(\leq x\). Curiously, the mini-probe base sequences for \(m\ge 14\) are the complex conjugate of the formula above, so I wonder if this is by design or it is an error in the standard.

Note that \(MP(k;4)\) is the (complex conjugate of the) length-16 Frank-Heimiller sequence contained in TABLE C-VIII, i.e., \begin{equation} \exp\big\{2\pi i\, [0, 0, 0, 0,\; 0, 2, 4, 6,\; 0, 4, 0, 4,\; 0, 6, 4, 2]/8\big\}\;. \end{equation} Many pages could have been saved by describing the mini-probe base sequences in terms of the formula above.

Tuesday, March 26, 2019

8-ary constellation bursts at 12800bps data rate

For background it might be helpful to read the relevant entries in i56578's blog.

Two consecutive bursts centered on 2670 kHz are shown below in terms of 287-symbol long frames. The preamble and mini-probes have been descrambled (gr-digitalhf) and therefore have phases close to 0 rad. There are 13 frames with payload data per burst, each one having 256 symbols/frame:

Symbols after adaptive filtering and descrambling of
MIL-STD-110C known symbols for consecutive bursts

These signals are perfectly compatible standard MIL-STD-110C for 12,800 bps data rate; note that for 12,800 bps there are no requirements on the interleaver and on the error coding specified. As was observed before, only 8 points out of the QAM-64 constellation are used.

Looking closer at the payload, a periodicity of 160 symbols was found. In terms of 160-symbol long frames the payload is shown below:

Payload in terms of 160 symbol frames.
The fact that (symbol2) above is the same for all frames indicates that the payload consists of BPSK-modulated data which is scrambled to the 8PSK-like constellation. So what is left is to determine the scrambling.

It turns out that the used scrambling sequence is based on one of the scrambling sequences specified in STANAG 4538, i.e., it can be obtained as an extrapolation of one of the S4538 scrambling sequences: writing the 3-bit scrambling sequence in binary notation as PN(i) = bA(i)B(i)C(i), one can verify that A(i), B(i), and C(i) are subsequences of the same pseudo-random binary sequence generated by a certain LFSR. Determining the LFSR and the offsets of the subsequences is left as an exercise for the interested reader.

Once the payload symbols are descrambled, it becomes apparent that they consist of 104 Walsh-modulated di-bits (104×32 = 13×256) where each 4-symbol long Walsh symbol is repeated 8 times:

Descrambled payload revealing 104 Walsh-coded di-bits. 

Sunday, March 24, 2019

Interesting MSK-modulated signals on HF (2)

This is an update of the last blog post.

Yesterday, another signal was picked up for which both the "X" and the "Y" bit streams were generated by the same LFSR with polynomial [3,1,0] × [17,16,15,14,13,12,10,8,5,4,0] and period N= (23-1)×(217-1)=917,497. The cross-correlation between "X" and "Y" show that the "X" bit stream is offset w.r.t. "Y" bit stream by M=(N-1)/2=458,748 bits.

"X" and "Y" bit stream cross-correlations

The data in the "X" channel can descrambled as follows
    b(i) = XOR(~Y(M+i), X(i)),
and the auto-correlation of the descrambled bits b(i) has peaks at multiples of 48 bits:

Autocorrelation of the descrambled bit stream
In terms of 240 bit frames the descrambled bits look like this:

Descrambled bit stream in terms of 240-bit frames

and in terms of 48-bit frames:

Descrambled bit stream in terms of 48-bit frames
Here one can see that the descrambled bits come in pairs
    b(2i) = b(2i+1)
so there are 24 pairs of bits per 48-bit frame. These 24 bits are not independent: they are determined by 6 bits only:
 1  ~3    4  6 13  ~20
 2   9  ~15
 5  18 -~21
 7   8   11 16 19 -~23
10  17
12  14 -~22
where ~P denotes logical NOT of bit number P and -P denotes a bit at position P from the previous frame.

These 6 bits are likely not independent. Interpreting them as a 6-bit binary number, the histogram of these numbers shows that they are not equally probable:

Histogram of 6-bit frame interpreted as 6-bit binary numbers

Thursday, March 21, 2019

Interesting MSK-modulated signals on HF

Recently, a number of MSK-modulated signals with bandwidth ≈48 kHz were picked up on various KiwiSDRs on frequencies including 6840, 7730, 9490, 10640, 10840, 14730, 14780, and 14830 kHz. For some of these signals a TDoA analysis has been performed, pointing to a location close to Chicago:

Since the bandwidth of theses signals exceeds the available bandwidth of a single KiwiSDR channel, three recordings spaced 15 kHz were coherently combined using gr-kiwisdr.

The power spectrum of FFT(IQ2) shows two clear peaks at ±24kHz, so these signals are MSK modulated with 48,000 baud data rate.

FFT(IQ2) showing two clear peaks at ±baud/2 → MSK modulation

For the coherently combined recording, the MSK demodulation quality plots shown below indicate that the quality is sufficient for extracting bit streams. These and the following plots were made with Octave code based on signal-analysis.

MSK demodulation quality plots

Using a coherent demodulation technique the "X" and "Y" bit streams were obtained, where the "X" bits are modulated onto cos(t) and "Y" onto sin(t). The data rate for both "X" and "Y" is 24,000 bits/sec.

The autocorrelations of the "X" and "Y" bit streams do not reveal any frame structure, i.e., "X" and "Y" look like streams of perfect random bits. However, it turns out that the "Y" bit stream is entirely made up by a pseudo-random sequence generated by a LFSR, so this presumably is how the start locations of frames can be recovered from the received signal.

The taps for the length-20 LFSR generating the "Y" bit stream are
   T = [11011101101101101101],
where the LFSR taps T are defined such that the following property holds for a given bit sequence b
   b(i) == mod(sum(b(i-20:i-1) .* T), 2)

The period of this LFSR was determined by simulating 2M bits using the found taps and a start state taken from the data. It is N = 917,497 = (23-1)×(217-1). The fact that N factorizes indicates that the polynomial in GF(2) defined by T is not prime, and indeed:
    [20,19,17,16,15,13,12,10,9,7,6,4,3,1,0] = [3,1,0] × [17,16,15,14,13,12,10,8,5,4,0].
A valid start state S which generates "Y" is
    S = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1].

The ~"Y" bit stream is generated by a LFSR with 20 taps.

No structures have yet been found for the "X" bit stream which presumably carries data.