Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new decoder for Velux shutter remote control - io-homecontrol protocoll #1376

Open
dwarning opened this issue May 7, 2020 · 70 comments
Open
Labels
device support Request for a new/improved device decoder feedback request for more information; may be closed id 30d if not received inactive issue is valid but no one is working on it

Comments

@dwarning
Copy link

dwarning commented May 7, 2020

Recently I asked for differences in decoding Velux remote controller KI 313 signals with RTL_433 in flex decoder mode compared to manual decoding by the Pulseview tool, see https://groups.google.com/forum/#!topic/rtl_433/HxjH97Tkgys.

Attached is a zipped .cu8 file. Please look in the region from 540ms to 620ms for the four 7ms chunks. The second attachement is a screenshot from Pulseview with one data sequence decoded by the UART decoder 38.4k, 8N1 lsb first bitorder. In discussion with Karl Lohner the outcome was that there are some uncertainties regarding the start bit configuration in Pulseview and the capabilities of the built-in flex Decoder.

g001_868.91M_1024k.zip
Pulseview_uart_decoded

The third attachement shows the decoding result for the Velux Controller in different operating modes like up, down and stop. by issuing the command two times to observe crc and rolling Code.

Velux_Codes

This is inline with a former work http://redd.it/cz8trb by z_rrr who sniffing the SPI between uC and RFIC in a Somfy remote which is also part of the io-homecontrol alliance.

I would like to ask for a new FSK_PCM Decoder, name it FSK_UART like Christian has suggested with the capability of specifing all needed decoding parameters, like Baudrate, protocol and start/stop bit configuration.

Don't hesitate to ask for more informations you need for implementation and testing.

Thank you,
Dietmar

@zuckschwerdt
Copy link
Collaborator

Thanks for the research, I'll look into it soon. There are two possible ways to add support:

  • if there is some synchronisation structure to find the start (or stop) bits we'll add FSK_UART
  • if the stream is unstructured we'll add decode_uart(), where you need to align the first start bit beforehand.

@dwarning
Copy link
Author

Thank you, Christian.
I want try to support you.
I think the Problem is clear identified and could the solution for uart implementation anyway.
Let me explain my way to decode. As I said I used the following conversion
rtl_433 -s 1024k -w g001_868.91M_1024k.sr -r g001_868.91M_1024k.cu8
to get a Pulseview file. Then I converted the weak FM Signal to logic at first (and later we see wrong) with a conversion Level of 0.0V. So the very long synchronisation Phase (About 510ms, exact 1961 Bytes x55) starts wrong because of wrong start bit recognition. See picture
Start_of_Sync_Phase
Coming from that we are also false with start bit recognition in data phase:
End_of_Sync_Phase
Now I shifted the conversion level of Pulseview logic converter to -0.03V and got following Sync start phase:
Start_of_Sync_low_level
and the correct data stream with Velux specific start Bytes 0xFF33:
End_of_Sync_low_conversion level
So a common usable FSK_UART Decoder should take care for

  • parametrizable sync phase (in Velux we have 2 different durations: 510ms and 13,5ms)
  • customary UART protocol parameter as baud rate, data bits, parity, stop bits and bit order.
  • start bit should only recognized inside configurable tolerances.
  • adjustable Start Bytes - in Velux we have 0xFF33

I have no clue why the from IQ data calculated analog FM Signal is so weak (+/-55mV). I think to have stronger input for the pulseview conversion step would be helpful. Any comments are appreciated.

@zuckschwerdt
Copy link
Collaborator

zuckschwerdt commented May 13, 2020

Thanks for the very detailed analysis! The start- and stop-bit then have the same timing as every other bit. If we don't know about the Sync-word (start byte) then every bit could be seen as a start bit.
I propose to do

  1. FSK_PCM decode
  2. search sync-word 0b0 0xff 0b1 0b0 0x33 0b1 (i.e. 0x7fd99, note that 0x33 is 0xcc "on the wire")
  3. run a decode_uart() function (a simple 10-to-8 decoder)

I guess we could try to find the start- and stop-bits by searching for a 0b10 pattern repeating after every 8 bits, but that seems like it could fail/false positive a lot.

I'll prototype something soon.

zuckschwerdt added a commit that referenced this issue May 14, 2020
@zuckschwerdt
Copy link
Collaborator

UART decoder support has now been added. The syntax for the flex spec will likely change, but to test this right away use ,preamble=7fd99,decode_uart, e.g.:
rtl_433 -c 0 -R 0 -X 'n=uart,m=FSK_PCM,s=26,l=26,r=7000,preamble=7fd99,decode_uart' -y 'ffff7fd9940481604' (not sure on the 26 µs, should match 38.4k?) Result should be:

codes     : {24}010203

@dwarning
Copy link
Author

Made a executable with msys/mingw64 after git pull of master branch.
If I use double quotes for flex options then it works with decode_uart on your test string with expected result.

