burst_msg_source_c together with blocks from gr-iridium

You will find the burst_msg_source_c in this out-of-tree module: https://github.com/rubund/capture-tools/tree/master/gr-capture_tools

gr-iridium is a module made for receiving packets from Iridium satellites. One clever idea by the gr-iridium guys is to use an FFT to monitor a whole band and then detect peaks. This makes it possible to receive packets at multiple frequencies at the same time, without having a huge number of baseband processors working in parallel.

Peaks in the FFT are discovered by the block fft_burst_tagger. The frequency and various other information is added as a stream tag to the stream. Then the block tagged_burst_to_pdu looks for these tags in the stream and whenever it finds one, it collects a number of IQ samples and stores them in a buffer which is then passed on as a GR message.

In gr-iridium, the downstream blocks then operate purely on messages. This means that only “custom” blocks can be used there. Since I like the idea of being able to use standard GR blocks, I implemented a new block, burst_msg_source_c, which then again converts the messages back to a normal stream. This has proven to be a quite useful “technique”. It allows receiving packets at multiple frequencies, even coming exactly at the same time, but having only a standard “one dimensional” baseband processor implemented in GNU Radio. Since the upstream blocks add tags to the stream, it is also possible to keep track of the exact time instant when the packets were being transmitted on air.


burst_msg_source_c does the frequency translation for every sample burst so that the baseband processor can stay tuned to the same frequency (baseband) all the time. Since the frequency detection mechanism in fft_burst_tagger is not always exact, burst_msg_source supports specifying specific frequency intervals for the channels if such information is a priori known (“Round factor” and “Round add“).

It can be seen that the output from burst_msg_source_c will not be at a regular sampling rate. It will come in bursts. Sometimes, if for instance the threshold has been set too low in fft_burst_tagger, the output from burst_msg_source_c  will be at a sampling rate much higher than the input! In that case, the handshaking mechanism between burst_msg_source_c and tagged_burst_to_pdu makes it possible to simply drop bursts instead of the whole flow graph hanging (“Drop Overflowing Bursts“).

Smart Meters from Kaifa

Smart meters for reporting electricity consumption come in several variants. One of them is a device from KAIFA with model number MA304H3E. It apparently communicates with the network on frequencies around 870 – 875 MHz.

By placing the HackRF close to the fuse box and monitoring these frequencies, I first got a recording, and by analyzing this with various demodulators, a packet popped up as a nice frequency modulated signal:

Since the packets apparently can come at various frequencies in the 870 MHz band, it was not possible to use a simple receiver for one channel. I was inspired by the burst_tagger approach used in the gr-iridium project (more information here). This burst_tagger is used to tag peaks in the FFT spectrum. The IQ samples for every tagged piece is then in the following block collected to a GR message and sent further down the chain. I wrote another block which then again converts these chunks of IQ samples back to a linear IQ stream which can then be treated further with normal GR DSP block. This makes it possible to simultaneously monitor a whole band for packets, and even receive packets that are transmitted simultaneously on different frequencies – using only one baseband processor! Every IQ chunk is marked with tags so that it is possible to recover the frequency it was received at and the exact time instant it occurred.

Below is one packet where tags have been added for the sampling instants. The preamble is quite clearly visible and long and therefore good for syncing the symbol clock in the receiver.

After implementing the block sync_and_strobe and using it for the measured symbol timing, packets were received (sync_and_strobe is part of the out-of-tree module gr-capture_tools). The sync word 0xaa904e was used. After some trial and error, I managed to find the correct bit offset, so that bytes line up nicely:

The first 8 bits (1 byte) after the sync word seemed to correlate with the length of the packet, so therefore it must be a length field. The next 16 bits are “always” one of 4 variants: 0x69dc, 0x00e2, 0x0200 or 0x49d8.  Each of these values seemed to correlate with a certain packet format, so these 16 bits are most likely a packet type field.

I also noticed that whenever the signal was very strong, a certain 16 bit wide part of the packet was always the same. Depending on the packet type field, this 16 bit part could be at various locations, but it was always present. This therefore indicated that it somehow is an address or ID for the exact smart meter which was close to the receiver.

Having this information it was already quite possible to make a quite nice plot to see a more overall picture.

The various colours correspond to various sender addresses. The various marker shapes correspond to different packet types. It can be seen that the packet type with round markers (0x00e2) always appears on the same frequency 871.3 MHz. It also seems to come every ~2 minutes from every device. These packets are quite short and do not seem to contain much information. They are probably some kind of beacon or keep-alive packets.

One of the other packet types contains another field where addresses for other devices appears. This address was therefore believed to be the recipient address. By using graphviz and plotting the sender and recipient addresses with lines between all devices which have send packets to each other, a very nice graph of nodes popped up surprisingly:


So, the system is clearly some kind of mesh network!

The last part of some of the packet types seems to contain data which looks quite random and is therefore most likely an encrypted payload. More information of this payload has not been found yet.

AIS Packets (Automatic Identification System)

AIS signals are GFSK modulated signals at 161.975 or 162.025 MHz. Packets are sent with a preamble and the HDLC packet protocol is used. Below are pictures showing frequency vs time plots.

Download flow graph here: https://www.funwithelectronics.com/wordpress/other_data/demod_gfsk_for_blog.grc

When connecting the sync_and_strobe (gr-capture_tools) block to this signal and configuring it correctly, we get this:

Zoomed in on the first part:


AIS packets are “encoded” in multiple steps:

  1. The fields of various sizes are packed together as a bit sequence.
  2. Every 8 bit bundle is then reversed
  3. Bit-stuffing is performed: Every 111111 is converted to 1111101
  4. The stream is inverted, 1101 becomes 0010
  5. Differential encoding is performed. So every 1 becomes a transition, every 0 causes no change
  6. Then the header and end word are added at the start and the end.