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.