Update UniTemp and run fbt format

This commit is contained in:
MX
2023-01-18 22:25:39 +03:00
parent e4aad248cf
commit 5a9da13d84
36 changed files with 1478 additions and 966 deletions

View File

@@ -9,9 +9,9 @@
#include "../app.h"
static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
if (numbits < 30) return false;
const char *sync_patterns[3] = {
static bool decode(uint8_t* bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo* info) {
if(numbits < 30) return false;
const char* sync_patterns[3] = {
"10000000000000000000000000000001", /* 30 zero bits. */
"100000000000000000000000000000001", /* 31 zero bits. */
"1000000000000000000000000000000001", /* 32 zero bits. */
@@ -19,32 +19,29 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
uint32_t off;
int j;
for (j = 0; j < 3; j++) {
off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_patterns[j]);
if (off != BITMAP_SEEK_NOT_FOUND) break;
for(j = 0; j < 3; j++) {
off = bitmap_seek_bits(bits, numbytes, 0, numbits, sync_patterns[j]);
if(off != BITMAP_SEEK_NOT_FOUND) break;
}
if (off == BITMAP_SEEK_NOT_FOUND) return false;
if (DEBUG_MSG) FURI_LOG_E(TAG, "B4B1 preamble at: %lu",off);
if(off == BITMAP_SEEK_NOT_FOUND) return false;
if(DEBUG_MSG) FURI_LOG_E(TAG, "B4B1 preamble at: %lu", off);
info->start_off = off;
// Seek data setction. Why -1? Last bit is data.
off += strlen(sync_patterns[j])-1;
off += strlen(sync_patterns[j]) - 1;
uint8_t d[3]; /* 24 bits of data. */
uint32_t decoded =
convert_from_line_code(d,sizeof(d),bits,numbytes,off,"1000","1110");
uint32_t decoded = convert_from_line_code(d, sizeof(d), bits, numbytes, off, "1000", "1110");
if (DEBUG_MSG) FURI_LOG_E(TAG, "B4B1 decoded: %lu",decoded);
if (decoded < 24) return false;
if(DEBUG_MSG) FURI_LOG_E(TAG, "B4B1 decoded: %lu", decoded);
if(decoded < 24) return false;
off += 24*4; // seek to end symbol offset to calculate the length.
off += 24 * 4; // seek to end symbol offset to calculate the length.
off++; // In this protocol there is a final pulse as terminator.
info->pulses_count = off - info->start_off;
snprintf(info->name,PROTOVIEW_MSG_STR_LEN,"PT/SC remote");
snprintf(info->raw,PROTOVIEW_MSG_STR_LEN,"%02X%02X%02X",d[0],d[1],d[2]);
snprintf(info->name, PROTOVIEW_MSG_STR_LEN, "PT/SC remote");
snprintf(info->raw, PROTOVIEW_MSG_STR_LEN, "%02X%02X%02X", d[0], d[1], d[2]);
return true;
}
ProtoViewDecoder B4B1Decoder = {
"B4B1", decode
};
ProtoViewDecoder B4B1Decoder = {"B4B1", decode};

View File

@@ -24,16 +24,16 @@
#include "../app.h"
static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
static bool decode(uint8_t* bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo* info) {
/* In the sync pattern, we require the 12 high/low pulses and at least
* half the gap we expect (5 pulses times, one is the final zero in the
* 24 symbols high/low sequence, then other 4). */
const char *sync_pattern = "101010101010101010101010" "0000";
uint8_t sync_len = 24+4;
if (numbits-sync_len+sync_len < 3*66) return false;
uint32_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern);
if (off == BITMAP_SEEK_NOT_FOUND) return false;
const char* sync_pattern = "101010101010101010101010"
"0000";
uint8_t sync_len = 24 + 4;
if(numbits - sync_len + sync_len < 3 * 66) return false;
uint32_t off = bitmap_seek_bits(bits, numbytes, 0, numbits, sync_pattern);
if(off == BITMAP_SEEK_NOT_FOUND) return false;
info->start_off = off;
off += sync_len; // Seek start of message.
@@ -42,50 +42,57 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
* symbols of gap, to avoid missing the signal for a matter of wrong
* timing. */
uint8_t gap_len = 0;
while(gap_len <= 7 && bitmap_get(bits,numbytes,off+gap_len) == 0)
gap_len++;
if (gap_len < 3 || gap_len > 7) return false;
while(gap_len <= 7 && bitmap_get(bits, numbytes, off + gap_len) == 0) gap_len++;
if(gap_len < 3 || gap_len > 7) return false;
off += gap_len;
FURI_LOG_E(TAG, "Keeloq preamble+sync found");
uint8_t raw[9] = {0};
uint32_t decoded =
convert_from_line_code(raw,sizeof(raw),bits,numbytes,off,
"110","100"); /* Pulse width modulation. */
uint32_t decoded = convert_from_line_code(
raw, sizeof(raw), bits, numbytes, off, "110", "100"); /* Pulse width modulation. */
FURI_LOG_E(TAG, "Keeloq decoded bits: %lu", decoded);
if (decoded < 66) return false; /* Require the full 66 bits. */
if(decoded < 66) return false; /* Require the full 66 bits. */
info->pulses_count = (off+66*3) - info->start_off;
info->pulses_count = (off + 66 * 3) - info->start_off;
bitmap_reverse_bytes(raw,sizeof(raw)); /* Keeloq is LSB first. */
bitmap_reverse_bytes(raw, sizeof(raw)); /* Keeloq is LSB first. */
int buttons = raw[7]>>4;
int s3 = (buttons&1) != 0;
int s0 = (buttons&2) != 0;
int s1 = (buttons&4) != 0;
int s2 = (buttons&8) != 0;
int buttons = raw[7] >> 4;
int s3 = (buttons & 1) != 0;
int s0 = (buttons & 2) != 0;
int s1 = (buttons & 4) != 0;
int s2 = (buttons & 8) != 0;
int remote_id = ((raw[7]&0x0f) << 24) |
(raw[6] << 16) |
(raw[5] << 8) |
(raw[4] << 0);
int lowbat = raw[8]&0x80;
int remote_id = ((raw[7] & 0x0f) << 24) | (raw[6] << 16) | (raw[5] << 8) | (raw[4] << 0);
int lowbat = raw[8] & 0x80;
snprintf(info->name,sizeof(info->name),"%s","Keeloq remote");
snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X",
raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
raw[6],raw[7],raw[8]);
snprintf(info->info1,sizeof(info->info1),"Encrpyted %02X%02X%02X%02X",
raw[3],raw[2],raw[1],raw[0]);
snprintf(info->info2,sizeof(info->info2),"ID %08X", remote_id);
snprintf(info->info3,sizeof(info->info3),"s0-s3: %d%d%d%d",
s0,s1,s2,s3);
snprintf(info->info4,sizeof(info->info4),"Low battery? %s",
lowbat ? "yes" : "no");
snprintf(info->name, sizeof(info->name), "%s", "Keeloq remote");
snprintf(
info->raw,
sizeof(info->raw),
"%02X%02X%02X%02X%02X%02X%02X%02X%02X",
raw[0],
raw[1],
raw[2],
raw[3],
raw[4],
raw[5],
raw[6],
raw[7],
raw[8]);
snprintf(
info->info1,
sizeof(info->info1),
"Encrpyted %02X%02X%02X%02X",
raw[3],
raw[2],
raw[1],
raw[0]);
snprintf(info->info2, sizeof(info->info2), "ID %08X", remote_id);
snprintf(info->info3, sizeof(info->info3), "s0-s3: %d%d%d%d", s0, s1, s2, s3);
snprintf(info->info4, sizeof(info->info4), "Low battery? %s", lowbat ? "yes" : "no");
return true;
}
ProtoViewDecoder KeeloqDecoder = {
"Keeloq", decode
};
ProtoViewDecoder KeeloqDecoder = {"Keeloq", decode};

