Z-Wave Packets

When turning on one switch:

Mag: -30.15, Time: 2018-06-17 13:32:27 [f0d66dec2c0141060d042501ff100000..]
Mag: -23.62, Time: 2018-06-17 13:32:27 [f0d26dec2c0403060a018e00..]
Mag: -26.69, Time: 2018-06-17 13:32:27 [f0d66dec2c0441090d012503ff1d00..]
Mag: -30.11, Time: 2018-06-17 13:32:27 [f0d66dec2c0103090a048100..]

When turning off the same switch:

Mag: -30.38, Time: 2018-06-17 13:33:45 [f0d66dec2c0141070d04250100ee00..]
Mag: -21.80, Time: 2018-06-17 13:33:45 [f0d66dec2c0403070a018f00..]
Mag: -22.77, Time: 2018-06-17 13:33:45 [f0d66dec2c04410a0d01250300e100..]
Mag: -30.52, Time: 2018-06-17 13:33:45 [f0d66dec2c01030a0a04820000..]

Turning on a second time:

Mag: -30.77, Time: 2018-06-17 13:35:16 [f0d66dec2c01410a0d042501ff1c00..]
Mag: -24.04, Time: 2018-06-17 13:35:16 [f0de6dec2c04030a0a018200..]
Mag: -28.45, Time: 2018-06-17 13:35:16 [f0d66dec2c04410e0d012503ff1a00..]
Mag: -30.92, Time: 2018-06-17 13:35:16 [f0d66dec2c01030e0a04860000..]

 

Turning off a second time:

Mag: -30.88, Time: 2018-06-17 13:35:55 [f0d66dec2c01410b0d04250100e200..]
Mag: -20.82, Time: 2018-06-17 13:35:55 [f0d66dec2c04030b0a01830000..]
Mag: -23.79, Time: 2018-06-17 13:35:55 [f0d66dec2c04410f0d01250300e400]
Mag: -30.78, Time: 2018-06-17 13:35:55 [f0d66dec2c01030f0a048700..]

 

By comparing the two packets used to start a “turn on” procedure:

Mag: -30.15, Time: 2018-06-17 13:32:27 [f0d66dec2c0141060d042501ff100000..]
Mag: -30.77, Time: 2018-06-17 13:35:16 [f0d66dec2c01410a0d042501ff1c00..]

We see that the only byte changing is the 8th byte (apart from the CRC). It changes from 0x06 to 0x0a. This is then probably just a number to identify a specific request.

By comparing the “turn on” packet with the “turn off” packet:

Mag: -30.15, Time: 2018-06-17 13:32:27 [f0d66dec2c0141060d042501ff100000..]
Mag: -30.38, Time: 2018-06-17 13:33:45 [f0d66dec2c0141070d04250100ee00..]

We see that the 8th byte is also changing here, but also the 13th byte. It is 0xff when turning on and 0x00 when turning off.

By comparing the first packet from the hub device with the receiver:

Mag: -30.15, Time: 2018-06-17 13:32:27 [f0d66dec2c0141060d042501ff100000..] 
Mag: -23.62, Time: 2018-06-17 13:32:27 [f0d26dec2c0403060a018e00..]

We see that the 6th byte changes (the device id), the 8th byte remains the same (request ID). The 7th byte changes from 0x41 to 0x03. This may indicate that it is an indicator of the packet type, where 0x41 is a request and 0x03 is an acknowledgement.

The end of the first packet (before the CRC) looks like 0x0d042501ff, while the second packet ends with 0x0a01. The first of the bytes is decimal 13 and decimal 10, which could be the length of the packet as of and including the CRC bytes.

By comparing the first packet from the hub device with the first “request packet” from the receiver:

Mag: -30.15, Time: 2018-06-17 13:32:27 [f0d66dec2c0141060d042501ff100000..] 
Mag: -26.69, Time: 2018-06-17 13:32:27 [f0d66dec2c0441090d012503ff1d00..]

We see that the 6th byte (device id) changes, the 8th byte changes (request id), the end of the packet changes from 0x0d042501ff to 0x0d012503ff.  The second of these bytes look like the address of the receiver. The 7th byte remains the same.

Mag: -30.15, Time: 2018-06-17 13:32:27 [f0d66dec2c0141060d042501ff100000..] 
                                        <><------><><><><><><---<><> 
                                        a b       c d e f g h   i j
a: sync word (0xf0)
b: network id
c: device id (central hub seems to be 0x01)
d: packet type (0x41: request, 0x03: ack)
e: request id
f: length of packet
g: device id of receiver
h: unknown
i: on(0xff) / off(0xff)
j: CRC

 

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.