So I used the velux remote control and got without decode_uart:
`rtl_433 -f 868.89M -s 1024k -g 20 -c 0 -R 0 -X "n=uart,m=FSK_PCM,s=26,l=26,r=2048,preamble={16}0xaaff"
rtl_433 version 20.02-49-g177fb6b branch master at 202005141540 inputs file rtl_tcp RTL-SDR
Use -h for usage help and see https://triq.org/ for documentation.

New defaults active, use "-Y classic -s 250k" for the old defaults!

Disabling all device decoders.
Registered 1 out of 152 device decoding protocols [ ]
Found Rafael Micro R820T tuner
[R82XX] PLL not locked!
Sample rate set to 1024000 S/s.
Tuner gain set to 20.700000 dB.
Tuned to 868.890MHz.


time : 2020-05-14 17:45:13
model : uart count : 1 num_rows : 1 rows :
len : 261 data : b326f80200802fc96eb395e00a028692e0080200ac2a49ea50862e6af299a5e768
codes : {261}b326f80200802fc96eb395e00a028692e0080200ac2a49ea50862e6af299a5e768


time : 2020-05-14 17:45:13
model : uart count : 1 num_rows : 1 rows :
len : 262 data : b326f80200802fc96eb395e00a028692e0080200ac2a49ea50862e6af299a5e768
codes : {262}b326f80200802fc96eb395e00a028692e0080200ac2a49ea50862e6af299a5e768


time : 2020-05-14 17:45:13
model : uart count : 1 num_rows : 1 rows :
len : 262 data : b326f80200802fc96eb395e00a028692e0080200ac2a49ea50862e6af299a5e76c
codes : {262}b326f80200802fc96eb395e00a028692e0080200ac2a49ea50862e6af299a5e76c


time : 2020-05-14 17:45:13
model : uart count : 1 num_rows : 1 rows :
len : 262 data : b326f80200802fc96eb395e00a028692e0080200ac2a49ea50862e6af299a5e76c
codes : {262}b326f80200802fc96eb395e00a028692e0080200ac2a49ea50862e6af299a5e76c


time : 2020-05-14 17:45:14
model : uart count : 1 num_rows : 1 rows :
len : 261 data : b326f80200802fc96eb395e00a028692e0080200ac264a625f886bfa72fbb46218
codes : {261}b326f80200802fc96eb395e00a028692e0080200ac264a625f886bfa72fbb46218


time : 2020-05-14 17:45:14
model : uart count : 1 num_rows : 1 rows :
len : 262 data : b326f80200802fc96eb395e00a028692e0080200ac264a625f886bfa72fbb4621c
codes : {262}b326f80200802fc96eb395e00a028692e0080200ac264a625f886bfa72fbb4621c


time : 2020-05-14 17:45:14
model : uart count : 1 num_rows : 1 rows :
len : 261 data : b326f80200802fc96eb395e00a028692e0080200ac264a625f886bfa72fbb46218
codes : {261}b326f80200802fc96eb395e00a028692e0080200ac264a625f886bfa72fbb46218
But with decode_uart option there comes nothing:c:\msys64\home\dwarning\sdr_decode\velux\decode>rtl_433 -f 868.89M -s 1024k -g 20 -c 0 -R 0 -X "n=uart,m=FSK_PCM,s=26,l=26,r=2048,preamble={16}0xaaff,decode_uart"
rtl_433 version 20.02-49-g177fb6b branch master at 202005141540 inputs file rtl_tcp RTL-SDR
Use -h for usage help and see https://triq.org/ for documentation.

New defaults active, use "-Y classic -s 250k" for the old defaults!

Disabling all device decoders.
Registered 1 out of 152 device decoding protocols [ ]
Found Rafael Micro R820T tuner
[R82XX] PLL not locked!
Sample rate set to 1024000 S/s.
Tuner gain set to 20.700000 dB.
Tuned to 868.890MHz.


time : 2020-05-14 17:53:39
model : uart count : 1 num_rows : 1 rows :
len : 0 data :
codes : {0}


time : 2020-05-14 17:53:40
model : uart count : 1 num_rows : 1 rows :
len : 0 data :
codes : {0}


time : 2020-05-14 17:53:40
model : uart count : 1 num_rows : 1 rows :
len : 0 data :
codes : {0}


time : 2020-05-14 17:53:40
model : uart count : 1 num_rows : 1 rows :
len : 0 data :
codes : {0}


time : 2020-05-14 17:53:40
model : uart count : 1 num_rows : 1 rows :
len : 0 data :
codes : {0}


time : 2020-05-14 17:53:40
model : uart count : 1 num_rows : 1 rows :
len : 0 data :
codes : {0}


time : 2020-05-14 17:53:40
model : uart count : 1 num_rows : 1 rows :
len : 0 data :
codes : {0}
`
Is there a misunderstanding of the preamble? Should I use the decoded value?

@zuckschwerdt
Copy link
Collaborator

If you have a PCM code of say aaffb326f80200..., i.e. after preamble matching b326f80200... then that won't work with UART. You are off by a single bit -- b32 is 1 01100110 0 10.
See this BitBench with your codes.

You need to align one bit to the right, e.g. 55ff:

rtl_433 -c 0 -R 0 -X 'n=foo,m=FSK_PCM,s=26,l=26,r=2048,preamble=55ff,decode_uart' -y 'aaffb326f80200802fc96eb395e00a028692e0080200ac2a49ea50862e6af299a5e768'gives

codes     : {208}33f60000003fdacdea000161d20000000d255e0a18673d99e96e

@dwarning
Copy link
Author

dwarning commented May 14, 2020 via email

@zuckschwerdt
Copy link
Collaborator

To clarify: the preamble can match anywhere in the data. No need to use all bits from the start. Preamble here means: search these bits and cut exactly there.
You can also use the sync-word ff33 (encoded: 0 ff 1 0 cc 1 = 7fd99) to match:

rtl_433 -c 0 -R 0 -X 'n=uart,m=FSK_PCM,s=26,l=26,r=2048,preamble=7fd99,decode_uart' -y 'aaffb326f80200802fc96eb395e00a028692e0080200ac2a49ea50862e6af299a5e768' makes sure the full sync word is found and the output is only the payload:

codes     : {200}f60000003fdacdea000161d20000000d255e0a18673d99e96e