View File

@@ -6,11 +6,14 @@
#include "../app.h"
static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
if (numbits < 32) return false;
const char *sync_pattern = "01100110" "01100110" "10010110" "10010110";
uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern);
if (off == BITMAP_SEEK_NOT_FOUND) return false;
static bool decode(uint8_t* bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo* info) {
if(numbits < 32) return false;
const char* sync_pattern = "01100110"
"01100110"
"10010110"
"10010110";
uint64_t off = bitmap_seek_bits(bits, numbytes, 0, numbits, sync_pattern);
if(off == BITMAP_SEEK_NOT_FOUND) return false;
FURI_LOG_E(TAG, "Oregon2 preamble+sync found");
info->start_off = off;
@@ -18,50 +21,71 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
uint8_t buffer[8], raw[8] = {0};
uint32_t decoded =
convert_from_line_code(buffer,sizeof(buffer),bits,numbytes,off,"1001","0110");
convert_from_line_code(buffer, sizeof(buffer), bits, numbytes, off, "1001", "0110");
FURI_LOG_E(TAG, "Oregon2 decoded bits: %lu", decoded);
if (decoded < 11*4) return false; /* Minimum len to extract some data. */
info->pulses_count = (off+11*4*4) - info->start_off;
if(decoded < 11 * 4) return false; /* Minimum len to extract some data. */
info->pulses_count = (off + 11 * 4 * 4) - info->start_off;
char temp[3] = {0}, deviceid[2] = {0}, hum[2] = {0};
for (int j = 0; j < 64; j += 4) {
for(int j = 0; j < 64; j += 4) {
uint8_t nib[1];
nib[0] = (bitmap_get(buffer,8,j+0) |
bitmap_get(buffer,8,j+1) << 1 |
bitmap_get(buffer,8,j+2) << 2 |
bitmap_get(buffer,8,j+3) << 3);
if (DEBUG_MSG) FURI_LOG_E(TAG, "Not inverted nibble[%d]: %x", j/4, (unsigned int)nib[0]);
raw[j/8] |= nib[0] << (4-(j%4));
switch(j/4) {
case 1: deviceid[0] |= nib[0]; break;
case 0: deviceid[0] |= nib[0] << 4; break;
case 3: deviceid[1] |= nib[0]; break;
case 2: deviceid[1] |= nib[0] << 4; break;
case 10: temp[0] = nib[0]; break;
nib[0] =
(bitmap_get(buffer, 8, j + 0) | bitmap_get(buffer, 8, j + 1) << 1 |
bitmap_get(buffer, 8, j + 2) << 2 | bitmap_get(buffer, 8, j + 3) << 3);
if(DEBUG_MSG) FURI_LOG_E(TAG, "Not inverted nibble[%d]: %x", j / 4, (unsigned int)nib[0]);
raw[j / 8] |= nib[0] << (4 - (j % 4));
switch(j / 4) {
case 1:
deviceid[0] |= nib[0];
break;
case 0:
deviceid[0] |= nib[0] << 4;
break;
case 3:
deviceid[1] |= nib[0];
break;
case 2:
deviceid[1] |= nib[0] << 4;
break;
case 10:
temp[0] = nib[0];
break;
/* Fixme: take the temperature sign from nibble 11. */
case 9: temp[1] = nib[0]; break;
case 8: temp[2] = nib[0]; break;
case 13: hum[0] = nib[0]; break;
case 12: hum[1] = nib[0]; break;
case 9:
temp[1] = nib[0];
break;
case 8:
temp[2] = nib[0];
break;
case 13:
hum[0] = nib[0];
break;
case 12:
hum[1] = nib[0];
break;
}
}
snprintf(info->name,sizeof(info->name),"%s","Oregon v2.1");
snprintf(info->name, sizeof(info->name), "%s", "Oregon v2.1");
/* The following line crashes the Flipper because of broken
* snprintf() implementation. */
snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X",
raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
raw[6],raw[7]);
snprintf(info->info1,sizeof(info->info1),"Sensor ID %02X%02X",
deviceid[0], deviceid[1]);
snprintf(info->info2,sizeof(info->info2),"Temperature %d%d.%d",
temp[0],temp[1],temp[2]);
snprintf(info->info3,sizeof(info->info3),"Humidity %d%d",
hum[0],hum[1]);
snprintf(
info->raw,
sizeof(info->raw),
"%02X%02X%02X%02X%02X%02X%02X%02X",
raw[0],
raw[1],
raw[2],
raw[3],
raw[4],
raw[5],
raw[6],
raw[7]);
snprintf(info->info1, sizeof(info->info1), "Sensor ID %02X%02X", deviceid[0], deviceid[1]);
snprintf(info->info2, sizeof(info->info2), "Temperature %d%d.%d", temp[0], temp[1], temp[2]);
snprintf(info->info3, sizeof(info->info3), "Humidity %d%d", hum[0], hum[1]);
return true;
}
ProtoViewDecoder Oregon2Decoder = {
"Oregon2", decode
};
ProtoViewDecoder Oregon2Decoder = {"Oregon2", decode};

View File

@@ -7,57 +7,69 @@
#include "../../app.h"
static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
static bool decode(uint8_t* bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo* info) {
/* We consider a preamble of 17 symbols. They are more, but the decoding
* is more likely to happen if we don't pretend to receive from the
* very start of the message. */
uint32_t sync_len = 17;
const char *sync_pattern = "10101010101010110";
if (numbits-sync_len < 8*10) return false; /* Expect 10 bytes. */
const char* sync_pattern = "10101010101010110";
if(numbits - sync_len < 8 * 10) return false; /* Expect 10 bytes. */
uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern);
if (off == BITMAP_SEEK_NOT_FOUND) return false;
uint64_t off = bitmap_seek_bits(bits, numbytes, 0, numbits, sync_pattern);
if(off == BITMAP_SEEK_NOT_FOUND) return false;
FURI_LOG_E(TAG, "Renault TPMS preamble+sync found");
info->start_off = off;
off += sync_len; /* Skip preamble + sync. */
uint8_t raw[10];
uint32_t decoded =
convert_from_line_code(raw,sizeof(raw),bits,numbytes,off,
"01","10"); /* Manchester. */
uint32_t decoded = convert_from_line_code(
raw, sizeof(raw), bits, numbytes, off, "01", "10"); /* Manchester. */
FURI_LOG_E(TAG, "Citroen TPMS decoded bits: %lu", decoded);
if (decoded < 8*10) return false; /* Require the full 10 bytes. */
if(decoded < 8 * 10) return false; /* Require the full 10 bytes. */
/* Check the CRC. It's a simple XOR of bytes 1-9, the first byte
* is not included. The meaning of the first byte is unknown and
* we don't display it. */
uint8_t crc = 0;
for (int j = 1; j < 10; j++) crc ^= raw[j];
if (crc != 0) return false; /* Require sane checksum. */
for(int j = 1; j < 10; j++) crc ^= raw[j];
if(crc != 0) return false; /* Require sane checksum. */
info->pulses_count = (off+8*10*2) - info->start_off;
info->pulses_count = (off + 8 * 10 * 2) - info->start_off;
int repeat = raw[5] & 0xf;
float kpa = (float)raw[6]*1.364;
int temp = raw[7]-50;
float kpa = (float)raw[6] * 1.364;
int temp = raw[7] - 50;
int battery = raw[8]; /* This may be the battery. It's not clear. */
snprintf(info->name,sizeof(info->name),"%s","Citroen TPMS");
snprintf(info->raw,sizeof(info->raw),
snprintf(info->name, sizeof(info->name), "%s", "Citroen TPMS");
snprintf(
info->raw,
sizeof(info->raw),
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
raw[6],raw[7],raw[8],raw[9]);
snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X%02X",
raw[1],raw[2],raw[3],raw[4]);
snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa);
snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp);
snprintf(info->info4,sizeof(info->info4),"Repeat %d, Bat %d", repeat, battery);
raw[0],
raw[1],
raw[2],
raw[3],
raw[4],
raw[5],
raw[6],
raw[7],
raw[8],
raw[9]);
snprintf(
info->info1,
sizeof(info->info1),
"Tire ID %02X%02X%02X%02X",
raw[1],
raw[2],
raw[3],
raw[4]);
snprintf(info->info2, sizeof(info->info2), "Pressure %.2f kpa", (double)kpa);
snprintf(info->info3, sizeof(info->info3), "Temperature %d C", temp);
snprintf(info->info4, sizeof(info->info4), "Repeat %d, Bat %d", repeat, battery);
return true;
}
ProtoViewDecoder CitroenTPMSDecoder = {
"Citroen TPMS", decode
};
ProtoViewDecoder CitroenTPMSDecoder = {"Citroen TPMS", decode};

