Редизайн на основе текущей ветки мейнстрима + новые устройства.
[rtl-433.git] / src / devices / lightwave_rf.c
1 /* LightwaveRF protocol
2  *
3  * Stub for decoding test data only
4  *
5  * Reference: https://wiki.somakeit.org.uk/wiki/LightwaveRF_RF_Protocol
6  *
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.
12  */
13 #include "rtl_433.h"
14
15
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
20         switch(in) {
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
38         }
39         return nibble;
40 }
41
42
43 static int lightwave_rf_callback(bitbuffer_t *bitbuffer) {
44         bitrow_t *bb = bitbuffer->bb;
45
46         // Validate package
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...) 
51         {
52                 // Polarity is inverted
53                 bitbuffer_invert(bitbuffer);
54
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);
61                         } else {
62                                 bitbuffer_add_bit(bitbuffer, 1);
63                                 bitbuffer_add_bit(bitbuffer, 0);
64                         }
65                 }
66
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;
70
71                 // Check initial delimiter bit is "1"
72                 unsigned bit_idx = 0;
73                 uint8_t delimiter_bit = bitrow_get_bit(bb[1], bit_idx++);
74                 if (delimiter_bit == 0) return 0;       // Decode error
75
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
82
83                         for(unsigned m=0; m<8; ++m) {
84                                 bitbuffer_add_bit(bitbuffer, bitrow_get_bit(bb[1], bit_idx++));
85                         }
86                 }
87                 // Final delimiter bit will be missing - so do not check...
88
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]);
94                         if (nibble < 0) {
95                                 if (debug_output) {
96                                         fprintf(stderr, "LightwaveRF. Nibble decode error %X, idx: %u\n", bb[2][n], n);
97                                         bitbuffer_print(bitbuffer);
98                                 }
99                                 return 0;       // Decode error
100                         }
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));
103                         }
104                 }
105
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]);
113
114                 if (debug_output) {
115                         bitbuffer_print(bitbuffer);
116                         fprintf(stderr, "  Row 0 = Input, Row 1 = Zero bit stuffing, Row 2 = Stripped delimiters, Row 3 = Decoded nibbles\n");
117                 }
118
119
120                 return 1;
121         }
122         return 0;
123 }
124
125
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,
133         .disabled               = 1,
134         .demod_arg              = 0,
135 };
136
137
138