@dwarning
Copy link
Author

dwarning commented May 15, 2020 via email

@psa-jforestier
Copy link
Contributor

Hello. I just realize I have Velux windows too. The IO-HOMECONTROL protocol is used by theses devices (I have the single-way remote control : no feedback from the window motor sent back to the remote).
Thanks to @dwarning, I use the Flex decoder like this :
rtl_433 -c 0 -R 0 -g 40 -X "n=uart,m=FSK_PCM,s=26,l=26,r=2048,preamble={24}0x5555ff,decode_uart" -f 868.89M

It gives me the following codes :
Stop the motor :

codes     : {208}33f60000003f708758000161d20000003bd2e6b62cef54c8a937
codes     : {208}33f60000003f708758000161d20000003bd6630743f0530ddc24

Up :

codes     : {224}33f80000007f708758000161d40080c800003bd505526875499c7e72

Down :

codes     : {224}33f80000007f708758000161d40080c800003bdf1ee7a0e304487a6b

Note : the down signal is detected 1 times on 3 or 4 tries.

The Command 1Byte you identified seems to be different, and also the messages have different length (224 for up and down, 208 for stop). I think the decoder is not accurate.

@dwarning
Copy link
Author

dwarning commented Sep 4, 2020

Hello,
don't know about the accuracy of this decoder. If I remember right I got also sometimes some bytes more then expected.
Below you can find an excerpt of my results of investigation the velux protocoll.

In my opinion you have 27 bytes with Sync, Length, address, command, 7 bytes Rolling code and 2 bytes CRC-16 Kermit Polynom: 0x1021, Init 0x0000, Final XOR: 0x0000 at the end.

And the bytes for up, down and stop:
`

F5 33 F6 20 00 00 3F DA CD EA 00 01 61 00 00 00 00 0B DD FD 8E F5 6F 15 AD AA 1E
F5 33 F6 00 00 00 3F DA CD EA 00 01 61 00 00 00 00 0B DD FD 8E F5 6F 15 AD 4F 9C
F5 33 F6 00 00 00 3F DA CD EA 00 01 61 00 00 00 00 0B DD FD 8E F5 6F 15 AD 4F 9C
D5 33 F6 00 00 00 3F DA CD EA 00 01 61 00 00 00 00 0B DD FD 8E F5 6F 15 AD 4F 9C
                                                     
FF 33 F6 20 00 00 3F DA CD EA 00 01 61 C8 00 00 00 0B BD 8A A3 A9 73 2E 10 26 D2
D5 33 F6 00 00 00 3F DA CD EA 00 01 61 C8 00 00 00 0B BD 8A A3 A9 73 2E 10 C3 50
FD 33 F6 00 00 00 3F DA CD EA 00 01 61 C8 00 00 00 0B BD 8A A3 A9 73 2E 10 C3 50
D5 33 F6 00 00 00 3F DA CD EA 00 01 61 C8 00 00 00 0B BD 8A A3 A9 73 2E 10 C3 50
                                                     
FX 33 F6 20 00 00 3F DA CD EA 00 01 61 D2 00 00 00 0B 99 15 DE CA CF 7E 0E 80 69
FF 33 F6 00 00 00 3F DA CD EA 00 01 61 D2 00 00 00 0B 99 15 DE CA CF 7E 0E 65 EB
FD 33 F6 00 00 00 3F DA CD EA 00 01 61 D2 00 00 00 0B 99 15 DE CA CF 7E 0E 65 EB
FF 33 F6 00 00 00 3F DA CD EA 00 01 61 D2 00 00 00 0B 99 15 DE CA CF 7E 0E 65 EB
                                                     
D5 33 F6 00 00 00 3F DA CD EA 00 01 61 D2 00 00 00 0B A1 05 17 5A 82 DF AE 8B BF
FF 33 F6 00 00 00 3F DA CD EA 00 01 61 D2 00 00 00 0B A1 05 17 5A 82 DF AE 8B BF
FF 33 F6 00 00 00 3F DA CD EA 00 01 61 D2 00 00 00 0B A1 05 17 5A 82 DF AE 8B BF
FD 33 F6 00 00 00 3F DA CD EA 00 01 61 D2 00 00 00 0B A1 05 17 5A 82 DF AE 8B BF

`
Sorry - I can't attach the excel sheet.
Saw no chance to recognize rolling code algorithm.

@TheChatty
Copy link
Contributor

TheChatty commented Jun 24, 2021

I tried psa's command and observed the following using my two Velux remotes (one code per button push):

UP 2xRIGHT, 2xLEFT, 1xPSA
codes     : {224}33f80000007fe1f573000161d40080c800000d6c2c3a3123e6ab7f1e
codes     : {224}33f80000007fe1f573000161d40080c800000d6ee448de7d4e0362d1
codes     : {224}33f80000007fc58967000161d40080c800000c6304e867ed64adf055
codes     : {224}33f80000007fc58967000161d40080c800000c658414991e8b06b82b
codes     : {224}33f80000007f708758000161d40080c800003bd505526875499c7e72

STOP 2xRIGHT, 2xLEFT, 2xPSA
codes     : {208}33f60000003fe1f573000161d20000000d6f708d89781e43bc24
codes     : {208}33f60000003fe1f573000161d20000000d71d1b10f26e1c18a9d
codes     : {208}33f60000003fc58967000161d20000000c664fcf56fb1c72d31e
codes     : {208}33f60000003fc58967000161d20000000c682025e049f331b64a
codes     : {208}33f60000003f708758000161d20000003bd2e6b62cef54c8a937
codes     : {208}33f60000003f708758000161d20000003bd6630743f0530ddc24