View File

@@ -10,58 +10,70 @@
#include "../../app.h"
static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
static bool decode(uint8_t* bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo* info) {
const char* sync_pattern = "010101010101"
"0110";
uint8_t sync_len = 12 + 4; /* We just use 12 preamble symbols + sync. */
if(numbits - sync_len < 8 * 8) return false;
const char *sync_pattern = "010101010101" "0110";
uint8_t sync_len = 12+4; /* We just use 12 preamble symbols + sync. */
if (numbits-sync_len < 8*8) return false;
uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern);
if (off == BITMAP_SEEK_NOT_FOUND) return false;
uint64_t off = bitmap_seek_bits(bits, numbytes, 0, numbits, sync_pattern);
if(off == BITMAP_SEEK_NOT_FOUND) return false;
FURI_LOG_E(TAG, "Fort TPMS preamble+sync found");
info->start_off = off;
off += sync_len; /* Skip preamble and sync. */
uint8_t raw[8];
uint32_t decoded =
convert_from_line_code(raw,sizeof(raw),bits,numbytes,off,
"01","10"); /* Manchester. */
uint32_t decoded = convert_from_line_code(
raw, sizeof(raw), bits, numbytes, off, "01", "10"); /* Manchester. */
FURI_LOG_E(TAG, "Ford TPMS decoded bits: %lu", decoded);
if (decoded < 8*8) return false; /* Require the full 8 bytes. */
if(decoded < 8 * 8) return false; /* Require the full 8 bytes. */
/* CRC is just the sum of the first 7 bytes MOD 256. */
uint8_t crc = 0;
for (int j = 0; j < 7; j++) crc += raw[j];
if (crc != raw[7]) return false; /* Require sane CRC. */
for(int j = 0; j < 7; j++) crc += raw[j];
if(crc != raw[7]) return false; /* Require sane CRC. */
info->pulses_count = (off+8*8*2) - info->start_off;
info->pulses_count = (off + 8 * 8 * 2) - info->start_off;
float psi = 0.25 * (((raw[6]&0x20)<<3)|raw[4]);
float psi = 0.25 * (((raw[6] & 0x20) << 3) | raw[4]);
/* Temperature apperas to be valid only if the most significant
* bit of the value is not set. Otherwise its meaning is unknown.
* Likely useful to alternatively send temperature or other info. */
int temp = raw[5] & 0x80 ? 0 : raw[5]-56;
int temp = raw[5] & 0x80 ? 0 : raw[5] - 56;
int flags = raw[5] & 0x7f;
int car_moving = (raw[6] & 0x44) == 0x44;
snprintf(info->name,sizeof(info->name),"%s","Ford TPMS");
snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X",
raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
raw[6],raw[7]);
snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X%02X",
raw[0],raw[1],raw[2],raw[3]);
snprintf(info->info2,sizeof(info->info2),"Pressure %.2f psi", (double)psi);
if (temp)
snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp);
snprintf(info->name, sizeof(info->name), "%s", "Ford TPMS");
snprintf(
info->raw,
sizeof(info->raw),
"%02X%02X%02X%02X%02X%02X%02X%02X",
raw[0],
raw[1],
raw[2],
raw[3],
raw[4],
raw[5],
raw[6],
raw[7]);
snprintf(
info->info1,
sizeof(info->info1),
"Tire ID %02X%02X%02X%02X",
raw[0],
raw[1],
raw[2],
raw[3]);
snprintf(info->info2, sizeof(info->info2), "Pressure %.2f psi", (double)psi);
if(temp)
snprintf(info->info3, sizeof(info->info3), "Temperature %d C", temp);
else
snprintf(info->info3,sizeof(info->info3),"Flags %d", flags);
snprintf(info->info4,sizeof(info->info4),"Moving %s", car_moving ? "yes" : "no");
snprintf(info->info3, sizeof(info->info3), "Flags %d", flags);
snprintf(info->info4, sizeof(info->info4), "Moving %s", car_moving ? "yes" : "no");
return true;
}
ProtoViewDecoder FordTPMSDecoder = {
"Ford TPMS", decode
};
ProtoViewDecoder FordTPMSDecoder = {"Ford TPMS", decode};

