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

Change somfy_iohc to recognize more messages #2258

Merged
merged 2 commits into from
Jan 22, 2023
Merged

Conversation

mtdcr
Copy link
Contributor

@mtdcr mtdcr commented Dec 1, 2022

  • Messages can be as short as 11 bytes.
  • Message length has 5 bits instead of 4.
  • Flags were assumed to be constant, causing two-way remotes not to get recognized.
  • The message type (command id) is not indicated by the 1st but the 9th byte.
  • Trailing bytes were not removed, leading to invalid length and failing CRC.
  • Sequence numbers and MAC are limited to authenticated one-way frames.

This was briefly tested using both one- and two-way remotes.

- Messages can be as short as 11 bytes.
- Message length has 5 bits instead of 4.
- Flags were assumed to be constant, causing two-way remotes not to get recognized.
- The message type (command id) is not indicated by the 1st but the 9th byte.
- Trailing bytes were not removed, leading to invalid length and failing CRC.
- Sequence numbers and MAC are limited to authenticated one-way frames.

This was briefly tested using both one- and two-way remotes.
unsigned offset = bitbuffer_search(bitbuffer, 0, 0, preamble_pattern, 24) + 24;
if (offset + 19 * 10 >= bitbuffer->bits_per_row[0])
unsigned offset = bitbuffer_search(bitbuffer, 0, 0, preamble_pattern, 24);
if (offset == bitbuffer->bits_per_row[0])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use >= to be safe

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Safe from what?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API changes. bitbuffer_search() does not guarantee any particular return value.

offset += 24;

int num_bits = bitbuffer->bits_per_row[0] - offset;
if (num_bits <= 0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check can never be true, remove.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this because of the cast to size_t below. This way a reviewer will see it's safe to cast, even without knowing the data type or value range of bits_per_row[0].

Using <= instead of < was just an optimization, because it's possible to find the preamble_pattern without following data, therefore getting num_bits==0, right?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, but bitbuffer->bits_per_row[0] - offset >= 0 is checked by excluding offset >= bitbuffer->bits_per_row[0] 3 lines above. Modern compilers will infer that and bug us with "condition is constant".

return DECODE_ABORT_EARLY;

unsigned num_bits = bitbuffer->bits_per_row[0] - offset;
num_bits = MIN(num_bits, sizeof (b) * 8);
if ((size_t)num_bits > sizeof b * 8)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keep the parens on sizeof and add braces for the block, otherwise maybe keep MIN

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why braces? Other single-line blocks don't have any. sizeof is an operator, but well... I'll change it back to MIN with a cast.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Operator, yes, that's why sizeof (x) is prefered to sizeof(x). The sizeof x * y just looks sketchy at a quick glance.
Newer and changed code should preferably use braces, even for single-line blocks -- the compiler and linter will warn on mishaps, still it's just an accident waiting to happen.


if (msg.protocol_mode == 1)
data = data_append(data,
"counter", "Counter", DATA_INT, msg.seq_nr,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also use DATA_COND here an put in the data_make above.
E.g.
"counter", "Counter", DATA_COND, msg.protocol_mode == 1, DATA_INT, msg.seq_nr,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw that and thought it would obfuscate the code. Therefore I chose to avoid it.

NULL);
/* clang-format on */

if (decoder->verbose) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a good idea to have decoder data depended on verbosity level.
If this is just debug output please use decoder_logf()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It clutters the output, but some people may want to see it. According to the help screen, -vv is supposed to make decoders verbose. It didn't work for me, FWIW. Feel free to adapt it. It's not debug output, as it outputs received protocol data.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rule we try to follow is that data on the air should be translated as straight as possible to what is output. So we want it all. It is up to the consumer/presentation layer to select what data to use.

@@ -91,60 +91,123 @@ Example packets:

#include "decoder.h"

struct iohc_msg {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really need a struct? I.e. using just e.g. iohc_end_flag or msg_end_flag would be simpler to maintain.
Otherwise you will need to put a @fn on the doc-comment above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a struct is both clean and easy to initialize to zero. There's no way it would add maintenance burden per se, only if you insist on adding documentation. As you'd accept the struct members as standalone variables without documentation, adding it to the struct seems rather pointless. It's not in a shared header file anyway.

@zuckschwerdt
Copy link
Collaborator

Great stuff, looks good. Thanks!

@mtdcr
Copy link
Contributor Author

mtdcr commented Dec 1, 2022

Thanks for you review! I added another commit reintroducing the use of the MIN macro. I'll stop here, because I'm not interested in discussing style preferences of yet another project just to contribute a single patch. You can modify it to suit your needs, if you like to.

@zuckschwerdt
Copy link
Collaborator

not interested in discussing style preferences of yet another project

Fair enough. The work analyzing and coding the protocol is appreciated.

TBH style preferences here are mostly "same dumb simple in all decoders" -- with ~200 decoders any "smart" or "neat" will cause headache when e.g. refactoring with some regex is needed.

@Velocet
Copy link

Velocet commented Dec 29, 2022

@mtdcr / @zuckschwerdt You both should have a look at iown-homecontrol
The protocol is mainly deciphered and the „encryption“ is broken and documented. You will find all relevant info there.

@zuckschwerdt zuckschwerdt merged commit b00641c into merbanan:master Jan 22, 2023
obones pushed a commit to obones/rtl_433 that referenced this pull request Jan 30, 2023
- Messages can be as short as 11 bytes.
- Message length has 5 bits instead of 4.
- Flags were assumed to be constant, causing two-way remotes not to get recognized.
- The message type (command id) is not indicated by the 1st but the 9th byte.
- Trailing bytes were not removed, leading to invalid length and failing CRC.
- Sequence numbers and MAC are limited to authenticated one-way frames.

This was briefly tested using both one- and two-way remotes.
andrewjw pushed a commit to andrewjw/rtl_433 that referenced this pull request Sep 29, 2023
- Messages can be as short as 11 bytes.
- Message length has 5 bits instead of 4.
- Flags were assumed to be constant, causing two-way remotes not to get recognized.
- The message type (command id) is not indicated by the 1st but the 9th byte.
- Trailing bytes were not removed, leading to invalid length and failing CRC.
- Sequence numbers and MAC are limited to authenticated one-way frames.

This was briefly tested using both one- and two-way remotes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants