Bugfixes
[rtl-433.git] / src / devices / dsc.c
1 /* DSC sensor
2  *
3  *
4  * Decode DSC security contact messages
5  *
6  * Copyright (C) 2015 Tommy Vestermark
7  * Copyright (C) 2015 Robert C. Terzi
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  * DSC - Digital Security Controls 433 Mhz Wireless Security Contacts
14  *       doors, windows, smoke, CO2, water, 
15  *
16  * Protcol Description available in this FCC Report for FCC ID F5300NB912
17  *  https://apps.fcc.gov/eas/GetApplicationAttachment.html?id=100988
18  *
19  * General Packet Description
20  * - Packets are 26.5 mS long
21  * - Packets start with 2.5 mS of constant modulation for most sensors
22  *   Smoke/CO2/Fire sensors start with 5.6 mS of constant modulation
23  * - The length of a bit is 500 uS, broken into two 250 uS segments.
24  *    A logic 0 is 500 uS (2 x 250 uS) of no signal.
25  *    A logic 1 is 250 uS of no signal followed by 250 uS of signal/keying
26  * - Then there are 4 sync logic 1 bits.
27  * - There is a sync/start 1 bit in between every 8 bits.
28  * - A zero byte would be 8 x 500 uS of no signal (plus the 250 uS of
29  *   silence for the first half of the next 1 bit) for a maximum total
30  *   of 4,250 uS (4.25 mS) of silence.
31  * - The last byte is a CRC with nothing after it, no stop/sync bit, so
32  *   if there was a CRC byte of 0, the packet would wind up being short
33  *   by 4 mS and up to 8 bits (48 bits total).
34  *
35  * There are 48 bits in the packet including the leading 4 sync 1 bits.
36  * This makes the packet 48 x 500 uS bits long plus the 2.5 mS preamble
37  * for a total packet length of 26.5 ms.  (smoke will be 3.1 ms longer)
38  *
39  * Packet Decoding
40  *    Check intermessage start / sync bits, every 8 bits
41  *    Byte 0   Byte 1   Byte 2   Byte 3   Byte 4   Byte 5
42  *    vvvv         v         v         v         v
43  *    SSSSdddd ddddSddd dddddSdd ddddddSd dddddddS cccccccc  Sync,data,crc
44  *    01234567 89012345 67890123 45678901 23456789 01234567  Received Bit No.
45  *    84218421 84218421 84218421 84218421 84218421 84218421  Received Bit Pos.
46  *
47  #    SSSS         S         S         S         S           Synb bit positions
48  *        ssss ssss ttt teeee ee eeeeee e eeeeeee  cccccccc  type
49  *        tttt tttt yyy y1111 22 223333 4 4445555  rrrrrrrr  
50  *
51  *  Bits: 0,1,2,3,12,21,30,39 should == 1
52  *
53  *  Status (st) = 8 bits, open, closed, tamper, repeat
54  *  Type (ty)   = 4 bits, Sensor type, really first nybble of ESN
55  *  ESN (e1-5)  = 20 bits, Electronic Serial Number: Sensor ID.
56  *  CRC (cr)    = 8 bits, CRC, type/polynom to be determined
57  *
58  * The ESN in practice is 24 bits, The type + remaining 5 nybbles, 
59  *
60  * The CRC is 8 bit, "little endian", Polynomial 0xf5, Inital value 0x3d
61  *
62  * CRC algorithm found with CRC reveng (reveng.sourceforge.net)
63  *
64  * CRC Model Parameters:
65  * width=8  poly=0xf5  init=0x3d  refin=true  refout=true  xorout=0x00  check=0xfd  name=(none)
66  *
67  */
68
69 #include "rtl_433.h"
70 #include "util.h"
71
72 #define DSC_CT_MSGLEN           5       
73 #define DSC_CT_CRC_POLY         0xf5
74 #define DSC_CT_CRC_INIT         0x3d
75
76
77 static int DSC_callback(bitbuffer_t *bitbuffer) {
78     bitrow_t *bb = bitbuffer->bb;
79     int valid_cnt = 0;
80     char time_str[LOCAL_TIME_BUFLEN];
81
82     if (debug_output > 1) {
83         fprintf(stderr,"Possible DSC Contact: ");
84         bitbuffer_print(bitbuffer);
85     }
86
87     for (int row = 0; row < bitbuffer->num_rows; row++) {
88         if (debug_output > 1 && bitbuffer->bits_per_row[row] > 0 ) {
89             fprintf(stderr,"row %d bit count %d\n", row, 
90                     bitbuffer->bits_per_row[row]);
91         }
92
93         // Number of bits in the packet should be 48 but due to the 
94         // encoding of trailing zeros is a guess based on reset_limit / 
95         // long_limit (bit period).  With current values up to 10 zero
96         // bits could be added, so it is normal to get a 58 bit packet.
97         //
98         // If the limits are changed for some reason, the max number of bits
99         // will need to be changed as there may be more zero bit padding
100         if (bitbuffer->bits_per_row[row] < 48 || 
101             bitbuffer->bits_per_row[row] > 70) {  // should be 48 at most
102             if (debug_output > 1 && bitbuffer->bits_per_row[row] > 0) {
103                 fprintf(stderr,"DSC row %d invalid bit count %d\n",
104                         row, bitbuffer->bits_per_row[row]);
105             }
106             continue;
107         }
108
109         // Validate Sync/Start bits == 1 and are in the right position
110         if (!((bb[row][0] & 0xF0) &&    // First 4 bits are start/sync bits
111               (bb[row][1] & 0x08) &&    // Another sync/start bit between
112               (bb[row][2] & 0x04) &&    // every 8 data bits
113               (bb[row][3] & 0x02) &&
114               (bb[row][4] & 0x01))) {
115             if (debug_output > 1) {
116                 fprintf(stderr,
117                         "DSC Invalid start/sync bits %02x %02x %02x %02x %02x\n",
118                         bb[row][0] & 0xF0,
119                         bb[row][1] & 0x08,
120                         bb[row][2] & 0x04,
121                         bb[row][3] & 0x02,
122                         bb[row][4] & 0x01);
123             }
124             continue;
125         }
126
127         uint8_t bytes[5];
128         uint8_t status,crc;
129         uint32_t esn;
130         uint8_t crcc1, crcc2, crcc3, crcc4, crcc5, crcc6, crcc7, crcc8;
131
132         bytes[0] = ((bb[row][0] & 0x0F) << 4) | ((bb[row][1] & 0xF0) >> 4);
133         bytes[1] = ((bb[row][1] & 0x07) << 5) | ((bb[row][2] & 0xF8) >> 3);
134         bytes[2] = ((bb[row][2] & 0x03) << 6) | ((bb[row][3] & 0xFC) >> 2);
135         bytes[3] = ((bb[row][3] & 0x01) << 7) | ((bb[row][4] & 0xFE) >> 1);
136         bytes[4] = ((bb[row][5]));
137
138         // XXX change to debug_output
139         if (debug_output) 
140             fprintf(stdout, "DSC Contact Raw Data: %02X %02X %02X %02X %02X\n",
141                 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4]);
142
143         status = bytes[0];
144         esn = (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]; 
145         crc = bytes[4];
146
147         local_time_str(0, time_str);
148
149         if (crc8le(bytes, DSC_CT_MSGLEN, DSC_CT_CRC_POLY, DSC_CT_CRC_INIT) == 0) {
150             printf("%s DSC Contact ESN: %06X, Status: %02X, CRC: %02X\n",
151                    time_str, esn, status, crc);
152
153             valid_cnt++; // Have a valid packet.
154         } else if (debug_output) {
155             fprintf(stderr,"%s DSC Contact bad CRC: %06X, Status: %02X, CRC: %02X\n",
156                    time_str, esn, status, crc);
157         }
158     }
159
160     if (valid_cnt) {
161         return 1;
162     }
163
164     return 0;
165 }
166
167
168 r_device DSC = {
169     .name               = "DSC Security Contact",
170     .modulation         = OOK_PULSE_PCM_RZ,
171     .short_limit        = 250,  // Pulse length, 250 µs
172     .long_limit         = 500,  // Bit period, 500 µs
173     .reset_limit        = 5000, // Max gap, 
174     .json_callback      = &DSC_callback,
175     .disabled           = 1,
176     .demod_arg          = 0,
177 };
178
179
180