View File

@@ -6,64 +6,69 @@
#include "../../app.h"
#define USE_TEST_VECTOR 0
static const char *test_vector =
static const char* test_vector =
"...01010101010101010110" // Preamble + sync
/* The following is Marshal encoded, so each two characters are
* actaully one bit. 01 = 0, 10 = 1. */
"010110010110" // Flags.
"10011001101010011001" // Pressure, multiply by 0.75 to obtain kpa.
// 244 kpa here.
"1010010110011010" // Temperature, subtract 30 to obtain celsius. 22C here.
// 244 kpa here.
"1010010110011010" // Temperature, subtract 30 to obtain celsius. 22C here.
"1001010101101001"
"0101100110010101"
"1001010101100110" // Tire ID. 0x7AD779 here.
"1001010101100110" // Tire ID. 0x7AD779 here.
"0101010101010101"
"0101010101010101" // Two FF bytes (usually). Unknown.
"0101010101010101" // Two FF bytes (usually). Unknown.
"0110010101010101"; // CRC8 with (poly 7, initialization 0).
static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
if (USE_TEST_VECTOR) { /* Test vector to check that decoding works. */
bitmap_set_pattern(bits,numbytes,0,test_vector);
static bool decode(uint8_t* bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo* info) {
if(USE_TEST_VECTOR) { /* Test vector to check that decoding works. */
bitmap_set_pattern(bits, numbytes, 0, test_vector);
numbits = strlen(test_vector);
}
if (numbits-12 < 9*8) return false;
if(numbits - 12 < 9 * 8) return false;
const char *sync_pattern = "01010101010101010110";
uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern);
if (off == BITMAP_SEEK_NOT_FOUND) return false;
const char* sync_pattern = "01010101010101010110";
uint64_t off = bitmap_seek_bits(bits, numbytes, 0, numbits, sync_pattern);
if(off == BITMAP_SEEK_NOT_FOUND) return false;
FURI_LOG_E(TAG, "Renault TPMS preamble+sync found");
info->start_off = off;
off += 20; /* Skip preamble. */
uint8_t raw[9];
uint32_t decoded =
convert_from_line_code(raw,sizeof(raw),bits,numbytes,off,
"01","10"); /* Manchester. */
uint32_t decoded = convert_from_line_code(
raw, sizeof(raw), bits, numbytes, off, "01", "10"); /* Manchester. */
FURI_LOG_E(TAG, "Renault TPMS decoded bits: %lu", decoded);
if (decoded < 8*9) return false; /* Require the full 9 bytes. */
if (crc8(raw,8,0,7) != raw[8]) return false; /* Require sane CRC. */
if(decoded < 8 * 9) return false; /* Require the full 9 bytes. */
if(crc8(raw, 8, 0, 7) != raw[8]) return false; /* Require sane CRC. */
info->pulses_count = (off+8*9*2) - info->start_off;
info->pulses_count = (off + 8 * 9 * 2) - info->start_off;
float kpa = 0.75 *((uint32_t)((raw[0]&3)<<8) | raw[1]);
int temp = raw[2]-30;
float kpa = 0.75 * ((uint32_t)((raw[0] & 3) << 8) | raw[1]);
int temp = raw[2] - 30;
snprintf(info->name,sizeof(info->name),"%s","Renault TPMS");
snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X",
raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
raw[6],raw[7],raw[8]);
snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X",
raw[3],raw[4],raw[5]);
snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa);
snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp);
snprintf(info->name, sizeof(info->name), "%s", "Renault TPMS");
snprintf(
info->raw,
sizeof(info->raw),
"%02X%02X%02X%02X%02X%02X%02X%02X%02X",
raw[0],
raw[1],
raw[2],
raw[3],
raw[4],
raw[5],
raw[6],
raw[7],
raw[8]);
snprintf(info->info1, sizeof(info->info1), "Tire ID %02X%02X%02X", raw[3], raw[4], raw[5]);
snprintf(info->info2, sizeof(info->info2), "Pressure %.2f kpa", (double)kpa);
snprintf(info->info3, sizeof(info->info3), "Temperature %d C", temp);
return true;
}
ProtoViewDecoder RenaultTPMSDecoder = {
"Renault TPMS", decode
};
ProtoViewDecoder RenaultTPMSDecoder = {"Renault TPMS", decode};