DOWN 2xRIGHT, 2xLEFT, 1xPSA
codes     : {224}33f80000007fe1f573000161d40080c800000d749fb9a0665ff477a6
codes     : {224}33f80000007fe1f573000161d40080c800000d7671b81065a2e20616
codes     : {224}33f80000007fc58967000161d40080c800000c6b56fcf691e6a92c74
codes     : {224}33f80000007fc58967000161d40080c800000c6ddaf0208646688fad
codes     : {224}33f80000007f708758000161d40080c800003bdf1ee7a0e304487a6b

I also got a rolling door using Somfy smoove io which produces roughly 10 codes per button push. E.g.

codes     : {208}33f60000003f17f523000147c800000018c438789cb680ccbc74
codes     : {200}33f60000003f17f523000147c800000018c438789cb680ccbc
codes     : {224}33f80000003f17f5232002ff0143010e000018c5045ee107363d59b4
codes     : {216}33f80000003f17f5232002ff0143010e000018c5045ee107363d59
codes     : {224}33f80000003f17f5232002ff0143010e000018c5045ee107363d59b4
codes     : {216}33f80000003f17f5232002ff0143010e000018c5045ee107363d59
codes     : {224}33f80000003f17f5232002ff01430105ff0018c6a34715cbe0124f7f
codes     : {224}33f80000003f17f5232002ff01430105ff0018c6a34715cbe0124f7f
codes     : {224}33f80000003f17f5232002ff01430105ff0018c6a34715cbe0124f7f
codes     : {224}33f80000003f17f5232002ff01430105ff0018c6a34715cbe0124f7f

Does this help?

@zuckschwerdt
Copy link
Collaborator

@dwarning did a very thorough analysis, and found a/the structure including CRC. We can check with your data and turn this into a decoder -- but there is still the rolling code encryption or MAC.

@zuckschwerdt
Copy link
Collaborator

zuckschwerdt commented Jun 25, 2021

From the previous examples and the new packets I assume to following format.
The dest/src are not encrypted and the payload could be unencrypted too, i.e. it's only a MAC- not encryption-scheme.

33 f6 2000003f dacdea00 016100000000     0bdd fd8ef56f15ad aa1e
33 f6 0000003f dacdea00 016100000000     0bdd fd8ef56f15ad 4f9c
33 f6 2000003f dacdea00 0161c8000000     0bbd 8aa3a9732e10 26d2
33 f6 0000003f dacdea00 0161c8000000     0bbd 8aa3a9732e10 c350
33 f6 2000003f dacdea00 0161d2000000     0b99 15decacf7e0e 8069
33 f6 0000003f dacdea00 0161d2000000     0b99 15decacf7e0e 65eb
33 f6 0000003f dacdea00 0161d2000000     0ba1 05175a82dfae 8bbf

33 f8 0000007f e1f57300 0161d40080c80000 0d6c 2c3a3123e6ab 7f1e [UP RIGHT]
33 f8 0000007f e1f57300 0161d40080c80000 0d6e e448de7d4e03 62d1 [UP RIGHT]
33 f8 0000007f c5896700 0161d40080c80000 0c63 04e867ed64ad f055 [UP LEFT]
33 f8 0000007f c5896700 0161d40080c80000 0c65 8414991e8b06 b82b [UP LEFT]
33 f8 0000007f 70875800 0161d40080c80000 3bd5 05526875499c 7e72 [UP PSA]
33 f6 0000003f e1f57300 0161d2000000     0d6f 708d89781e43 bc24 [STOP RIGHT]
33 f6 0000003f e1f57300 0161d2000000     0d71 d1b10f26e1c1 8a9d [STOP RIGHT]
33 f6 0000003f c5896700 0161d2000000     0c66 4fcf56fb1c72 d31e [STOP LEFT]
33 f6 0000003f c5896700 0161d2000000     0c68 2025e049f331 b64a [STOP LEFT]
33 f6 0000003f 70875800 0161d2000000     3bd2 e6b62cef54c8 a937 [STOP PSA]
33 f6 0000003f 70875800 0161d2000000     3bd6 630743f0530d dc24 [STOP PSA]
33 f8 0000007f e1f57300 0161d40080c80000 0d74 9fb9a0665ff4 77a6 [DOWN RIGHT]
33 f8 0000007f e1f57300 0161d40080c80000 0d76 71b81065a2e2 0616 [DOWN RIGHT]
33 f8 0000007f c5896700 0161d40080c80000 0c6b 56fcf691e6a9 2c74 [DOWN LEFT]
33 f8 0000007f c5896700 0161d40080c80000 0c6d daf020864668 8fad [DOWN LEFT]
33 f8 0000007f 70875800 0161d40080c80000 3bdf 1ee7a0e30448 7a6b [DOWN PSA]

33 f6 0000003f 17f52300 0147c8000000     18c4 38789cb680cc bc74
33 f8 0000003f 17f52320 02ff0143010e0000 18c5 045ee107363d 59b4
33 f8 0000003f 17f52320 02ff01430105ff00 18c6 a34715cbe012 4f7f
^  ^  ^        ^        ^                ^    ^            ^CRC
^  ^  ^        ^        ^                ^    ^MAC
^  ^  ^        ^        ^                ^counter
^  ^  ^        ^        ^payload
^  ^  ^        ^source
^  ^  ^destination
^  ^length of payload
^sync, not included in CRC

It's interesting to note that at least the (presumed) destination, source, and payload field seem not included in the MAC (which is a security bug).

