1 /* LightwaveRF protocol
3 * Stub for decoding test data only
5 * Reference: https://wiki.somakeit.org.uk/wiki/LightwaveRF_RF_Protocol
7 * Copyright (C) 2015 Tommy Vestermark
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
16 /// Decode a nibble from byte value
17 /// Will return -1 if invalid byte is input
18 int lightwave_rf_nibble_from_byte(uint8_t in) {
19 int nibble = -1; // Default error
21 case 0xF6: nibble = 0x0; break;
22 case 0xEE: nibble = 0x1; break;
23 case 0xED: nibble = 0x2; break;
24 case 0xEB: nibble = 0x3; break;
25 case 0xDE: nibble = 0x4; break;
26 case 0xDD: nibble = 0x5; break;
27 case 0xDB: nibble = 0x6; break;
28 case 0xBE: nibble = 0x7; break;
29 case 0xBD: nibble = 0x8; break;
30 case 0xBB: nibble = 0x9; break;
31 case 0xB7: nibble = 0xA; break;
32 case 0x7E: nibble = 0xB; break;
33 case 0x7D: nibble = 0xC; break;
34 case 0x7B: nibble = 0xD; break;
35 case 0x77: nibble = 0xE; break;
36 case 0x6F: nibble = 0xF; break;
37 // default: // Just return error
43 static int lightwave_rf_callback(bitbuffer_t *bitbuffer) {
44 bitrow_t *bb = bitbuffer->bb;
47 // Transmitted pulses are always 72
48 // Pulse 72 (delimiting "1" is not demodulated, as gap becomes End-Of-Message - thus expected length is 71
49 if ((bitbuffer->bits_per_row[0] == 71)
50 && (bitbuffer->num_rows == 1)) // There should be only one message (and we use the rest...)
52 // Polarity is inverted
53 bitbuffer_invert(bitbuffer);
55 // Expand all "0" to "10" (bit stuffing)
56 // row_in = 0, row_out = 1
57 bitbuffer_add_row(bitbuffer);
58 for (unsigned n=0; n < bitbuffer->bits_per_row[0]; ++n) {
59 if (bitrow_get_bit(bb[0], n)) {
60 bitbuffer_add_bit(bitbuffer, 1);
62 bitbuffer_add_bit(bitbuffer, 1);
63 bitbuffer_add_bit(bitbuffer, 0);
67 // Check length is correct
68 // Due to encoding there will be two "0"s per byte, thus message grows to 91 bits
69 if (bitbuffer->bits_per_row[1] != 91) return 0;
71 // Check initial delimiter bit is "1"
73 uint8_t delimiter_bit = bitrow_get_bit(bb[1], bit_idx++);
74 if (delimiter_bit == 0) return 0; // Decode error
76 // Strip delimiter bits
77 // row_in = 1, row_out = 2
78 bitbuffer_add_row(bitbuffer);
79 for(unsigned n=0; n<10; ++n) { // We have 10 bytes
80 delimiter_bit = bitrow_get_bit(bb[1], bit_idx++);
81 if (delimiter_bit == 0) return 0; // Decode error
83 for(unsigned m=0; m<8; ++m) {
84 bitbuffer_add_bit(bitbuffer, bitrow_get_bit(bb[1], bit_idx++));
87 // Final delimiter bit will be missing - so do not check...
89 // Decode bytes to nibbles
90 // row_in = 2, row_out = 3
91 bitbuffer_add_row(bitbuffer);
92 for(unsigned n=0; n<10; ++n) { // We have 10 bytes/nibbles
93 int nibble = lightwave_rf_nibble_from_byte(bb[2][n]);
96 fprintf(stderr, "LightwaveRF. Nibble decode error %X, idx: %u\n", bb[2][n], n);
97 bitbuffer_print(bitbuffer);
99 return 0; // Decode error
101 for (unsigned m=0; m<4; ++m) { // Add nibble one bit at a time...
102 bitbuffer_add_bit(bitbuffer, (nibble & (8 >> m)) >> (3-m));
106 // Print out generic decode
107 // Decoded nibbles are in row 3
108 fprintf(stdout, "LightwaveRF:\n");
109 fprintf(stdout, "ID = 0x%X%X%X\n", bb[3][2], bb[3][3], bb[3][4]);
110 fprintf(stdout, "Subunit = %u\n", (bb[3][1] & 0xF0) >> 4);
111 fprintf(stdout, "Command = %u\n", bb[3][1] & 0x0F);
112 fprintf(stdout, "Parameter = %u\n", bb[3][0]);
115 bitbuffer_print(bitbuffer);
116 fprintf(stderr, " Row 0 = Input, Row 1 = Zero bit stuffing, Row 2 = Stripped delimiters, Row 3 = Decoded nibbles\n");
126 r_device lightwave_rf = {
127 .name = "LightwaveRF",
128 .modulation = OOK_PULSE_PPM_RAW,
129 .short_limit = 750, // Short gap 250µs, long gap 1250µs, (Pulse width is 250µs)
130 .long_limit = 1500, //
131 .reset_limit = 1500, // Gap between messages is unknown so let us get them individually
132 .json_callback = &lightwave_rf_callback,