View File

@@ -11,20 +11,21 @@
#include "../../app.h"
#define USE_TEST_VECTOR 0
static const char *test_vector = "000000111101010101011010010110010110101001010110100110011001100101010101011010100110100110011010101010101010101010101010101010101010101010101010";
static const char* test_vector =
"000000111101010101011010010110010110101001010110100110011001100101010101011010100110100110011010101010101010101010101010101010101010101010101010";
static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
if (USE_TEST_VECTOR) { /* Test vector to check that decoding works. */
bitmap_set_pattern(bits,numbytes,0,test_vector);
static bool decode(uint8_t* bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo* info) {
if(USE_TEST_VECTOR) { /* Test vector to check that decoding works. */
bitmap_set_pattern(bits, numbytes, 0, test_vector);
numbits = strlen(test_vector);
}
if (numbits < 64) return false; /* Preamble + data. */
if(numbits < 64) return false; /* Preamble + data. */
const char *sync_pattern = "1111010101" "01011010";
uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern);
if (off == BITMAP_SEEK_NOT_FOUND) return false;
const char* sync_pattern = "1111010101"
"01011010";
uint64_t off = bitmap_seek_bits(bits, numbytes, 0, numbits, sync_pattern);
if(off == BITMAP_SEEK_NOT_FOUND) return false;
FURI_LOG_E(TAG, "Schrader TPMS gap+preamble found");
info->start_off = off;
@@ -33,36 +34,48 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
0011 = 0x3. */
uint8_t raw[8];
uint32_t decoded =
convert_from_line_code(raw,sizeof(raw),bits,numbytes,off,
"01","10"); /* Manchester code. */
uint32_t decoded = convert_from_line_code(
raw, sizeof(raw), bits, numbytes, off, "01", "10"); /* Manchester code. */
FURI_LOG_E(TAG, "Schrader TPMS decoded bits: %lu", decoded);
if (decoded < 64) return false; /* Require the full 8 bytes. */
if(decoded < 64) return false; /* Require the full 8 bytes. */
raw[0] |= 0xf0; // Fix the preamble nibble for checksum computation.
uint8_t cksum = crc8(raw,sizeof(raw)-1,0xf0,0x7);
if (cksum != raw[7]) {
uint8_t cksum = crc8(raw, sizeof(raw) - 1, 0xf0, 0x7);
if(cksum != raw[7]) {
FURI_LOG_E(TAG, "Schrader TPMS checksum mismatch");
return false;
}
info->pulses_count = (off+8*8*2) - info->start_off;
info->pulses_count = (off + 8 * 8 * 2) - info->start_off;
float kpa = (float)raw[5]*2.5;
int temp = raw[6]-50;
float kpa = (float)raw[5] * 2.5;
int temp = raw[6] - 50;
snprintf(info->name,sizeof(info->name),"%s","Schrader TPMS");
snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X",
raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
raw[6],raw[7]);
snprintf(info->info1,sizeof(info->info1),"Tire ID %01X%02X%02X%02X",
raw[1]&7,raw[2],raw[3],raw[4]); /* Only 28 bits of ID, not 32. */
snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa);
snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp);
snprintf(info->name, sizeof(info->name), "%s", "Schrader TPMS");
snprintf(
info->raw,
sizeof(info->raw),
"%02X%02X%02X%02X%02X%02X%02X%02X",
raw[0],
raw[1],
raw[2],
raw[3],
raw[4],
raw[5],
raw[6],
raw[7]);
snprintf(
info->info1,
sizeof(info->info1),
"Tire ID %01X%02X%02X%02X",
raw[1] & 7,
raw[2],
raw[3],
raw[4]); /* Only 28 bits of ID, not 32. */
snprintf(info->info2, sizeof(info->info2), "Pressure %.2f kpa", (double)kpa);
snprintf(info->info3, sizeof(info->info3), "Temperature %d C", temp);
return true;
}
ProtoViewDecoder SchraderTPMSDecoder = {
"Schrader TPMS", decode
};
ProtoViewDecoder SchraderTPMSDecoder = {"Schrader TPMS", decode};