@TheChatty
Copy link
Contributor

TheChatty commented Jun 25, 2021

Is there a firmware file of any io homecontrol device available (to extract the signature private key)? --> There is.

PS: "RIGHT" and "LEFT" just refer to different sets of remote/window as well as "PSA" refers to psa's remote/window.

@zuckschwerdt
Copy link
Collaborator

It's a (truncated) CMAC, there is no indication of AES. And you really don't need it anyway.

@zuckschwerdt
Copy link
Collaborator

I've added support for Somfy io-homecontrol devices now. Please investigate all your devices and see if

  • id source/device ID is sensible?
  • dst_id target ID is sensible? 3f000000/7f000000 should be group calls /call all. Is there a pattern?
  • counter increments in steps of mostly 1?
  • message hast fixed content for the same action always? Please list those per sender type.
time      : 2021-06-25 15:35:36
model     : Somfy-IOHC   id        : 00eacdda
Dest ID   : 3f000000     Msg type  : f6
Message   : 0161d2000000
Counter   : 3365         MAC       : 5e0a18673d99
Integrity : CRC

@TheChatty
Copy link
Contributor

TheChatty commented Jun 25, 2021

This might not be the whole message. If I compare up/down from the same window:

33 f8 0000007f e1f57300 0161d40080c80000 0d6c 2c3a3123e6ab 7f1e [UP RIGHT]
33 f8 0000007f e1f57300 0161d40080c80000 0d6e e448de7d4e03 62d1 [UP RIGHT]
33 f8 0000007f e1f57300 0161d40080c80000 0d74 9fb9a0665ff4 77a6 [DOWN RIGHT]
33 f8 0000007f e1f57300 0161d40080c80000 0d76 71b81065a2e2 0616 [DOWN RIGHT]
^  ^  ^        ^        ^                ^    ^            ^CRC
^  ^  ^        ^        ^                ^    ^MAC
^  ^  ^        ^        ^                ^counter
^  ^  ^        ^        ^payload
^  ^  ^        ^source
^  ^  ^destination
^  ^length of payload
^sync, not included in CRC

Thus the actual command (up or down) seems to be part of the "MAC".

And I'm interested in rebuilding the signature algorithm because I actually want to control the window (not receive commands).

@zuckschwerdt
Copy link
Collaborator

Yes, 6 bytes MAC does not feel right. It might be 2 or 4 byte data plus 4 or 2 byte actual MAC. Or it could just be encrypted bytes. But based on the whole scheme of this protcol I'd guess it's : fixed header + variable payload + checks (with checks being CMAC and CRC).
Try to catch as many packets as possible, log preferably in JSON, and post a file here.
Perhaps you can roll on of the senders counter up to match another one? That should be interesting. (PSA is way of, but LEFT can catch up to RIGHT in ~256 clicks...)
Worst case log 65536 MACs and then table them :p -- it will also show if there is there is data in those.

@TheChatty
Copy link
Contributor

TheChatty commented Jun 25, 2021

Single button push usually increments counter by 2 thus I only had to push ~128 times ("down" btw). When counter was similar I produced a couple of same-counter-logs:

