Reversing H.Koenig wireless remote (part 2)

This is the follow-up the previous post regarding that robot vacuum.

If you have not read it yet, here is the first part.

So far, we have looked at the setup procedure of the RF transceiver and here is what we have learned:

  • the radio transceiver is an Avantcom A7105
  • modulation is FSK
  • frequency deviaton is set to 186 kHz
  • the base frequency is 2.40 GHz
  • channel is set to 100 right before any transmission
  • channel space is 500 kHz
  • thus the working frequency is 2.45 GHz
  • the ID number is 0x58 0x52 0xD2 0x41
  • the bandwith is 500 kbps
  • the packets are 8-bytes long
  • the preamble is 4-bytes long
  • CRC is disabled
  • Data whitening is disabled
  • FEC encoding is disabled
  • the firmware is definitely not optimized for batteries as the transceiver is reset and the set up before every single FIFO operation!

Here is an excerpt from the transceiver datasheet that describes the packet format :

In our case, according to what we have decoded, the packet is restricted to a 4 bytes preamble, followed by a 4 bytes ID code and finally the 8 bytes payload (without encoding, without data whitening and without CRC).

Alright, let’s dig a bit deeper into the protocol.

First, let’s hook our favorite logic analyzer to the SPI bus and try every single button! Just as a remainder, here is a picture of the remote:

We have 14 buttons so we expect 14 different packets over the air.

In fact, for each button, the remote sends a packet when the button is pressed and another one when it is released. So we get 28 packets.

The MCU waits between 50ms and 55ms between each transmission and sends an “IDLE” strobe to the transceiver 55ms after the last “button up” event.

In the capture here-under, you can see that the pressed button has been sent 3 times, followed by the “button released” packet. On the upper-right packet you can see the 55ms delay between two transmissions.

And if you are wondering what the last tiny spike is, the answer can be found on this last picture:

Ok, enough waiting, here are the packets for each button. The first one is for the “down” event while the second one represents an “up” event.

Thursday” button

0xAA 0x00 0x03 0x49 0x00 0x00 0x01 0xF7

0xAA 0x00 0x03 0x49 0x00 0x00 0x11 0x07

Full Go” button

0xAA 0x00 0x03 0x49 0x00 0x00 0x02 0xF8

0xAA 0x00 0x03 0x49 0x00 0x00 0x12 0x08

Wednesday” button

0xAA 0x00 0x03 0x49 0x00 0x00 0x03 0xF9

0xAA 0x00 0x03 0x49 0x00 0x00 0x13 0x09

Friday” button

0xAA 0x00 0x03 0x49 0x00 0x00 0x04 0xFA

0xAA 0x00 0x03 0x49 0x00 0x00 0x14 0x0A

Sunday” button

0xAA 0x00 0x03 0x49 0x00 0x00 0x05 0xFB

0xAA 0x00 0x03 0x49 0x00 0x00 0x15 0x0B

Monday” button

0xAA 0x00 0x03 0x49 0x00 0x00 0x06 0xFC

0xAA 0x00 0x03 0x49 0x00 0x00 0x16 0x0C

OK” button

0xAA 0x00 0x03 0x49 0x00 0x00 0x07 0xFD

0xAA 0x00 0x03 0x49 0x00 0x00 0x17 0x0D

Saturday” button

0xAA 0x00 0x03 0x49 0x00 0x00 0x08 0xFE

0xAA 0x00 0x03 0x49 0x00 0x00 0x18 0x0E

Tuesday” button

0xAA 0x00 0x03 0x49 0x00 0x00 0x09 0xFF

0xAA 0x00 0x03 0x49 0x00 0x00 0x19 0x0F

Red” button

0xAA 0x00 0x03 0x49 0x00 0x00 0x0A 0x00

0xAA 0x00 0x03 0x49 0x00 0x00 0x1A 0x10

Down” button

0xAA 0x00 0x03 0x49 0x00 0x00 0x0B 0x01

0xAA 0x00 0x03 0x49 0x00 0x00 0x1B 0x11

Left” button

0xAA 0x00 0x03 0x49 0x00 0x00 0x0C 0x02

0xAA 0x00 0x03 0x49 0x00 0x00 0x1C 0x12

Right” button

0xAA 0x00 0x03 0x49 0x00 0x00 0x0D 0x03

0xAA 0x00 0x03 0x49 0x00 0x00 0x1D 0x13

Up” button

0xAA 0x00 0x03 0x49 0x00 0x00 0x0E 0x04

0xAA 0x00 0x03 0x49 0x00 0x00 0x1E 0x14

You may have noticed that only the last two bytes are changing.

So far, we can assume that the second to last byte encodes the button in the lower nibble and its state (pressed / released) in the higher nibble.

My guess is that the last byte is computed against the previous one (or maybe all the previous ones).

But we are still missing something. According to the manual, there is a pairing procedure to get the robot work with a given remote: one have to press and hold the “OK” button for 5 seconds and while it is still pressed, power on the robot. Two beeps (from the robot) acknowledges the remote pairing.

If we try that procedure with our logic analyzer hooked on the SPI bus, we grab that packet during the first couple of seconds (2.3 seconds):

0xAA 0x00 0x03 0x49 0x00 0x00 0x07 0xFD

And then, the packet changes to:

0x55 0x00 0x03 0x49 0x00 0x00 0x00 0xA1

Therefore, the first byte is used to tell the robot some “code”. Unfortunately I do not have another remote to test that theory and the robot itself is much more difficult to take appart to try to get a hand on its firmware. But I guess that:

  1. The first byte gives the operational mode
  2. The following 5 bytes is the hard-coded serial number of the remote that the robot has to learn to be paired
  3. The second to last byte encodes the button
  4. The last byte may be a kind of checksum (as they disabled the internal CRC)

That’s all for the second part of this study. The third (and last) part will be about building a computer controlled remote.

If you get other theories for the last byte, please tell me in comments!