View File

@@ -15,52 +15,65 @@
#include "../../app.h"
static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
static bool decode(uint8_t* bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo* info) {
const char* sync_pattern = "010101010101"
"01100101";
uint8_t sync_len = 12 + 8; /* We just use 12 preamble symbols + sync. */
if(numbits - sync_len + 8 < 8 * 10) return false;
const char *sync_pattern = "010101010101" "01100101";
uint8_t sync_len = 12+8; /* We just use 12 preamble symbols + sync. */
if (numbits-sync_len+8 < 8*10) return false;
uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern);
if (off == BITMAP_SEEK_NOT_FOUND) return false;
uint64_t off = bitmap_seek_bits(bits, numbytes, 0, numbits, sync_pattern);
if(off == BITMAP_SEEK_NOT_FOUND) return false;
FURI_LOG_E(TAG, "Schrader EG53MA4 TPMS preamble+sync found");
info->start_off = off;
off += sync_len-8; /* Skip preamble, not sync that is part of the data. */
off += sync_len - 8; /* Skip preamble, not sync that is part of the data. */
uint8_t raw[10];
uint32_t decoded =
convert_from_line_code(raw,sizeof(raw),bits,numbytes,off,
"01","10"); /* Manchester code. */
uint32_t decoded = convert_from_line_code(
raw, sizeof(raw), bits, numbytes, off, "01", "10"); /* Manchester code. */
FURI_LOG_E(TAG, "Schrader EG53MA4 TPMS decoded bits: %lu", decoded);
if (decoded < 10*8) return false; /* Require the full 10 bytes. */
if(decoded < 10 * 8) return false; /* Require the full 10 bytes. */
/* CRC is just all bytes added mod 256. */
uint8_t crc = 0;
for (int j = 0; j < 9; j++) crc += raw[j];
if (crc != raw[9]) return false; /* Require sane CRC. */
for(int j = 0; j < 9; j++) crc += raw[j];
if(crc != raw[9]) return false; /* Require sane CRC. */
info->pulses_count = (off+10*8*2) - info->start_off;
info->pulses_count = (off + 10 * 8 * 2) - info->start_off;
/* To convert the raw pressure to kPa, RTL433 uses 2.5, but is likely
* wrong. Searching on Google for users experimenting with the value
* reported, the value appears to be 2.75. */
float kpa = (float)raw[7]*2.75;
float kpa = (float)raw[7] * 2.75;
int temp_f = raw[8];
int temp_c = (temp_f-32)*5/9; /* Convert Fahrenheit to Celsius. */
int temp_c = (temp_f - 32) * 5 / 9; /* Convert Fahrenheit to Celsius. */
snprintf(info->name,sizeof(info->name),"%s","Schrader EG53MA4 TPMS");
snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
raw[6],raw[7],raw[8],raw[9]);
snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X",
raw[4],raw[5],raw[6]); /* Only 28 bits of ID, not 32. */
snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa);
snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp_c);
snprintf(info->name, sizeof(info->name), "%s", "Schrader EG53MA4 TPMS");
snprintf(
info->raw,
sizeof(info->raw),
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
raw[0],
raw[1],
raw[2],
raw[3],
raw[4],
raw[5],
raw[6],
raw[7],
raw[8],
raw[9]);
snprintf(
info->info1,
sizeof(info->info1),
"Tire ID %02X%02X%02X",
raw[4],
raw[5],
raw[6]); /* Only 28 bits of ID, not 32. */
snprintf(info->info2, sizeof(info->info2), "Pressure %.2f kpa", (double)kpa);
snprintf(info->info3, sizeof(info->info3), "Temperature %d C", temp_c);
return true;
}
ProtoViewDecoder SchraderEG53MA4TPMSDecoder = {
"Schrader EG53MA4 TPMS", decode
};
ProtoViewDecoder SchraderEG53MA4TPMSDecoder = {"Schrader EG53MA4 TPMS", decode};