{"time" : "2021-06-25 17:49:07", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fc58967000161d40080c800000d9a87ac970b53d1d80d"}], "codes" : ["{224}33f80000007fc58967000161d40080c800000d9a87ac970b53d1d80d"]}
{"time" : "2021-06-25 17:50:37", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fe1f573000161d40080c800000d9a4c0e4a0e45aa995d"}], "codes" : ["{224}33f80000007fe1f573000161d40080c800000d9a4c0e4a0e45aa995d"]}
{"time" : "2021-06-25 17:49:08", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fc58967000161d40080c800000d9cf610e5e0eb9f6ba1"}], "codes" : ["{224}33f80000007fc58967000161d40080c800000d9cf610e5e0eb9f6ba1"]}
{"time" : "2021-06-25 17:50:39", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fe1f573000161d40080c800000d9cec44bf478a060cad"}], "codes" : ["{224}33f80000007fe1f573000161d40080c800000d9cec44bf478a060cad"]}
{"time" : "2021-06-25 17:49:11", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fc58967000161d40080c800000d9e10707b9a1f4aed84"}], "codes" : ["{224}33f80000007fc58967000161d40080c800000d9e10707b9a1f4aed84"]}
{"time" : "2021-06-25 17:50:41", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fe1f573000161d40080c800000d9ede2cc3c1117af8fd"}], "codes" : ["{224}33f80000007fe1f573000161d40080c800000d9ede2cc3c1117af8fd"]}
{"time" : "2021-06-25 17:49:13", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fc58967000161d40080c800000da011280dad6fe7b06a"}], "codes" : ["{224}33f80000007fc58967000161d40080c800000da011280dad6fe7b06a"]}
{"time" : "2021-06-25 17:50:43", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fe1f573000161d40080c800000da0209550b7e3530a35"}], "codes" : ["{224}33f80000007fe1f573000161d40080c800000da0209550b7e3530a35"]}
{"time" : "2021-06-25 17:49:15", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fc58967000161d40080c800000da2445f4c017d240cde"}], "codes" : ["{224}33f80000007fc58967000161d40080c800000da2445f4c017d240cde"]}
{"time" : "2021-06-25 17:50:46", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fe1f573000161d40080c800000da2877cc2f46a388a5c"}], "codes" : ["{224}33f80000007fe1f573000161d40080c800000da2877cc2f46a388a5c"]}
{"time" : "2021-06-25 17:49:16", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fc58967000161d40080c800000da4787e20402f196b43"}], "codes" : ["{224}33f80000007fc58967000161d40080c800000da4787e20402f196b43"]}
{"time" : "2021-06-25 17:50:47", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fe1f573000161d40080c800000da44412916d3fe642b8"}], "codes" : ["{224}33f80000007fe1f573000161d40080c800000da44412916d3fe642b8"]}
{"time" : "2021-06-25 17:49:17", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fc58967000161d40080c800000da633a9c2c0cc665e5d"}], "codes" : ["{224}33f80000007fc58967000161d40080c800000da633a9c2c0cc665e5d"]}
{"time" : "2021-06-25 17:50:49", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fe1f573000161d40080c800000da60eb34055b18f1209"}], "codes" : ["{224}33f80000007fe1f573000161d40080c800000da60eb34055b18f1209"]}
{"time" : "2021-06-25 17:49:19", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fc58967000161d40080c800000da8b3f7dd7a366fde5e"}], "codes" : ["{224}33f80000007fc58967000161d40080c800000da8b3f7dd7a366fde5e"]}
{"time" : "2021-06-25 17:50:51", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fe1f573000161d40080c800000da807c9a103761b1f5b"}], "codes" : ["{224}33f80000007fe1f573000161d40080c800000da807c9a103761b1f5b"]}
{"time" : "2021-06-25 17:49:20", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fc58967000161d40080c800000daa80075cf2e7bc6064"}], "codes" : ["{224}33f80000007fc58967000161d40080c800000daa80075cf2e7bc6064"]}
{"time" : "2021-06-25 17:50:53", "model" : "uart", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 224, "data" : "33f80000007fe1f573000161d40080c800000daaeb6adf4f8fad3404"}], "codes" : ["{224}33f80000007fe1f573000161d40080c800000daaeb6adf4f8fad3404"]}

@zuckschwerdt
Copy link
Collaborator

zuckschwerdt commented Jun 25, 2021

Great! You are right then, there is data in the encrypted field, not just a MAC over the counter.

f8 0000007f e1f57300 0161d40080c80000 0d9a 4c0e4a0e45aa 995d
f8 0000007f c5896700 0161d40080c80000 0d9a 87ac970b53d1 d80d
f8 0000007f e1f57300 0161d40080c80000 0d9c ec44bf478a06 0cad
f8 0000007f c5896700 0161d40080c80000 0d9c f610e5e0eb9f 6ba1
f8 0000007f c5896700 0161d40080c80000 0d9e 10707b9a1f4a ed84
f8 0000007f e1f57300 0161d40080c80000 0d9e de2cc3c1117a f8fd
f8 0000007f c5896700 0161d40080c80000 0da0 11280dad6fe7 b06a
f8 0000007f e1f57300 0161d40080c80000 0da0 209550b7e353 0a35
f8 0000007f c5896700 0161d40080c80000 0da2 445f4c017d24 0cde
f8 0000007f e1f57300 0161d40080c80000 0da2 877cc2f46a38 8a5c
f8 0000007f e1f57300 0161d40080c80000 0da4 4412916d3fe6 42b8
f8 0000007f c5896700 0161d40080c80000 0da4 787e20402f19 6b43
f8 0000007f e1f57300 0161d40080c80000 0da6 0eb34055b18f 1209
f8 0000007f c5896700 0161d40080c80000 0da6 33a9c2c0cc66 5e5d
f8 0000007f e1f57300 0161d40080c80000 0da8 07c9a103761b 1f5b
f8 0000007f c5896700 0161d40080c80000 0da8 b3f7dd7a366f de5e
f8 0000007f c5896700 0161d40080c80000 0daa 80075cf2e7bc 6064
f8 0000007f e1f57300 0161d40080c80000 0daa eb6adf4f8fad 3404

@TheChatty
Copy link
Contributor

Thus I'd need a log of 32k pushes (+2/push) of up, 32k pushes of down and 32k pushes of stop be able to control the blinds. And then again for the other window ;-)

@dwarning
Copy link
Author

dwarning commented Jun 25, 2021

Hello again,
these guy comes to another conclusion https://community.openhab.org/t/io-homecontrol-velux-somethings-in-the-bush/11413/223
And there are other hints in web that io-homecontrol is using AES.

@zuckschwerdt
Copy link
Collaborator

Great find. AES is 128-bit-block based, so there is padding and truncation.
The fixed IV is not a bug or problem -- you'd need to transmit a variable IV anyway, otherwise.

The CRC-16 is not 0x8408 but the standard 0x1021 but with bit reflection -- note that (implied)top and bottom bit are always set for a proper CRC.

@zuckschwerdt
Copy link
Collaborator

At a closer look the linked docs are for a wired communication, not radio. And since we only have 6 bytes of encryption it's either just a truncated CMAC or some encryption scheme other than AES. It could be as simple as a 16-bit LFSR generating an XOR key.

@zuckschwerdt
Copy link
Collaborator

Should be best to record a sample file with the full conversation.
rtl_433 -f 868.7M -w file_868.7M_1024k.cu8 -T 10
The quickly trigger the remote. Upload as zip.

@merbanan
Copy link
Owner

Yeah, maybe we are missing one signal. The counter jumps 2 for some reason. Maybe we are missing a packet.

@Hofyyy
Copy link
Contributor

Hofyyy commented Jun 27, 2021

I see some messages which we are not interested in.
time : 2021-06-27 19:40:28
model : Marlec-Solar Raw data : 42ee....

Anyway ... see logs attached. "Down" -> "Stop" -> "Up"
CH1_868.7M_1024k.cu8.zip
CH2_868.7M_1024k.cu8.zip

@merbanan
Copy link
Owner

Ok, this signal is pushing what the code is able to handle.

The messages are repeated 3 or 4 times.

It looks like we are missing one message indicated by the counter because there is a long preamble filling up the buffer.

The framing code fails in some cases also but the repeats will most likely recover the message because of the repeats.

@merbanan
Copy link
Owner

Down results in 5 messages transmitted.
Stop gives 3 messages.
Up gives 5 messages

Using the SNR values was a red herring. You need to set the gain fixed also. With dynamic gain things will be all over the place.

The logs we have seen so far is missing the initial reply.

@merbanan
Copy link
Owner

Anyway I looked into the actual hardware for this protocol and they are using the SiLabs EFM32. Several devices implementing the protocol seems to have this chip. This is based on information found here:

https://groups.google.com/g/openhab/c/AinJdyyDtG0

and here:

https://community.openhab.org/t/io-homecontrol-velux-somethings-in-the-bush/11413

From the info there it seems like this protocol is fairly secured. The mcu has built storage and and hardware aes engine:

https://i1.wp.com/limitedresults.com/wp-content/uploads/2021/06/arch_block.png?resize=1024%2C463&is-pending-load=1#038;ssl=1

All this together could make this system very secure because all the secrets could be handled inside the mcu. We most likely need this code to be able to figure out the protocol completely.

So we need to replicate this:

https://limitedresults.com/2021/06/enter-the-efm32-gecko/

@merbanan
Copy link
Owner

Regarding the signal I now think that the logic just simple make sure that both parties are sure of the command steps. If one party is not sending a reply the other party will probably repeat this signal.

If one is bored this can be tested by switching of one of the motors and then trying to command it whilst recording the radio transmissions.

@Hofyyy
Copy link
Contributor

Hofyyy commented Jul 4, 2021

@paller
Copy link

paller commented Feb 20, 2022

The description in this pdf is probably pretty close to the actual design. But logic dictates that before encryption can occur both parties must have the encryption key.

"The emitter (the remote control) issues its encryption key to the receiver (e.g. an io roller shutter) once and once only."

So this can happen in plain text or be scrambled somehow. Imo scrambling is the only option ie a shared secret. And with the protocol being backed by an association this is how you share the secret.

Anyway this is probably quite complicated. The fastest path forward is probably to reverse engineer a bridge or something like that.

Since it's possible to clone a remote, and it's possible to have multiple remotes per receiver, I'm thinking it's possible to sniff the AES key when this is done.
You have to press the little button with the gear icon when allowing a new remote to control a receiver, as there is no prior information shared between the existing setup and the new remote, I'm assuming the key is exchanged somewhat unencrypted.
Don't know if anyone has looked into it.

@paller
Copy link

paller commented Feb 27, 2022

I'm trying to figure out if it's possible to obtain the AES key in some way. I have used rtl_433 -f 868.7M -w filename.cu8 while

  1. Cloning one remote to another (what Velux describes as remote A to B)
  2. The TaHoma box auto detecting IO-control devices in the home, where it correctly finds both windows and is able to control them after discovery.
  3. The background chatter of the house with no IO-control being used. This is just to better understand what I'm looking for in 1 and 2.

I tried converting it into .sr and had a look at it in PulseView, doesn't mean much to me. There seems to be some modulation but it's not decoded by rtl_433.
If anyone wants to have a look at it I would be happy to upload the .cu8 files, else pointers to how I can turn it into something meaningful (demodulated data in hex) would be appreciated.

@merbanan
Copy link
Owner

@paller well I assume the aes key is not transmitted in plain text. It could be XORed with a fixed key. And because we don't know the method how to derive it the least path of resistance is to look at the actual code. Looking at actual transmissions can be time of the universe hard. Looking through the code is a year hard.

I don't exactly remember the logic but I still think my conclusion stands.

Anyway this should work:

rtl_433 -c 0 -R 0 -X "n=uart,m=FSK_PCM,s=26,l=26,r=300,preamble=5555ff,decode_uart" -f 868.7M

@manny73
Copy link

manny73 commented May 13, 2022

Hi,
from few days, I have an "eolis 3D wirefree" wind sensor and the superb rtl_433 send to my mqtt broker some data, but perhaps the data are incomplete. For better decoding io-homecontrollorer protocol, below I report some example

JSON received on the broker mqtt

{
"time": "2022-05-13T12:02:36",
"protocol": 189,
"model": "Somfy-IOHC",
"id": 2524602,
"dst_id": 1057226752,
"msg_type": 246,
"msg": "0927d1000000",
"counter": 2583,
"mac": "cc106de9fc0c",
"mic": "CRC"
}

{
"time": "2022-05-13T12:02:36",
"protocol": 189,
"model": "Somfy-IOHC",
"id": 2524602,
"dst_id": -16777216,
"msg_type": 246,
"msg": "0927d1000000",
"counter": 2584,
"mac": "92ab4ea62d88",
"mic": "CRC"
}

{
"time": "2022-05-13T12:02:36",
"protocol": 189,
"model": "Somfy-IOHC",
"id": 2524602,
"dst_id": 2130968576,
"msg_type": 246,
"msg": "0927d1000000",
"counter": 2585,
"mac": "afe360b970d0",
"mic": "CRC"
}

Code from shell

rtl_433 -d 1 -c 0 -R 0 -X "n=uart,m=FSK_PCM,s=26,l=26,r=300,preamble=5555ff,decode_uart" -f 868.7M

time : 2022-05-13 11:20:51
model : uart count : 1 num_rows : 1 rows :
len : 160 data : 33f60000043fba8526000927d10000000a11a860
codes : {160}33f60000043fba8526000927d10000000a11a860


time : 2022-05-13 11:20:51
model : uart count : 1 num_rows : 1 rows :
len : 208 data : 33f60000043fba8526000927d10000000a11a860b8eefd1dc479
codes : {208}33f60000043fba8526000927d10000000a11a860b8eefd1dc479


time : 2022-05-13 11:20:51
model : uart count : 1 num_rows : 1 rows :
len : 72 data : 33f60000043fba8526
codes : {72}33f60000043fba8526


time : 2022-05-13 11:20:51
model : uart count : 1 num_rows : 1 rows :
len : 208 data : 33f60000043fba8526000927d10000000a11a860b8eefd1dc479
codes : {208}33f60000043fba8526000927d10000000a11a860b8eefd1dc479


time : 2022-05-13 11:20:51
model : uart count : 1 num_rows : 1 rows :
len : 208 data : 33f6000000ffba8526000927d10000000a12a8518f0be7f34426
codes : {208}33f6000000ffba8526000927d10000000a12a8518f0be7f34426


time : 2022-05-13 11:20:51
model : uart count : 1 num_rows : 1 rows :
len : 200 data : 33f6000000ffba8526000927d10000000a12a8518f0be7f344
codes : {200}33f6000000ffba8526000927d10000000a12a8518f0be7f344


time : 2022-05-13 11:20:51
model : uart count : 1 num_rows : 1 rows :
len : 208 data : 33f6000000ffba8526000927d10000000a12a8518f0be7f34426
codes : {208}33f6000000ffba8526000927d10000000a12a8518f0be7f34426


time : 2022-05-13 11:20:51
model : uart count : 1 num_rows : 1 rows :
len : 208 data : 33f6000000ffba8526000927d10000000a12a8518f0be7f34426
codes : {208}33f6000000ffba8526000927d10000000a12a8518f0be7f34426


time : 2022-05-13 11:20:51
model : uart count : 1 num_rows : 1 rows :
len : 208 data : 33f60000047fba8526000927d10000000a13917d383cd8c2f5f8
codes : {208}33f60000047fba8526000927d10000000a13917d383cd8c2f5f8


time : 2022-05-13 11:20:51

Congrat for your awesome great work

@mtdcr
Copy link
Contributor

mtdcr commented Dec 1, 2022

I submitted #2258 to improve packet detection for both one- and two-way remotes at the parser level. Feedback from subscribers of this issue would be welcome.

@obones
Copy link
Contributor

obones commented Jan 9, 2023

For what it's worth, there is an entire repository dedicated to decoding the protocol: https://github.com/Velocet/iown-homecontrol
It has a reference to this discussion, I thus thought it would be interesting to cross reference it.

@druckgott
Copy link

Does it maybe work if we have enough examples to use chatgpt to decode some connections in the code and to analyze the code, I'm really interesting in this because I have 6 shutters and I don't want to by 2 boxes to have this working with homatoc 🤔

@beaune33
Copy link

beaune33 commented Jun 7, 2023

The Link layer seems to be encoded already: https://github.com/Aldohrs/iown-homecontrol/blob/main/LinkLayer.md. Does this include the missing information here?

@merbanan
Copy link
Owner

merbanan commented Jun 7, 2023

Yes it looks fairly complete. We could add aes support and key input via command line. Then we could decode messages for real.

@zuckschwerdt
Copy link
Collaborator

We could add aes support and key input via command line.

We should establish some kind of default post-processor to do these things in a flexible way. It should be transparent but enrich with decoded and aggregated data and possibly de-duplicate.

But there are things like https://github.com/kokke/tiny-AES-c and OpenSSL could be employed also.

@beaune33
Copy link

beaune33 commented Jun 7, 2023

That would be great :-)

@gdt gdt added the device support Request for a new/improved device decoder label Sep 25, 2023
@gdt
Copy link
Collaborator

gdt commented Oct 14, 2023

Where are we on this issue? Is there a path to adding support to rtl_433 at least in part? Even if a flex decoder with a comment linking to the other project. I would like to see us capture information from issues into the code base and close the issues.

@gdt gdt added the feedback request for more information; may be closed id 30d if not received label Oct 14, 2023
@mtdcr
Copy link
Contributor

mtdcr commented Oct 15, 2023

I guess it's pretty complete since #2258 was merged. Of course it would be possible to make the output more verbose, if that's wanted.

Commands get transmitted without being encrypted. AES would only be needed to verify signatures.

@gdt
Copy link
Collaborator

gdt commented Oct 15, 2023

Do you mean "this issue should be closed"? That's how I interpret your comments.

@beaune33
Copy link

Wasn’t the question how to figure out the right encryption key a main topic in this discussion? As far as I understand the situation, this information is available now, but there is no implementation using it. Am I wrong?

@gdt
Copy link
Collaborator

gdt commented Oct 15, 2023

Issues are not supposed to be questions :-) I am trying to ask the question: Given that a PR was merged, of the desired functionality, what is missing, and is anyone actually working on it. Right now we have an issue that cannot be absorbed in 30s and I don't know which way is up.

@druckgott
Copy link

Is this now working?

@gdt
Copy link
Collaborator

gdt commented Jun 6, 2024

We still need someone to figure out what's done, what's next, and do it. This issue is too hard to understand.

@gdt gdt added the inactive issue is valid but no one is working on it label Jun 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
device support Request for a new/improved device decoder feedback request for more information; may be closed id 30d if not received inactive issue is valid but no one is working on it
Projects
None yet
Development

No branches or pull requests