parent
f03710a53d
commit
72164effe4
8 changed files with 535 additions and 7 deletions
|
@ -164,7 +164,7 @@ See [CONTRIBUTING.md](./docs/CONTRIBUTING.md).
|
|||
[88] Toyota TPMS
|
||||
[89] Ford TPMS
|
||||
[90] Renault TPMS
|
||||
[91] inFactory, FreeTec NC-3982-913 temperature humidity sensor
|
||||
[91] inFactory, nor-tec, FreeTec NC-3982-913 temperature humidity sensor
|
||||
[92] FT-004-B Temperature Sensor
|
||||
[93] Ford Car Key
|
||||
[94] Philips outdoor temperature sensor (type AJ3650)
|
||||
|
@ -229,9 +229,10 @@ See [CONTRIBUTING.md](./docs/CONTRIBUTING.md).
|
|||
[153] Cotech 36-7959 wireless weather station with USB
|
||||
[154] Standard Consumption Message Plus (SCMplus)
|
||||
[155] Fine Offset Electronics WH1080/WH3080 Weather Station (FSK)
|
||||
[156] Abarth 124 / VDO TG1C TPMS Sensor
|
||||
[156] Abarth 124 Spider TPMS
|
||||
[157] Missil ML0757 weather station
|
||||
[158] Sharp SPC775
|
||||
[158] Sharp SPC775 weather station
|
||||
[159] Insteon
|
||||
|
||||
* Disabled by default, use -R n or -G
|
||||
|
||||
|
|
|
@ -166,6 +166,7 @@
|
|||
DECL(tpms_abarth124) \
|
||||
DECL(missil_ml0757) \
|
||||
DECL(sharp_spc775) \
|
||||
DECL(insteon) \
|
||||
|
||||
/* Add new decoders here. */
|
||||
|
||||
|
|
|
@ -393,7 +393,7 @@ Ford TPMS
|
|||
Renault TPMS
|
||||
.TP
|
||||
[ \fB91\fI\fP ]
|
||||
inFactory, FreeTec NC\-3982\-913 temperature humidity sensor
|
||||
inFactory, nor\-tec, FreeTec NC\-3982\-913 temperature humidity sensor
|
||||
.TP
|
||||
[ \fB92\fI\fP ]
|
||||
FT\-004\-B Temperature Sensor
|
||||
|
@ -588,14 +588,16 @@ Standard Consumption Message Plus (SCMplus)
|
|||
Fine Offset Electronics WH1080/WH3080 Weather Station (FSK)
|
||||
.TP
|
||||
[ \fB156\fI\fP ]
|
||||
Abarth 124 / VDO TG1C TPMS Sensor
|
||||
Abarth 124 Spider TPMS
|
||||
.TP
|
||||
[ \fB157\fI\fP ]
|
||||
Missil ML0757 weather station
|
||||
.TP
|
||||
[ \fB158\fI\fP ]
|
||||
Sharp SPC775
|
||||
|
||||
Sharp SPC775 weather station
|
||||
.TP
|
||||
[ \fB159\fI\fP ]
|
||||
Insteon
|
||||
|
||||
* Disabled by default, use \-R n or \-G
|
||||
.SS "Input device selection"
|
||||
|
|
|
@ -92,6 +92,7 @@ add_library(r_433 STATIC
|
|||
devices/ikea_sparsnas.c
|
||||
devices/infactory.c
|
||||
devices/inovalley-kw9015b.c
|
||||
devices/insteon.c
|
||||
devices/interlogix.c
|
||||
devices/intertechno.c
|
||||
devices/kedsum.c
|
||||
|
|
|
@ -91,6 +91,7 @@ rtl_433_SOURCES = abuf.c \
|
|||
devices/ikea_sparsnas.c \
|
||||
devices/infactory.c \
|
||||
devices/inovalley-kw9015b.c \
|
||||
devices/insteon.c \
|
||||
devices/interlogix.c \
|
||||
devices/intertechno.c \
|
||||
devices/kedsum.c \
|
||||
|
|
518
src/devices/insteon.c
Normal file
518
src/devices/insteon.c
Normal file
|
@ -0,0 +1,518 @@
|
|||
/** @file
|
||||
Insteon RF decoder
|
||||
|
||||
Copyright (C) 2020 Peter Shipley
|
||||
|
||||
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.
|
||||
**/
|
||||
|
||||
/** @fn int insteon_callback(r_device *decoder, bitbuffer_t *bitbuffer)
|
||||
|
||||
Insteon RF decoder
|
||||
|
||||
"Insteon is a home automation (domotics) technology that enables
|
||||
light switches, lights, thermostats, leak sensors, remote controls,
|
||||
motion sensors, and other electrically powered devices to interoperate
|
||||
through power lines, radio frequency (RF) communications, or both
|
||||
[ from wikipedia ]
|
||||
|
||||
the Insteon RF protocol is a series of 28 bit packets containing one byte of data
|
||||
|
||||
|
||||
Each byte (X) is encoded as 28 bits:
|
||||
> '11' followed by
|
||||
> 5 bit index number (manchester encoded)
|
||||
> 8 bit byte (manchester encoded)
|
||||
|
||||
All values are written in LSB format (Least Significant Bit first)
|
||||
|
||||
The first byte is always transmitted with a index of 32 ( 11111 )
|
||||
all following bytes are transmitted with a decrementing index count with the final byte with index 0
|
||||
|
||||
Dat index dat LSB index dat manchester '11' + manchester
|
||||
03 -> 11111 00000011 -> 11111 11000000 -> 0101010101 0101101010101010 -> 1101010101010101101010101010
|
||||
E5 -> 01011 11100101 -> 11010 10100111 -> 0101100110 0110011010010101 -> 1101011001100110011010010101
|
||||
3F -> 01010 00111111 -> 01010 11111100 -> 1001100110 0101010101011010 -> 1110011001100101010101011010
|
||||
16 -> 01001 00010110 -> 01010 11111100 -> 0110100110 1001011001101010 -> 1101101001101001011001101010
|
||||
|
||||
[Insteon RF Toolkit](https://github.com/evilpete/insteonrf/Doc)
|
||||
|
||||
## Printed packet format notation
|
||||
|
||||
*flag* **:** *to_address* **:** *from_address* : command_data crc
|
||||
|
||||
`43 : 226B3F : 2B7811 : 13 01 35`
|
||||
|
||||
## Settings
|
||||
|
||||
- Frequency: 915MHz
|
||||
- SampleRate: 1024K
|
||||
- Modulation: FSK
|
||||
|
||||
**/
|
||||
|
||||
#include "decoder.h"
|
||||
|
||||
// 1100111010101010
|
||||
static const uint8_t insteon_preamble[] = {0xCE, 0xAA};
|
||||
|
||||
#define INSTEON_PACKET_MIN 10
|
||||
#define INSTEON_PACKET_MAX 13
|
||||
#define INSTEON_PACKET_MIN_EXT 23
|
||||
#define INSTEON_PACKET_MAX_EXT 32
|
||||
#define INSTEON_BITLEN_MIN (INSTEON_PACKET_MIN * 28) + sizeof(insteon_preamble)
|
||||
#define INSTEON_PREAMBLE_LEN 16
|
||||
|
||||
|
||||
/*
|
||||
calc checksum of extended packet data
|
||||
(differs from normal packet)
|
||||
|
||||
takes an instion packet in form of a list of uint8_t
|
||||
and returns CRC in the form of a uint8_t
|
||||
|
||||
using :
|
||||
((Not(sum of cmd1..d13)) + 1) and 255
|
||||
*/
|
||||
|
||||
static uint8_t gen_ext_crc(uint8_t *dat)
|
||||
{
|
||||
uint8_t r = 0;
|
||||
|
||||
for (int i = 7; i < 22; i++) {
|
||||
r += dat[i];
|
||||
}
|
||||
|
||||
r = ~r;
|
||||
r = r + 1;
|
||||
r = (r & 0xFF);
|
||||
|
||||
return ((uint8_t)r);
|
||||
}
|
||||
|
||||
/*
|
||||
calc checksum of normal packet data
|
||||
(differs from extended packet)
|
||||
|
||||
takes an instion packet in form of a list of uint8_t
|
||||
and returns uint8_t the CRC for RF packet
|
||||
*/
|
||||
static uint8_t gen_crc(uint8_t *dat)
|
||||
{
|
||||
uint8_t r = 0;
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
r ^= dat[i];
|
||||
r ^= ((r ^ (r << 1)) & 0x0F) << 4;
|
||||
}
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
static unsigned int parse_insteon_pkt(r_device *decoder, bitbuffer_t *bits, unsigned int row, unsigned int start_pos)
|
||||
{
|
||||
uint8_t results[35] = {0};
|
||||
uint8_t results_len = 0;
|
||||
bitbuffer_t i_bits = {0};
|
||||
bitbuffer_t d_bits = {0};
|
||||
unsigned int next_pos = 0;
|
||||
uint8_t i = 0;
|
||||
uint8_t pkt_i, pkt_d;
|
||||
|
||||
// move past preamble
|
||||
start_pos += 7;
|
||||
|
||||
/*
|
||||
We are looking as something line this
|
||||
110101010101010110101010101011....
|
||||
|
||||
which we an break down as
|
||||
|
||||
11 0101010101 0101101010101010 11....
|
||||
|
||||
"11" + 10 manchester bits LSB + 16 manchester bits LSB + "11"
|
||||
|
||||
we decode this into a
|
||||
5 bits LSB (always 32 in the first block)
|
||||
8 bits LSB (flag bits for the upcoming packet
|
||||
|
||||
|
||||
Flag fields (MSB format):
|
||||
"maxhops" = (flag & 0b00000011)
|
||||
"hopsleft" = (flag & 0b00001100)
|
||||
"extended" = (flag & 0b00010000)
|
||||
"ack" = (flag & 0b00100000)
|
||||
"group" = (flag & 0b01000000)
|
||||
"bcast" = (flag & 0b10000000)
|
||||
"mtype" = (flag & 0b11100000)
|
||||
|
||||
( we can discard the 5 bit digit )
|
||||
|
||||
after this we can index forward 28 bits ( 2 + 10 + 16 )
|
||||
|
||||
*/
|
||||
|
||||
next_pos = bitbuffer_manchester_decode(bits, row, start_pos, &i_bits, 5);
|
||||
pkt_i = reverse8(i_bits.bb[0][0]);
|
||||
|
||||
next_pos = bitbuffer_manchester_decode(bits, row, next_pos, &d_bits, 8);
|
||||
pkt_d = reverse8(d_bits.bb[0][0]);
|
||||
results[results_len++] = pkt_d;
|
||||
|
||||
if (pkt_i != 31) { // should always be 31 ( 0b11111) in first block of packet
|
||||
return (DECODE_ABORT_EARLY);
|
||||
}
|
||||
|
||||
bitbuffer_extract_bytes(bits, row, start_pos + 26, &i, 2);
|
||||
// Check for packet delimiter marker bits (at least once)
|
||||
if (i != 0xc0) { // 0b11000000
|
||||
return (DECODE_FAIL_SANITY); // There should be two high bits '11' between packets
|
||||
}
|
||||
|
||||
// printBits(sizeof(d), &d);
|
||||
int extended = 0;
|
||||
|
||||
uint8_t max_pkt_len = INSTEON_PACKET_MAX;
|
||||
uint8_t min_pkt_len = INSTEON_PACKET_MIN;
|
||||
if (results[0] & 0x10) {
|
||||
extended = 1;
|
||||
max_pkt_len = INSTEON_PACKET_MAX_EXT;
|
||||
min_pkt_len = INSTEON_PACKET_MIN_EXT;
|
||||
}
|
||||
|
||||
if (decoder->verbose) {
|
||||
uint8_t buffy[4];
|
||||
fprintf(stderr, "%s\tstart_pos %u row_length %hu = %d\n",
|
||||
__func__, start_pos, bits->bits_per_row[row], (bits->bits_per_row[row] - start_pos));
|
||||
fprintf(stderr, "%s\t%s\t%-5s\t%s\t%s\t%s\n",
|
||||
__func__, "pkt_i", "pkt_d", "next", "length", "count");
|
||||
|
||||
bitbuffer_extract_bytes(bits, row, start_pos - 2, buffy, 30);
|
||||
bitrow_printf(buffy, 30, "%s\t%2d\t%02X\t%03u\t%u\t%2d\t",
|
||||
__func__, pkt_i, pkt_d, next_pos, (next_pos - start_pos), 0);
|
||||
}
|
||||
|
||||
/* Is this overkill ??
|
||||
unsigned int l;
|
||||
if(extended) {
|
||||
l = 642;
|
||||
} else {
|
||||
l = 278;
|
||||
}
|
||||
if ((bits->bits_per_row[row] - start_pos) < l) {
|
||||
if (decoder->verbose) {
|
||||
fprintf(stderr, "%s\trow to short for %s packet type\n",
|
||||
__func__, (extended ? "extended" : "regular"));
|
||||
}
|
||||
return(DECODE_ABORT_LENGTH); // row to short for packet type
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
The data is contained in 26bit blocks containing 26bit manchester
|
||||
the resulting 13bits contains 5bit of packet index
|
||||
and 8bits of data
|
||||
*/
|
||||
uint8_t prev_i=33;
|
||||
for (int j = 1; j < max_pkt_len; j++) {
|
||||
unsigned y;
|
||||
start_pos += 28;
|
||||
bitbuffer_clear(&i_bits);
|
||||
bitbuffer_clear(&d_bits);
|
||||
next_pos = bitbuffer_manchester_decode(bits, row, start_pos, &i_bits, 5);
|
||||
next_pos = bitbuffer_manchester_decode(bits, row, next_pos, &d_bits, 8);
|
||||
|
||||
y = (next_pos - start_pos);
|
||||
if (y != 26) {
|
||||
if (decoder->verbose)
|
||||
fprintf(stderr, "%s: stop %d != 26\n", __func__, y);
|
||||
break;
|
||||
}
|
||||
|
||||
// bitbuffer_extract_bytes(bits, row, start_pos -2, buff, 8);
|
||||
// printBits(sizeof(buff), buff);
|
||||
|
||||
pkt_i = reverse8(i_bits.bb[0][0]);
|
||||
pkt_d = reverse8(d_bits.bb[0][0]);
|
||||
|
||||
results[results_len++] = pkt_d;
|
||||
|
||||
if (decoder->verbose) {
|
||||
uint8_t buffy[4];
|
||||
bitbuffer_extract_bytes(bits, row, start_pos - 2, buffy, 30);
|
||||
// bitrow_printf(buffy, 30, "%s\t%2d %02X %3u\t%d\t%d\t",
|
||||
bitrow_printf(buffy, 30, "%s\t%2d\t%02X\t%03u\t%u\t%2d\t",
|
||||
__func__, pkt_i, pkt_d, next_pos, (next_pos - start_pos), j);
|
||||
// parse_insteon_pkt: curr packet (3f) { 1} d6 : 1
|
||||
}
|
||||
|
||||
// packet index should decrement
|
||||
if (pkt_i < prev_i) {
|
||||
prev_i = pkt_i;
|
||||
} else {
|
||||
return(DECODE_ABORT_EARLY);
|
||||
}
|
||||
}
|
||||
|
||||
// if (decoder->verbose > 1) {
|
||||
// for(int j=0; j < results_len; j++) {
|
||||
// printf("%d:%02X ", j, results[j]);
|
||||
// }
|
||||
// puts("\n");
|
||||
// }
|
||||
|
||||
if (results_len < min_pkt_len) {
|
||||
if (decoder->verbose > 1)
|
||||
fprintf(stderr, "%s: fail: short packet %d < 9\n", __func__, results_len);
|
||||
return (0);
|
||||
}
|
||||
|
||||
uint8_t crc_val;
|
||||
if (extended) {
|
||||
crc_val = gen_ext_crc(results);
|
||||
}
|
||||
else {
|
||||
crc_val = gen_crc(results);
|
||||
}
|
||||
|
||||
if (results[min_pkt_len - 1] != crc_val) {
|
||||
if (decoder->verbose > 1)
|
||||
fprintf(stderr, "%s: fail: bad CRC %02X != %02X %s\n", __func__, results[min_pkt_len], crc_val,
|
||||
(extended ? "extended" : ""));
|
||||
return (DECODE_FAIL_MIC);
|
||||
}
|
||||
|
||||
char pkt_from_addr[8] = {0};
|
||||
char pkt_to_addr[32] = {0};
|
||||
char pkt_formatted[256] = {0};
|
||||
char cmd_str[92] = {0};
|
||||
|
||||
snprintf(pkt_to_addr, sizeof(pkt_to_addr), "%02X%02X%02X",
|
||||
results[3], results[2], results[1]);
|
||||
snprintf(pkt_from_addr, sizeof(pkt_from_addr), "%02X%02X%02X",
|
||||
results[6], results[5], results[4]);
|
||||
|
||||
char *p = cmd_str;
|
||||
int cmd_array[32];
|
||||
int cmd_array_len = 0;
|
||||
for (int j = 7; j < min_pkt_len - 1; j++) {
|
||||
p += sprintf(p, "%02X ", results[j]);
|
||||
cmd_array[cmd_array_len++] = (int)results[j];
|
||||
}
|
||||
|
||||
char payload[35] = {0};
|
||||
p = payload;
|
||||
for (int j = 0; j < min_pkt_len; j++) {
|
||||
p += sprintf(p, "%02X", results[j]);
|
||||
}
|
||||
|
||||
snprintf(pkt_formatted, sizeof(pkt_formatted), "%02X : %s : %s : %s %02X",
|
||||
results[0], pkt_to_addr, pkt_from_addr, cmd_str, results[min_pkt_len - 1]);
|
||||
|
||||
/*
|
||||
flag = b[0]
|
||||
"maxhops" = (flag & 0b00000011)
|
||||
"hopsleft" = (flag & 0b00001100)
|
||||
"extended" = (flag & 0b00010000)
|
||||
"ack" = (flag & 0b00100000)
|
||||
"group" = (flag & 0b01000000)
|
||||
"bcast" = (flag & 0b10000000)
|
||||
"mtype" = (flag & 0b11100000)
|
||||
*/
|
||||
|
||||
int hopsmax = (results[0] & 0x03);
|
||||
int hopsleft = (results[0] >> 2) & 0x03;
|
||||
|
||||
// char hops_str[8] = {0};
|
||||
// snprintf(hops_str, sizeof(hops_str), "%d / %d",
|
||||
// (results[0] & 0x03),
|
||||
// (results[0] >> 2) & 0x03);
|
||||
|
||||
int pkt_type = (results[0] >> 5) & 0x07;
|
||||
char *messsage_text[8] = {
|
||||
"Direct Message", // 000
|
||||
"ACK of Direct Message", // 001
|
||||
"Group Cleanup Direct Message", // 010
|
||||
"ACK of Group Cleanup Direct Message", // 011
|
||||
"Broadcast Message", // 100
|
||||
"NAK of Direct Message", // 101
|
||||
"Group Broadcast Message", // 110
|
||||
"NAK of Group Cleanup Direct Message"}; // 111
|
||||
|
||||
char *pkt_type_str = messsage_text[pkt_type];
|
||||
// bitrow_printf(results, 8, "%s\tFlag", __func__);
|
||||
//fprintf(stderr, "%s: pkt_type: %02X \n", __func__, pkt_type);
|
||||
|
||||
if (decoder->verbose > 1) {
|
||||
printf("type %s\n", pkt_type_str);
|
||||
for (int j = 0; j < min_pkt_len; j++) {
|
||||
printf("%d:%02X ", j, results[j]);
|
||||
}
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
// Format data
|
||||
/*
|
||||
static int data_payload[35];
|
||||
for (int j = 0; j < min_pkt_len; j++) {
|
||||
data_payload[j] = (int)results[j];
|
||||
}
|
||||
*/
|
||||
|
||||
/* clang-format off */
|
||||
data_t *data = data_make(
|
||||
"model", "", DATA_STRING, "Insteon",
|
||||
// "id", "", DATA_INT, sensor_id,
|
||||
// "data", "Data", DATA_INT, value,
|
||||
"from_id", "From_Addr", DATA_STRING, pkt_from_addr,
|
||||
"to_id", "To_Addr", DATA_STRING, pkt_to_addr,
|
||||
"msg_type", "Message_Type", DATA_INT, pkt_type,
|
||||
"msg_str", "Message_Str", DATA_STRING, pkt_type_str,
|
||||
// "command", "Command", DATA_STRING, cmd_str,
|
||||
"extended", "Extended", DATA_INT, extended,
|
||||
// "hops", "Hops", DATA_STRING, hops_str,
|
||||
"hopsmax", "Hops_Max", DATA_INT, hopsmax,
|
||||
"hopsleft", "Hops_Left", DATA_INT, hopsleft,
|
||||
"formatted", "Packet", DATA_STRING, pkt_formatted,
|
||||
"mic", "Integrity", DATA_STRING, "CRC", // CRC, CHECKSUM, or PARITY
|
||||
"payload", "Payload", DATA_STRING, payload,
|
||||
"cmd_dat", "CMD_Data", DATA_ARRAY, data_array(cmd_array_len, DATA_INT, cmd_array),
|
||||
// "payload", "Payload", DATA_ARRAY, data_array(min_pkt_len, DATA_INT, data_payload),
|
||||
NULL);
|
||||
|
||||
/* clang-format on */
|
||||
decoder_output_data(decoder, data);
|
||||
|
||||
// Return 1 if message successfully decoded
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int insteon_callback(r_device *decoder, bitbuffer_t *bitbuffer)
|
||||
{
|
||||
// unsigned int pkt_start_pos;
|
||||
uint16_t row;
|
||||
unsigned int bit_index;
|
||||
unsigned int ret_value = 0;
|
||||
int fail_value = 0;
|
||||
// unsigned int pkt_cnt = 0;
|
||||
|
||||
// if (decoder->verbose > 2)
|
||||
// bitbuffer_debug(bitbuffer);
|
||||
|
||||
// if (decoder->verbose > 1) fprintf(stderr, "row complete row / bit_index : %d, %d\n", row, bit_index);
|
||||
|
||||
if (decoder->verbose > 1)
|
||||
fprintf(stderr, "%s: new buffer %hu rows\n", __func__, bitbuffer->num_rows);
|
||||
|
||||
bitbuffer_invert(bitbuffer);
|
||||
|
||||
/*
|
||||
* loop over all rows and look for preamble
|
||||
*/
|
||||
for (row = 0; row < bitbuffer->num_rows; ++row) {
|
||||
bit_index = 0;
|
||||
// Validate message and reject it as fast as possible : check for preamble
|
||||
|
||||
if (bitbuffer->bits_per_row[row] < INSTEON_BITLEN_MIN) {
|
||||
// if (decoder->verbose )
|
||||
// fprintf(stderr, "%s: short row row=%hu len=%hu\n", __func__, row, bitbuffer->bits_per_row[row]);
|
||||
fail_value = DECODE_ABORT_LENGTH;
|
||||
continue;
|
||||
}
|
||||
// if (decoder->verbose)
|
||||
// fprintf(stderr, "%s: New row=%d len=%d\n", __func__, row, bitbuffer->bits_per_row[row]);
|
||||
|
||||
while (1) {
|
||||
unsigned search_index = bit_index;
|
||||
int ret;
|
||||
|
||||
if ((bitbuffer->bits_per_row[row] - bit_index) < INSTEON_BITLEN_MIN) {
|
||||
// fprintf(stderr, "%s: short remainder\n", __func__);
|
||||
break;
|
||||
}
|
||||
|
||||
if (decoder->verbose > 1)
|
||||
fprintf(stderr, "%s: bitbuffer_search at row / search_index : %d, %d %d (%d)\n",
|
||||
__func__, row, search_index, bit_index, bitbuffer->bits_per_row[row]);
|
||||
|
||||
search_index = bitbuffer_search(bitbuffer, row, search_index, insteon_preamble, INSTEON_PREAMBLE_LEN);
|
||||
|
||||
if (search_index >= bitbuffer->bits_per_row[row]) {
|
||||
if (decoder->verbose > 1 && bit_index == 0)
|
||||
fprintf(stderr, "%s: insteon_preamble not found %d %d %d\n", __func__,
|
||||
search_index, bit_index, bitbuffer->bits_per_row[row]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (decoder->verbose)
|
||||
fprintf(stderr, "%s: parse_insteon_pkt at: row / search_index : %hu, %u (%hu)\n",
|
||||
__func__, row, search_index, bitbuffer->bits_per_row[row]);
|
||||
|
||||
ret = parse_insteon_pkt(decoder, bitbuffer, row, search_index);
|
||||
|
||||
// if (decoder->verbose) tf(stderr, "%s: parse_insteon_pkt ret value %d\n", __func__, ret_value);
|
||||
if (ret > 0) { // preamble good, decode good
|
||||
ret_value += ret;
|
||||
bit_index = search_index + INSTEON_BITLEN_MIN; // move a full packet length
|
||||
}
|
||||
else { // preamble good, decode fail
|
||||
if (ret < 0)
|
||||
fail_value = ret;
|
||||
bit_index = search_index + INSTEON_PREAMBLE_LEN; // move to next preamble
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret_value > 0)
|
||||
return 1;
|
||||
else
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
/*
|
||||
* List of fields that may appear in the output
|
||||
*
|
||||
* Used to determine what fields will be output in what
|
||||
* order for this device when using -F csv.
|
||||
*
|
||||
*/
|
||||
|
||||
static char *output_fields[] = {
|
||||
"model",
|
||||
// "id",
|
||||
// "data",
|
||||
"from_id",
|
||||
"to_id",
|
||||
"msg_type", // packet type at int
|
||||
"msg_type_str", // packet type as formated string
|
||||
// "command",
|
||||
"extended", // 0= short pkt, 1=extended pkt
|
||||
"hops_max", // almost always 3
|
||||
"hops_left", // remaining hops
|
||||
"formatted", // entire packet as a formated string with hex
|
||||
"mic", // remove if not applicable
|
||||
"payload", // packet as a hex string
|
||||
"cmd_dat", // array of int containing command + data
|
||||
// "raw",
|
||||
// "raw_message",
|
||||
NULL,
|
||||
};
|
||||
|
||||
// -X 'n=Insteon_F16,m=FSK_PCM,s=110,l=110,t=15,g=20000,r=20000,invert,match={16}0x6666'
|
||||
|
||||
r_device insteon = {
|
||||
.name = "Insteon",
|
||||
.modulation = FSK_PULSE_PCM,
|
||||
.short_width = 110, // short gap is 132 us
|
||||
.long_width = 110, // long gap is 224 us
|
||||
.gap_limit = 300, // some distance above long
|
||||
.tolerance = 15,
|
||||
.reset_limit = 1000, // a bit longer than packet gap
|
||||
.decode_fn = &insteon_callback,
|
||||
.disabled = 0, // disabled and hidden, use 0 if there is a MIC, 1 otherwise
|
||||
.fields = output_fields,
|
||||
.verbose = 0,
|
||||
};
|
|
@ -215,6 +215,7 @@ COPY ..\..\libusb\MS64\dll\libusb*.dll $(TargetDir)</Command>
|
|||
<ClCompile Include="..\src\devices\ikea_sparsnas.c" />
|
||||
<ClCompile Include="..\src\devices\infactory.c" />
|
||||
<ClCompile Include="..\src\devices\inovalley-kw9015b.c" />
|
||||
<ClCompile Include="..\src\devices\insteon.c" />
|
||||
<ClCompile Include="..\src\devices\interlogix.c" />
|
||||
<ClCompile Include="..\src\devices\intertechno.c" />
|
||||
<ClCompile Include="..\src\devices\kedsum.c" />
|
||||
|
|
|
@ -382,6 +382,9 @@
|
|||
<ClCompile Include="..\src\devices\inovalley-kw9015b.c">
|
||||
<Filter>Source Files\devices</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\devices\insteon.c">
|
||||
<Filter>Source Files\devices</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\devices\interlogix.c">
|
||||
<Filter>Source Files\devices</Filter>
|
||||
</ClCompile>
|
||||
|
|
Loading…
Add table
Reference in a new issue