View File

@@ -24,40 +24,33 @@
#include "../../app.h"
static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
if (numbits-6 < 64*2) return false; /* Ask for 64 bit of data (each bit
static bool decode(uint8_t* bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo* info) {
if(numbits - 6 < 64 * 2)
return false; /* Ask for 64 bit of data (each bit
is two symbols in the bitmap). */
char *sync[] = {
"00111100",
"001111100",
"00111101",
"001111101",
NULL
};
char* sync[] = {"00111100", "001111100", "00111101", "001111101", NULL};
int j;
uint32_t off = 0;
for (j = 0; sync[j]; j++) {
off = bitmap_seek_bits(bits,numbytes,0,numbits,sync[j]);
if (off != BITMAP_SEEK_NOT_FOUND) {
for(j = 0; sync[j]; j++) {
off = bitmap_seek_bits(bits, numbytes, 0, numbits, sync[j]);
if(off != BITMAP_SEEK_NOT_FOUND) {
info->start_off = off;
off += strlen(sync[j])-2;
off += strlen(sync[j]) - 2;
break;
}
}
}
if (off == BITMAP_SEEK_NOT_FOUND) return false;
if(off == BITMAP_SEEK_NOT_FOUND) return false;
FURI_LOG_E(TAG, "Toyota TPMS sync[%s] found", sync[j]);
uint8_t raw[9];
uint32_t decoded =
convert_from_diff_manchester(raw,sizeof(raw),bits,numbytes,off,true);
uint32_t decoded = convert_from_diff_manchester(raw, sizeof(raw), bits, numbytes, off, true);
FURI_LOG_E(TAG, "Toyota TPMS decoded bits: %lu", decoded);
if (decoded < 8*9) return false; /* Require the full 8 bytes. */
if (crc8(raw,8,0x80,7) != raw[8]) return false; /* Require sane CRC. */
if(decoded < 8 * 9) return false; /* Require the full 8 bytes. */
if(crc8(raw, 8, 0x80, 7) != raw[8]) return false; /* Require sane CRC. */
/* We detected a valid signal. However now info->start_off is actually
* pointing to the sync part, not the preamble of alternating 0 and 1.
@@ -65,27 +58,41 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
* for the decoder itself to fix the signal if neeeded, so that its
* logical representation will be more accurate and better to save
* and retransmit. */
if (info->start_off >= 12) {
if(info->start_off >= 12) {
info->start_off -= 12;
bitmap_set_pattern(bits,numbytes,info->start_off,"010101010101");
bitmap_set_pattern(bits, numbytes, info->start_off, "010101010101");
}
info->pulses_count = (off+8*9*2) - info->start_off;
info->pulses_count = (off + 8 * 9 * 2) - info->start_off;
float kpa = (float)((raw[4]&0x7f)<<1 | raw[5]>>7) * 0.25 - 7;
int temp = ((raw[5]&0x7f)<<1 | raw[6]>>7) - 40;
float kpa = (float)((raw[4] & 0x7f) << 1 | raw[5] >> 7) * 0.25 - 7;
int temp = ((raw[5] & 0x7f) << 1 | raw[6] >> 7) - 40;
snprintf(info->name,sizeof(info->name),"%s","Toyota TPMS");
snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X",
raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
raw[6],raw[7],raw[8]);
snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X%02X",
raw[0],raw[1],raw[2],raw[3]);
snprintf(info->info2,sizeof(info->info2),"Pressure %.2f psi", (double)kpa);
snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp);
snprintf(info->name, sizeof(info->name), "%s", "Toyota TPMS");
snprintf(
info->raw,
sizeof(info->raw),
"%02X%02X%02X%02X%02X%02X%02X%02X%02X",
raw[0],
raw[1],
raw[2],
raw[3],
raw[4],
raw[5],
raw[6],
raw[7],
raw[8]);
snprintf(
info->info1,
sizeof(info->info1),
"Tire ID %02X%02X%02X%02X",
raw[0],
raw[1],
raw[2],
raw[3]);
snprintf(info->info2, sizeof(info->info2), "Pressure %.2f psi", (double)kpa);
snprintf(info->info3, sizeof(info->info3), "Temperature %d C", temp);
return true;
}
ProtoViewDecoder ToyotaTPMSDecoder = {
"Toyota TPMS", decode
};
ProtoViewDecoder ToyotaTPMSDecoder = {"Toyota TPMS", decode};