X-Git-Url: https://git.rvb.name/rtl-433.git/blobdiff_plain/ca13278b24eb61443559bcb61e64627fba3d8823..6d15c6f967221af825cf84e3ed12b96c763b127b:/src/devices/lightwave_rf.c diff --git a/src/devices/lightwave_rf.c b/src/devices/lightwave_rf.c new file mode 100644 index 0000000..161e60c --- /dev/null +++ b/src/devices/lightwave_rf.c @@ -0,0 +1,138 @@ +/* LightwaveRF protocol + * + * Stub for decoding test data only + * + * Reference: https://wiki.somakeit.org.uk/wiki/LightwaveRF_RF_Protocol + * + * Copyright (C) 2015 Tommy Vestermark + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include "rtl_433.h" + + +/// Decode a nibble from byte value +/// Will return -1 if invalid byte is input +int lightwave_rf_nibble_from_byte(uint8_t in) { + int nibble = -1; // Default error + switch(in) { + case 0xF6: nibble = 0x0; break; + case 0xEE: nibble = 0x1; break; + case 0xED: nibble = 0x2; break; + case 0xEB: nibble = 0x3; break; + case 0xDE: nibble = 0x4; break; + case 0xDD: nibble = 0x5; break; + case 0xDB: nibble = 0x6; break; + case 0xBE: nibble = 0x7; break; + case 0xBD: nibble = 0x8; break; + case 0xBB: nibble = 0x9; break; + case 0xB7: nibble = 0xA; break; + case 0x7E: nibble = 0xB; break; + case 0x7D: nibble = 0xC; break; + case 0x7B: nibble = 0xD; break; + case 0x77: nibble = 0xE; break; + case 0x6F: nibble = 0xF; break; + // default: // Just return error + } + return nibble; +} + + +static int lightwave_rf_callback(bitbuffer_t *bitbuffer) { + bitrow_t *bb = bitbuffer->bb; + + // Validate package + // Transmitted pulses are always 72 + // Pulse 72 (delimiting "1" is not demodulated, as gap becomes End-Of-Message - thus expected length is 71 + if ((bitbuffer->bits_per_row[0] == 71) + && (bitbuffer->num_rows == 1)) // There should be only one message (and we use the rest...) + { + // Polarity is inverted + bitbuffer_invert(bitbuffer); + + // Expand all "0" to "10" (bit stuffing) + // row_in = 0, row_out = 1 + bitbuffer_add_row(bitbuffer); + for (unsigned n=0; n < bitbuffer->bits_per_row[0]; ++n) { + if (bitrow_get_bit(bb[0], n)) { + bitbuffer_add_bit(bitbuffer, 1); + } else { + bitbuffer_add_bit(bitbuffer, 1); + bitbuffer_add_bit(bitbuffer, 0); + } + } + + // Check length is correct + // Due to encoding there will be two "0"s per byte, thus message grows to 91 bits + if (bitbuffer->bits_per_row[1] != 91) return 0; + + // Check initial delimiter bit is "1" + unsigned bit_idx = 0; + uint8_t delimiter_bit = bitrow_get_bit(bb[1], bit_idx++); + if (delimiter_bit == 0) return 0; // Decode error + + // Strip delimiter bits + // row_in = 1, row_out = 2 + bitbuffer_add_row(bitbuffer); + for(unsigned n=0; n<10; ++n) { // We have 10 bytes + delimiter_bit = bitrow_get_bit(bb[1], bit_idx++); + if (delimiter_bit == 0) return 0; // Decode error + + for(unsigned m=0; m<8; ++m) { + bitbuffer_add_bit(bitbuffer, bitrow_get_bit(bb[1], bit_idx++)); + } + } + // Final delimiter bit will be missing - so do not check... + + // Decode bytes to nibbles + // row_in = 2, row_out = 3 + bitbuffer_add_row(bitbuffer); + for(unsigned n=0; n<10; ++n) { // We have 10 bytes/nibbles + int nibble = lightwave_rf_nibble_from_byte(bb[2][n]); + if (nibble < 0) { + if (debug_output) { + fprintf(stderr, "LightwaveRF. Nibble decode error %X, idx: %u\n", bb[2][n], n); + bitbuffer_print(bitbuffer); + } + return 0; // Decode error + } + for (unsigned m=0; m<4; ++m) { // Add nibble one bit at a time... + bitbuffer_add_bit(bitbuffer, (nibble & (8 >> m)) >> (3-m)); + } + } + + // Print out generic decode + // Decoded nibbles are in row 3 + fprintf(stdout, "LightwaveRF:\n"); + fprintf(stdout, "ID = 0x%X%X%X\n", bb[3][2], bb[3][3], bb[3][4]); + fprintf(stdout, "Subunit = %u\n", (bb[3][1] & 0xF0) >> 4); + fprintf(stdout, "Command = %u\n", bb[3][1] & 0x0F); + fprintf(stdout, "Parameter = %u\n", bb[3][0]); + + if (debug_output) { + bitbuffer_print(bitbuffer); + fprintf(stderr, " Row 0 = Input, Row 1 = Zero bit stuffing, Row 2 = Stripped delimiters, Row 3 = Decoded nibbles\n"); + } + + + return 1; + } + return 0; +} + + +r_device lightwave_rf = { + .name = "LightwaveRF", + .modulation = OOK_PULSE_PPM_RAW, + .short_limit = 750, // Short gap 250µs, long gap 1250µs, (Pulse width is 250µs) + .long_limit = 1500, // + .reset_limit = 1500, // Gap between messages is unknown so let us get them individually + .json_callback = &lightwave_rf_callback, + .disabled = 1, + .demod_arg = 0, +}; + + +