mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-10-01 01:26:06 -04:00
SubghzD rework (#2210)
* Removed controller code * Add Legrand * Added Somify Keytis * Somify * better display
This commit is contained in:
parent
9211975868
commit
765e3be55b
@ -32,12 +32,15 @@ using namespace ui;
|
|||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
void SubGhzDRecentEntryDetailView::update_data() {
|
void SubGhzDRecentEntryDetailView::update_data() {
|
||||||
|
// process protocol data
|
||||||
|
parseProtocol();
|
||||||
// set text elements
|
// set text elements
|
||||||
text_type.set(SubGhzDView::getSensorTypeName((FPROTO_SUBGHZD_SENSOR)entry_.sensorType));
|
text_type.set(SubGhzDView::getSensorTypeName((FPROTO_SUBGHZD_SENSOR)entry_.sensorType));
|
||||||
text_id.set("0x" + to_string_hex(entry_.serial));
|
|
||||||
|
text_id.set("0x" + to_string_hex(serial));
|
||||||
if (entry_.bits > 0) console.writeln("Bits: " + to_string_dec_uint(entry_.bits));
|
if (entry_.bits > 0) console.writeln("Bits: " + to_string_dec_uint(entry_.bits));
|
||||||
if (entry_.btn != SD_NO_BTN) console.writeln("Btn: " + to_string_dec_uint(entry_.btn));
|
if (btn != SD_NO_BTN) console.writeln("Btn: " + to_string_dec_uint(btn));
|
||||||
if (entry_.cnt != SD_NO_CNT) console.writeln("Cnt: " + to_string_dec_uint(entry_.cnt));
|
if (cnt != SD_NO_CNT) console.writeln("Cnt: " + to_string_dec_uint(cnt));
|
||||||
|
|
||||||
if (entry_.data != 0) console.writeln("Data: " + to_string_hex(entry_.data));
|
if (entry_.data != 0) console.writeln("Data: " + to_string_hex(entry_.data));
|
||||||
}
|
}
|
||||||
@ -103,7 +106,7 @@ void SubGhzDView::on_tick_second() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SubGhzDView::on_data(const SubGhzDDataMessage* data) {
|
void SubGhzDView::on_data(const SubGhzDDataMessage* data) {
|
||||||
SubGhzDRecentEntry key{data->sensorType, data->serial, data->bits, data->data, data->btn, data->cnt};
|
SubGhzDRecentEntry key{data->sensorType, data->data, data->bits};
|
||||||
auto matching_recent = find(recent, key.key());
|
auto matching_recent = find(recent, key.key());
|
||||||
if (matching_recent != std::end(recent)) {
|
if (matching_recent != std::end(recent)) {
|
||||||
// Found within. Move to front of list, increment counter.
|
// Found within. Move to front of list, increment counter.
|
||||||
@ -203,6 +206,13 @@ const char* SubGhzDView::getSensorTypeName(FPROTO_SUBGHZD_SENSOR type) {
|
|||||||
return "Star Line";
|
return "Star Line";
|
||||||
case FPS_X10:
|
case FPS_X10:
|
||||||
return "X10";
|
return "X10";
|
||||||
|
case FPS_LEGRAND:
|
||||||
|
return "Legrand";
|
||||||
|
case FPS_SOMIFY_KEYTIS:
|
||||||
|
return "Somify Keytis";
|
||||||
|
case FPS_SOMIFY_TELIS:
|
||||||
|
return "Somify Telis";
|
||||||
|
|
||||||
case FPS_Invalid:
|
case FPS_Invalid:
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
@ -224,7 +234,7 @@ void RecentEntriesTable<ui::SubGhzDRecentEntries>::draw(
|
|||||||
line.reserve(30);
|
line.reserve(30);
|
||||||
|
|
||||||
line = SubGhzDView::getSensorTypeName((FPROTO_SUBGHZD_SENSOR)entry.sensorType);
|
line = SubGhzDView::getSensorTypeName((FPROTO_SUBGHZD_SENSOR)entry.sensorType);
|
||||||
line = line + " " + to_string_hex(entry.serial);
|
line = line + " " + to_string_hex(entry.data << 32);
|
||||||
if (line.length() < 19) {
|
if (line.length() < 19) {
|
||||||
line += SubGhzDView::pad_string_with_spaces(19 - line.length());
|
line += SubGhzDView::pad_string_with_spaces(19 - line.length());
|
||||||
} else {
|
} else {
|
||||||
@ -239,4 +249,469 @@ void RecentEntriesTable<ui::SubGhzDRecentEntries>::draw(
|
|||||||
painter.draw_string(target_rect.location(), style, line);
|
painter.draw_string(target_rect.location(), style, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// decoder helper functions
|
||||||
|
|
||||||
|
void atomo_decrypt(uint8_t* buff) {
|
||||||
|
buff[0] = (buff[0] ^ 5) & 0x7F;
|
||||||
|
uint8_t tmpB = (-buff[0]) & 0x7F;
|
||||||
|
|
||||||
|
uint8_t bitCnt = 8;
|
||||||
|
while (bitCnt < 59) {
|
||||||
|
if ((tmpB & 0x18) && (((tmpB / 8) & 3) != 3)) {
|
||||||
|
tmpB = ((tmpB << 1) & 0xFF) | 1;
|
||||||
|
} else {
|
||||||
|
tmpB = (tmpB << 1) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmpB & 0x80) {
|
||||||
|
buff[bitCnt / 8] ^= (0x80 >> (bitCnt & 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
bitCnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t came_twee_magic_numbers_xor[15] = {
|
||||||
|
0x0E0E0E00,
|
||||||
|
0x1D1D1D11,
|
||||||
|
0x2C2C2C22,
|
||||||
|
0x3B3B3B33,
|
||||||
|
0x4A4A4A44,
|
||||||
|
0x59595955,
|
||||||
|
0x68686866,
|
||||||
|
0x77777777,
|
||||||
|
0x86868688,
|
||||||
|
0x95959599,
|
||||||
|
0xA4A4A4AA,
|
||||||
|
0xB3B3B3BB,
|
||||||
|
0xC2C2C2CC,
|
||||||
|
0xD1D1D1DD,
|
||||||
|
0xE0E0E0EE,
|
||||||
|
};
|
||||||
|
|
||||||
|
// to save some byte of fw space, these will be inline. unreadeable? yes. needs a tons of free space? certanly. so sorry for this.
|
||||||
|
|
||||||
|
void SubGhzDRecentEntryDetailView::parseProtocol() {
|
||||||
|
btn = SD_NO_BTN;
|
||||||
|
cnt = SD_NO_CNT;
|
||||||
|
serial = 0;
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_Invalid) return;
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_BETT) {
|
||||||
|
return; // needs dip pattern output.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_AIRFORCE || entry_.sensorType == FPS_PRASTEL || entry_.sensorType == FPS_CAME) {
|
||||||
|
return; // nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_CAMEATOMO) {
|
||||||
|
entry_.data ^= 0xFFFFFFFFFFFFFFFF;
|
||||||
|
entry_.data <<= 4;
|
||||||
|
uint8_t pack[8] = {};
|
||||||
|
pack[0] = (entry_.data >> 56);
|
||||||
|
pack[1] = ((entry_.data >> 48) & 0xFF);
|
||||||
|
pack[2] = ((entry_.data >> 40) & 0xFF);
|
||||||
|
pack[3] = ((entry_.data >> 32) & 0xFF);
|
||||||
|
pack[4] = ((entry_.data >> 24) & 0xFF);
|
||||||
|
pack[5] = ((entry_.data >> 16) & 0xFF);
|
||||||
|
pack[6] = ((entry_.data >> 8) & 0xFF);
|
||||||
|
pack[7] = (entry_.data & 0xFF);
|
||||||
|
|
||||||
|
atomo_decrypt(pack);
|
||||||
|
|
||||||
|
// cnt_2 = pack[0];
|
||||||
|
cnt = (uint16_t)pack[1] << 8 | pack[2];
|
||||||
|
serial = (uint32_t)(pack[3]) << 24 | pack[4] << 16 | pack[5] << 8 | pack[6];
|
||||||
|
|
||||||
|
uint8_t btn_decode = (pack[7] >> 4);
|
||||||
|
if (btn_decode == 0x0) {
|
||||||
|
btn = 0x1;
|
||||||
|
} else if (btn_decode == 0x2) {
|
||||||
|
btn = 0x2;
|
||||||
|
} else if (btn_decode == 0x4) {
|
||||||
|
btn = 0x3;
|
||||||
|
} else if (btn_decode == 0x6) {
|
||||||
|
btn = 0x4;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_CAMETWEE) {
|
||||||
|
uint8_t cnt_parcel = (uint8_t)(entry_.data & 0xF);
|
||||||
|
uint32_t data = (uint32_t)(entry_.data & 0x0FFFFFFFF);
|
||||||
|
|
||||||
|
data = (data ^ came_twee_magic_numbers_xor[cnt_parcel]);
|
||||||
|
serial = data;
|
||||||
|
data /= 4;
|
||||||
|
btn = (data >> 4) & 0x0F;
|
||||||
|
data >>= 16;
|
||||||
|
data = (uint16_t)FProtoGeneral::subghz_protocol_blocks_reverse_key(data, 16);
|
||||||
|
cnt = data >> 6;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_CHAMBCODE) {
|
||||||
|
return; // nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_CLEMSA) {
|
||||||
|
serial = (entry_.data >> 2) & 0xFFFF;
|
||||||
|
btn = (entry_.data & 0x03);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_DOITRAND) {
|
||||||
|
cnt = (entry_.data >> 24) | ((entry_.data >> 15) & 0x1);
|
||||||
|
btn = ((entry_.data >> 18) & 0x3);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_DOOYA) {
|
||||||
|
serial = (entry_.data >> 16);
|
||||||
|
if ((entry_.data >> 12) & 0x0F) {
|
||||||
|
cnt = (entry_.data >> 8) & 0x0F;
|
||||||
|
} else {
|
||||||
|
cnt = 0xff;
|
||||||
|
}
|
||||||
|
btn = entry_.data & 0xFF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_FAAC) { // stripped down a lot.
|
||||||
|
uint32_t code_fix = entry_.data >> 32;
|
||||||
|
uint32_t code_hop = entry_.data & 0xFFFFFFFF;
|
||||||
|
// uint32_t decrypt = 0;
|
||||||
|
// uint64_t man;
|
||||||
|
|
||||||
|
uint8_t data_tmp = 0;
|
||||||
|
uint8_t data_prg[8];
|
||||||
|
data_prg[0] = (code_hop & 0xFF);
|
||||||
|
data_prg[1] = ((code_hop >> 8) & 0xFF);
|
||||||
|
data_prg[2] = ((code_hop >> 16) & 0xFF);
|
||||||
|
data_prg[3] = (code_hop >> 24);
|
||||||
|
data_prg[4] = (code_fix & 0xFF);
|
||||||
|
data_prg[5] = ((code_fix >> 8) & 0xFF);
|
||||||
|
data_prg[6] = ((code_fix >> 16) & 0xFF);
|
||||||
|
data_prg[7] = (code_fix >> 24);
|
||||||
|
|
||||||
|
if (((data_prg[7] == 0x52) && (data_prg[6] == 0x0F) && (data_prg[0] == 0x00))) {
|
||||||
|
// ProgMode ON
|
||||||
|
for (uint8_t i = data_prg[1] & 0xF; i != 0; i--) {
|
||||||
|
data_tmp = data_prg[2];
|
||||||
|
|
||||||
|
data_prg[2] = data_prg[2] >> 1 | (data_prg[3] & 1) << 7;
|
||||||
|
data_prg[3] = data_prg[3] >> 1 | (data_prg[4] & 1) << 7;
|
||||||
|
data_prg[4] = data_prg[4] >> 1 | (data_prg[5] & 1) << 7;
|
||||||
|
data_prg[5] = data_prg[5] >> 1 | (data_tmp & 1) << 7;
|
||||||
|
}
|
||||||
|
data_prg[2] ^= data_prg[1];
|
||||||
|
data_prg[3] ^= data_prg[1];
|
||||||
|
data_prg[4] ^= data_prg[1];
|
||||||
|
data_prg[5] ^= data_prg[1];
|
||||||
|
seed = data_prg[5] << 24 | data_prg[4] << 16 | data_prg[3] << 8 | data_prg[2];
|
||||||
|
// uint32_t dec_prg_1 = data_prg[7] << 24 | data_prg[6] << 16 | data_prg[5] << 8 | data_prg[4];
|
||||||
|
// uint32_t dec_prg_2 = data_prg[3] << 24 | data_prg[2] << 16 | data_prg[1] << 8 | data_prg[0];
|
||||||
|
// entry_.data_2 = (uint64_t)dec_prg_1 << 32 | dec_prg_2;
|
||||||
|
cnt = data_prg[1];
|
||||||
|
} else {
|
||||||
|
if (code_fix != 0x0) {
|
||||||
|
serial = code_fix >> 4;
|
||||||
|
btn = code_fix & 0xF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_GATETX) {
|
||||||
|
uint32_t code_found_reverse = FProtoGeneral::subghz_protocol_blocks_reverse_key(entry_.data, entry_.bits);
|
||||||
|
serial = (code_found_reverse & 0xFF) << 12 | ((code_found_reverse >> 8) & 0xFF) << 4 | ((code_found_reverse >> 20) & 0x0F);
|
||||||
|
btn = ((code_found_reverse >> 16) & 0x0F);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_HOLTEK) {
|
||||||
|
if ((entry_.data & 0xF000000000) == 0x5000000000) {
|
||||||
|
serial = FProtoGeneral::subghz_protocol_blocks_reverse_key((entry_.data >> 16) & 0xFFFFF, 20);
|
||||||
|
uint16_t btn_ = entry_.data & 0xFFFF;
|
||||||
|
if ((btn_ & 0xf) != 0xA) {
|
||||||
|
btn = 0x1 << 4 | (btn_ & 0xF);
|
||||||
|
} else if (((btn_ >> 4) & 0xF) != 0xA) {
|
||||||
|
btn = 0x2 << 4 | ((btn_ >> 4) & 0xF);
|
||||||
|
} else if (((btn_ >> 8) & 0xF) != 0xA) {
|
||||||
|
btn = 0x3 << 4 | ((btn_ >> 8) & 0xF);
|
||||||
|
} else if (((btn_ >> 12) & 0xF) != 0xA) {
|
||||||
|
btn = 0x4 << 4 | ((btn_ >> 12) & 0xF);
|
||||||
|
} else {
|
||||||
|
btn = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
serial = 0;
|
||||||
|
btn = 0;
|
||||||
|
cnt = 0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_HOLTEKHT12X) {
|
||||||
|
btn = entry_.data & 0x0F;
|
||||||
|
cnt = (entry_.data >> 4) & 0xFF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_HONEYWELL) {
|
||||||
|
serial = (entry_.data >> 24) & 0xFFFFF;
|
||||||
|
btn = (entry_.data >> 16) & 0xFF; // not exactly button, but can contain btn data too.
|
||||||
|
cnt = (entry_.data >> 44) & 0xF;
|
||||||
|
/*
|
||||||
|
uint8_t contact = (entry_.databtn & 0x80) >> 7;
|
||||||
|
uint8_t tamper = (entry_.databtn & 0x40) >> 6;
|
||||||
|
uint8_t reed = (entry_.databtn & 0x20) >> 5;
|
||||||
|
uint8_t alarm = (entry_.databtn & 0x10) >> 4;
|
||||||
|
uint8_t battery_low = (entry_.databtn & 0x08) >> 3;
|
||||||
|
uint8_t heartbeat = (entry_.databtn & 0x04) >> 2;
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_HONEYWELLWDB) {
|
||||||
|
serial = (entry_.data >> 28) & 0xFFFFF;
|
||||||
|
// enabled, when we'll have extra fields and free fw space
|
||||||
|
/* switch ((entry_.data >> 20) & 0x3) {
|
||||||
|
case 0x02:
|
||||||
|
device_type = "Doorbell";
|
||||||
|
break;
|
||||||
|
case 0x01:
|
||||||
|
device_type = "PIR-Motion";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
device_type = "Unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ((entry_.data >> 16) & 0x3) {
|
||||||
|
case 0x00:
|
||||||
|
alert = "Normal";
|
||||||
|
break;
|
||||||
|
case 0x01:
|
||||||
|
case 0x02:
|
||||||
|
alert = "High";
|
||||||
|
break;
|
||||||
|
case 0x03:
|
||||||
|
alert = "Full";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
alert = "Unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
secret_knock = (uint8_t)((entry_.data >> 4) & 0x1);
|
||||||
|
relay = (uint8_t)((entry_.data >> 3) & 0x1);
|
||||||
|
lowbat = (uint8_t)((entry_.data >> 1) & 0x1);*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_HORMANN) {
|
||||||
|
btn = (entry_.data >> 8) & 0xF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if (entry_.sensorType == FPS_HORMANNBISECURE) { //fm not implemented
|
||||||
|
serial = 0;
|
||||||
|
|
||||||
|
for (uint8_t i = 1; i < 5; i++) {
|
||||||
|
serial = serial << 8 | ((uint8_t*)(&entry_.data))[i];
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_IDO) {
|
||||||
|
uint64_t code_found_reverse = FProtoGeneral::subghz_protocol_blocks_reverse_key(entry_.data, entry_.bits);
|
||||||
|
uint32_t code_fix = code_found_reverse & 0xFFFFFF;
|
||||||
|
serial = code_fix & 0xFFFFF;
|
||||||
|
btn = (code_fix >> 20) & 0x0F;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_INTERTECHNOV3) {
|
||||||
|
if (entry_.bits == 32) {
|
||||||
|
serial = (entry_.data >> 6) & 0x3FFFFFF;
|
||||||
|
if ((entry_.data >> 5) & 0x1) {
|
||||||
|
cnt = 1 << 5;
|
||||||
|
} else {
|
||||||
|
cnt = (~entry_.data & 0xF);
|
||||||
|
}
|
||||||
|
btn = (entry_.data >> 4) & 0x1;
|
||||||
|
} else if (entry_.bits == 36) {
|
||||||
|
serial = (entry_.data >> 10) & 0x3FFFFFF;
|
||||||
|
if ((entry_.data >> 9) & 0x1) {
|
||||||
|
cnt = 1 << 5;
|
||||||
|
} else {
|
||||||
|
cnt = (~(entry_.data >> 4) & 0xF);
|
||||||
|
}
|
||||||
|
btn = (entry_.data) & 0xF;
|
||||||
|
} else {
|
||||||
|
serial = 0;
|
||||||
|
cnt = 0;
|
||||||
|
btn = 0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_KEELOQ) {
|
||||||
|
// too many sub protocol versions, skipping. maybe in future when we'll have much more fw space
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fm not implemented
|
||||||
|
if (entry_.sensorType == FPS_KIA) {
|
||||||
|
serial = (uint32_t)((entry_.data >> 12) & 0x0FFFFFFF);
|
||||||
|
btn = (entry_.data >> 8) & 0x0F;
|
||||||
|
cnt = (entry_.data >> 40) & 0xFFFF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_KINGGATESSTYLO4K) {
|
||||||
|
uint64_t fix = FProtoGeneral::subghz_protocol_blocks_reverse_key(entry_.data, 53);
|
||||||
|
btn = (fix >> 17) & 0x0F;
|
||||||
|
serial = ((fix >> 5) & 0xFFFF0000) | (fix & 0xFFFF);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_LEGRAND) {
|
||||||
|
return; // nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_LINEAR || entry_.sensorType == FPS_LINEARDELTA3) {
|
||||||
|
return; // nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_MAGELLAN) {
|
||||||
|
uint64_t data_rev = FProtoGeneral::subghz_protocol_blocks_reverse_key(entry_.data >> 8, 24);
|
||||||
|
serial = data_rev & 0xFFFF;
|
||||||
|
btn = (data_rev >> 16) & 0xFF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_MARANTEC) {
|
||||||
|
btn = (entry_.data >> 16) & 0xF;
|
||||||
|
serial = ((entry_.data >> 12) & 0xFFFFFF00) | ((entry_.data >> 8) & 0xFF);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_MASTERCODE) {
|
||||||
|
serial = (entry_.data >> 4) & 0xFFFF;
|
||||||
|
btn = (entry_.data >> 2 & 0x03);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_MEGACODE) {
|
||||||
|
if ((entry_.data >> 23) == 1) {
|
||||||
|
serial = (entry_.data >> 3) & 0xFFFF;
|
||||||
|
btn = entry_.data & 0b111;
|
||||||
|
cnt = (entry_.data >> 19) & 0b1111;
|
||||||
|
} else {
|
||||||
|
serial = 0;
|
||||||
|
btn = 0;
|
||||||
|
cnt = 0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_NERORADIO) {
|
||||||
|
return; // nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_NERO_SKETCH) {
|
||||||
|
return; // nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_NICEFLO || entry_.sensorType == FPS_NICEFLORS) {
|
||||||
|
return; // nothing, and can't
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_PHOENIXV2) {
|
||||||
|
uint64_t data_rev = FProtoGeneral::subghz_protocol_blocks_reverse_key(entry_.data, entry_.bits + 4);
|
||||||
|
serial = data_rev & 0xFFFFFFFF;
|
||||||
|
cnt = (data_rev >> 40) & 0xFFFF;
|
||||||
|
btn = (data_rev >> 32) & 0xF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_POWERSMART) {
|
||||||
|
btn = ((entry_.data >> 54) & 0x02) | ((entry_.data >> 40) & 0x1);
|
||||||
|
serial = ((entry_.data >> 33) & 0x3FFF00) | ((entry_.data >> 32) & 0xFF);
|
||||||
|
cnt = ((entry_.data >> 49) & 0x3F);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_PRINCETON) {
|
||||||
|
serial = entry_.data >> 4;
|
||||||
|
btn = entry_.data & 0xF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (entry_.sensorType == FPS_SECPLUSV1) {
|
||||||
|
uint32_t fixed = (entry_.data >> 32) & 0xFFFFFFFF;
|
||||||
|
cnt = entry_.data & 0xFFFFFFFF;
|
||||||
|
btn = fixed % 3;
|
||||||
|
// uint8_t id0 = (fixed / 3) % 3;
|
||||||
|
uint8_t id1 = (fixed / 9) % 3;
|
||||||
|
// uint16_t pin = 0;
|
||||||
|
if (id1 == 0) {
|
||||||
|
// (fixed // 3**3) % (3**7) 3^3=27 3^73=72187
|
||||||
|
|
||||||
|
serial = (fixed / 27) % 2187;
|
||||||
|
// pin = (fixed // 3**10) % (3**9) 3^10=59049 3^9=19683
|
||||||
|
// pin = (fixed / 59049) % 19683;
|
||||||
|
|
||||||
|
/* if (pin <= 9999) {
|
||||||
|
furi_string_cat_printf(output, " pin:%d", pin);
|
||||||
|
} else if (pin <= 11029) {
|
||||||
|
furi_string_cat_printf(output, " pin:enter");
|
||||||
|
} */
|
||||||
|
} else {
|
||||||
|
// id = fixed / 27;
|
||||||
|
serial = fixed / 27;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_SECPLUSV2) {
|
||||||
|
return; // fw space saver
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_SMC5326) {
|
||||||
|
return; // dip pattern output needed. skipping
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_STARLINE) {
|
||||||
|
uint64_t key = FProtoGeneral::subghz_protocol_blocks_reverse_key(entry_.data, entry_.bits);
|
||||||
|
uint32_t key_fix = key >> 32;
|
||||||
|
serial = key_fix & 0x00FFFFFF;
|
||||||
|
btn = key_fix >> 24;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_X10) {
|
||||||
|
serial = (entry_.data & 0xF0000000) >> (24 + 4);
|
||||||
|
btn = (((entry_.data & 0x07000000) >> 24) | ((entry_.data & 0xF800) >> 8));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_SOMIFY_KEYTIS) {
|
||||||
|
uint64_t dataa = entry_.data ^ (entry_.data >> 8);
|
||||||
|
btn = (dataa >> 48) & 0xF;
|
||||||
|
cnt = (dataa >> 24) & 0xFFFF;
|
||||||
|
serial = dataa & 0xFFFFFF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_.sensorType == FPS_SOMIFY_TELIS) {
|
||||||
|
uint64_t dataa = entry_.data ^ (entry_.data >> 8);
|
||||||
|
btn = (dataa >> 44) & 0xF; // ctrl
|
||||||
|
cnt = (dataa >> 24) & 0xFFFF; // rolling code
|
||||||
|
serial = dataa & 0xFFFFFF; // address}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace ui
|
} // namespace ui
|
@ -23,6 +23,10 @@
|
|||||||
#ifndef __UI_SUBGHZD_H__
|
#ifndef __UI_SUBGHZD_H__
|
||||||
#define __UI_SUBGHZD_H__
|
#define __UI_SUBGHZD_H__
|
||||||
|
|
||||||
|
#define SD_NO_SERIAL 0xFFFFFFFF
|
||||||
|
#define SD_NO_BTN 0xFF
|
||||||
|
#define SD_NO_CNT 0xFF
|
||||||
|
|
||||||
#include "ui.hpp"
|
#include "ui.hpp"
|
||||||
#include "ui_navigation.hpp"
|
#include "ui_navigation.hpp"
|
||||||
#include "ui_receiver.hpp"
|
#include "ui_receiver.hpp"
|
||||||
@ -33,6 +37,7 @@
|
|||||||
#include "recent_entries.hpp"
|
#include "recent_entries.hpp"
|
||||||
|
|
||||||
#include "../baseband/fprotos/subghztypes.hpp"
|
#include "../baseband/fprotos/subghztypes.hpp"
|
||||||
|
#include "../baseband/fprotos/fprotogeneral.hpp"
|
||||||
|
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
|
|
||||||
@ -42,29 +47,20 @@ struct SubGhzDRecentEntry {
|
|||||||
using Key = uint64_t;
|
using Key = uint64_t;
|
||||||
static constexpr Key invalid_key = 0x0fffffff;
|
static constexpr Key invalid_key = 0x0fffffff;
|
||||||
uint8_t sensorType = FPS_Invalid;
|
uint8_t sensorType = FPS_Invalid;
|
||||||
uint8_t btn = SD_NO_BTN;
|
|
||||||
uint32_t serial = SD_NO_SERIAL;
|
|
||||||
uint16_t bits = 0;
|
uint16_t bits = 0;
|
||||||
uint16_t age = 0; // updated on each seconds, show how long the signal was last seen
|
uint16_t age = 0; // updated on each seconds, show how long the signal was last seen
|
||||||
uint32_t cnt = SD_NO_CNT;
|
|
||||||
uint64_t data = 0;
|
uint64_t data = 0;
|
||||||
SubGhzDRecentEntry() {}
|
SubGhzDRecentEntry() {}
|
||||||
SubGhzDRecentEntry(
|
SubGhzDRecentEntry(
|
||||||
uint8_t sensorType,
|
uint8_t sensorType,
|
||||||
uint32_t serial,
|
|
||||||
uint16_t bits = 0,
|
|
||||||
uint64_t data = 0,
|
uint64_t data = 0,
|
||||||
uint8_t btn = SD_NO_BTN,
|
uint16_t bits = 0)
|
||||||
uint32_t cnt = SD_NO_CNT)
|
|
||||||
: sensorType{sensorType},
|
: sensorType{sensorType},
|
||||||
btn{btn},
|
|
||||||
serial{serial},
|
|
||||||
bits{bits},
|
bits{bits},
|
||||||
cnt{cnt},
|
|
||||||
data{data} {
|
data{data} {
|
||||||
}
|
}
|
||||||
Key key() const {
|
Key key() const {
|
||||||
return (data ^ ((static_cast<uint64_t>(serial) << 32) | (static_cast<uint64_t>(sensorType) & 0xFF) << 0));
|
return (data ^ ((static_cast<uint64_t>(sensorType) & 0xFF) << 0));
|
||||||
}
|
}
|
||||||
void inc_age(int delta) {
|
void inc_age(int delta) {
|
||||||
if (UINT16_MAX - delta > age) age += delta;
|
if (UINT16_MAX - delta > age) age += delta;
|
||||||
@ -149,6 +145,12 @@ class SubGhzDRecentEntryDetailView : public View {
|
|||||||
private:
|
private:
|
||||||
NavigationView& nav_;
|
NavigationView& nav_;
|
||||||
SubGhzDRecentEntry entry_{};
|
SubGhzDRecentEntry entry_{};
|
||||||
|
|
||||||
|
uint32_t serial = 0;
|
||||||
|
uint8_t btn = SD_NO_BTN;
|
||||||
|
uint32_t cnt = SD_NO_CNT;
|
||||||
|
uint32_t seed = 0;
|
||||||
|
|
||||||
Text text_type{{0 * 8, 1 * 16, 15 * 8, 16}, "?"};
|
Text text_type{{0 * 8, 1 * 16, 15 * 8, 16}, "?"};
|
||||||
Text text_id{{6 * 8, 2 * 16, 10 * 8, 16}, "?"};
|
Text text_id{{6 * 8, 2 * 16, 10 * 8, 16}, "?"};
|
||||||
|
|
||||||
@ -164,6 +166,8 @@ class SubGhzDRecentEntryDetailView : public View {
|
|||||||
Button button_done{
|
Button button_done{
|
||||||
{screen_width - 96 - 4, screen_height - 32 - 12, 96, 32},
|
{screen_width - 96 - 4, screen_height - 32 - 12, 96, 32},
|
||||||
"Done"};
|
"Done"};
|
||||||
|
|
||||||
|
void parseProtocol();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ui
|
} // namespace ui
|
||||||
|
@ -53,8 +53,6 @@ class FProtoSubGhzDCame : public FProtoSubGhzDBase {
|
|||||||
parser_step = CameDecoderStepFoundStartBit;
|
parser_step = CameDecoderStepFoundStartBit;
|
||||||
if ((decode_count_bit == min_count_bit_for_found) || (decode_count_bit == AIRFORCE_COUNT_BIT) ||
|
if ((decode_count_bit == min_count_bit_for_found) || (decode_count_bit == AIRFORCE_COUNT_BIT) ||
|
||||||
(decode_count_bit == PRASTEL_COUNT_BIT) || (decode_count_bit == CAME_24_COUNT_BIT)) {
|
(decode_count_bit == PRASTEL_COUNT_BIT) || (decode_count_bit == CAME_24_COUNT_BIT)) {
|
||||||
serial = SD_NO_SERIAL;
|
|
||||||
btn = SD_NO_BTN;
|
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
// if flippa hacky, i hacky
|
// if flippa hacky, i hacky
|
||||||
|
@ -45,36 +45,6 @@ class FProtoSubGhzDCameAtomo : public FProtoSubGhzDBase {
|
|||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
// controller
|
|
||||||
data ^= 0xFFFFFFFFFFFFFFFF;
|
|
||||||
data <<= 4;
|
|
||||||
|
|
||||||
uint8_t pack[8] = {};
|
|
||||||
pack[0] = (data >> 56);
|
|
||||||
pack[1] = ((data >> 48) & 0xFF);
|
|
||||||
pack[2] = ((data >> 40) & 0xFF);
|
|
||||||
pack[3] = ((data >> 32) & 0xFF);
|
|
||||||
pack[4] = ((data >> 24) & 0xFF);
|
|
||||||
pack[5] = ((data >> 16) & 0xFF);
|
|
||||||
pack[6] = ((data >> 8) & 0xFF);
|
|
||||||
pack[7] = (data & 0xFF);
|
|
||||||
|
|
||||||
atomo_decrypt(pack);
|
|
||||||
|
|
||||||
cnt = (uint16_t)pack[1] << 8 | pack[2];
|
|
||||||
serial = (uint32_t)(pack[3]) << 24 | pack[4] << 16 | pack[5] << 8 | pack[6];
|
|
||||||
|
|
||||||
uint8_t btn_decode = (pack[7] >> 4);
|
|
||||||
if (btn_decode == 0x0) {
|
|
||||||
btn = 0x1;
|
|
||||||
} else if (btn_decode == 0x2) {
|
|
||||||
btn = 0x2;
|
|
||||||
} else if (btn_decode == 0x4) {
|
|
||||||
btn = 0x3;
|
|
||||||
} else if (btn_decode == 0x6) {
|
|
||||||
btn = 0x4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
|
@ -45,7 +45,6 @@ class FProtoSubGhzDCameTwee : public FProtoSubGhzDBase {
|
|||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
subghz_protocol_came_twee_remote_controller();
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
@ -79,69 +78,6 @@ class FProtoSubGhzDCameTwee : public FProtoSubGhzDBase {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
ManchesterState manchester_saved_state = ManchesterStateMid1;
|
ManchesterState manchester_saved_state = ManchesterStateMid1;
|
||||||
|
|
||||||
void subghz_protocol_came_twee_remote_controller() {
|
|
||||||
/* Came Twee 54 bit, rolling code 15 parcels with
|
|
||||||
* a decreasing counter from 0xE to 0x0
|
|
||||||
* with originally coded dip switches on the console 10 bit code
|
|
||||||
*
|
|
||||||
* 0x003FFF72E04A6FEE
|
|
||||||
* 0x003FFF72D17B5EDD
|
|
||||||
* 0x003FFF72C2684DCC
|
|
||||||
* 0x003FFF72B3193CBB
|
|
||||||
* 0x003FFF72A40E2BAA
|
|
||||||
* 0x003FFF72953F1A99
|
|
||||||
* 0x003FFF72862C0988
|
|
||||||
* 0x003FFF7277DDF877
|
|
||||||
* 0x003FFF7268C2E766
|
|
||||||
* 0x003FFF7259F3D655
|
|
||||||
* 0x003FFF724AE0C544
|
|
||||||
* 0x003FFF723B91B433
|
|
||||||
* 0x003FFF722C86A322
|
|
||||||
* 0x003FFF721DB79211
|
|
||||||
* 0x003FFF720EA48100
|
|
||||||
*
|
|
||||||
* decryption
|
|
||||||
* the last 32 bits, do XOR by the desired number, divide the result by 4,
|
|
||||||
* convert the first 16 bits of the resulting 32-bit number to bin and do
|
|
||||||
* bit-by-bit mirroring, adding up to 10 bits
|
|
||||||
*
|
|
||||||
* Example
|
|
||||||
* Step 1. 0x003FFF721DB79211 => 0x1DB79211
|
|
||||||
* Step 4. 0x1DB79211 xor 0x1D1D1D11 => 0x00AA8F00
|
|
||||||
* Step 4. 0x00AA8F00 / 4 => 0x002AA3C0
|
|
||||||
* Step 5. 0x002AA3C0 => 0x002A
|
|
||||||
* Step 6. 0x002A bin => b101010
|
|
||||||
* Step 7. b101010 => b0101010000
|
|
||||||
* Step 8. b0101010000 => (Dip) Off ON Off ON Off ON Off Off Off Off
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint8_t cnt_parcel = (uint8_t)(data & 0xF);
|
|
||||||
serial = (uint32_t)(data & 0x0FFFFFFFF);
|
|
||||||
data = (data ^ came_twee_magic_numbers_xor[cnt_parcel]);
|
|
||||||
data /= 4;
|
|
||||||
btn = (data >> 4) & 0x0F;
|
|
||||||
data >>= 16;
|
|
||||||
data = (uint16_t)FProtoGeneral::subghz_protocol_blocks_reverse_key(data, 16);
|
|
||||||
cnt = data >> 6;
|
|
||||||
}
|
|
||||||
inline static const uint32_t came_twee_magic_numbers_xor[15] = {
|
|
||||||
0x0E0E0E00,
|
|
||||||
0x1D1D1D11,
|
|
||||||
0x2C2C2C22,
|
|
||||||
0x3B3B3B33,
|
|
||||||
0x4A4A4A44,
|
|
||||||
0x59595955,
|
|
||||||
0x68686866,
|
|
||||||
0x77777777,
|
|
||||||
0x86868688,
|
|
||||||
0x95959599,
|
|
||||||
0xA4A4A4AA,
|
|
||||||
0xB3B3B3BB,
|
|
||||||
0xC2C2C2CC,
|
|
||||||
0xD1D1D1DD,
|
|
||||||
0xE0E0E0EE,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -57,8 +57,6 @@ class FProtoSubGhzDChambCode : public FProtoSubGhzDBase {
|
|||||||
if (!level) { // save interval
|
if (!level) { // save interval
|
||||||
if (duration > te_short * 5) {
|
if (duration > te_short * 5) {
|
||||||
if (decode_count_bit >= min_count_bit_for_found) {
|
if (decode_count_bit >= min_count_bit_for_found) {
|
||||||
serial = SD_NO_SERIAL;
|
|
||||||
btn = SD_NO_BTN;
|
|
||||||
if (subghz_protocol_decoder_chamb_code_check_mask_and_parse()) {
|
if (subghz_protocol_decoder_chamb_code_check_mask_and_parse()) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
|
@ -64,11 +64,6 @@ class FProtoSubGhzDClemsa : public FProtoSubGhzDBase {
|
|||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
// controller
|
|
||||||
serial = (data >> 2) & 0xFFFF;
|
|
||||||
btn = (data & 0x03);
|
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
parser_step = ClemsaDecoderStepSaveDuration;
|
parser_step = ClemsaDecoderStepSaveDuration;
|
||||||
|
@ -46,10 +46,6 @@ class FProtoSubGhzDDoitrand : public FProtoSubGhzDBase {
|
|||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
// controller
|
|
||||||
cnt = (data >> 24) | ((data >> 15) & 0x1);
|
|
||||||
btn = ((data >> 18) & 0x3);
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
|
@ -74,16 +74,6 @@ class FProtoSubGhzDDooya : public FProtoSubGhzDBase {
|
|||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
// controller:
|
|
||||||
serial = (data >> 16);
|
|
||||||
if ((data >> 12) & 0x0F) {
|
|
||||||
cnt = (data >> 8) & 0x0F;
|
|
||||||
} else {
|
|
||||||
cnt = 0xFF;
|
|
||||||
}
|
|
||||||
btn = data & 0xFF;
|
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -46,12 +46,6 @@ class FProtoSubGhzDGateTx : public FProtoSubGhzDBase {
|
|||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
// controller
|
|
||||||
uint32_t code_found_reverse = FProtoGeneral::subghz_protocol_blocks_reverse_key(data, data_count_bit);
|
|
||||||
serial = (code_found_reverse & 0xFF) << 12 | ((code_found_reverse >> 8) & 0xFF) << 4 | ((code_found_reverse >> 20) & 0x0F);
|
|
||||||
btn = ((code_found_reverse >> 16) & 0x0F);
|
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
|
@ -51,22 +51,6 @@ class FProtoSubGhzDHoltek : public FProtoSubGhzDBase {
|
|||||||
if ((decode_data & HOLTEK_HEADER_MASK) == HOLTEK_HEADER) {
|
if ((decode_data & HOLTEK_HEADER_MASK) == HOLTEK_HEADER) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
// controller
|
|
||||||
serial = FProtoGeneral::subghz_protocol_blocks_reverse_key((data >> 16) & 0xFFFFF, 20);
|
|
||||||
uint16_t btn = data & 0xFFFF;
|
|
||||||
if ((btn & 0xf) != 0xA) {
|
|
||||||
btn = 0x1 << 4 | (btn & 0xF);
|
|
||||||
} else if (((btn >> 4) & 0xF) != 0xA) {
|
|
||||||
btn = 0x2 << 4 | ((btn >> 4) & 0xF);
|
|
||||||
} else if (((btn >> 8) & 0xF) != 0xA) {
|
|
||||||
btn = 0x3 << 4 | ((btn >> 8) & 0xF);
|
|
||||||
} else if (((btn >> 12) & 0xF) != 0xA) {
|
|
||||||
btn = 0x4 << 4 | ((btn >> 12) & 0xF);
|
|
||||||
} else {
|
|
||||||
btn = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,9 +47,6 @@ class FProtoSubGhzDHoltekHt12x : public FProtoSubGhzDBase {
|
|||||||
if (data != decode_data) {
|
if (data != decode_data) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
// controller
|
|
||||||
btn = data & 0x0F;
|
|
||||||
cnt = (data >> 4) & 0xFF;
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,8 +73,6 @@ class FProtoSubGhzDHoneywell : public FProtoSubGhzDBase {
|
|||||||
// the data is good. process it.
|
// the data is good. process it.
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit; // maybe set it to 64, and hack the first 2 bits to 1! will see if replay needs it
|
data_count_bit = decode_count_bit; // maybe set it to 64, and hack the first 2 bits to 1! will see if replay needs it
|
||||||
serial = (decode_data >> 24) & 0xFFFFF;
|
|
||||||
btn = (decode_data >> 16) & 0xFF; // not exactly button, but can contain btn data too.
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
decode_count_bit = 0;
|
decode_count_bit = 0;
|
||||||
|
@ -49,8 +49,6 @@ class FProtoSubGhzDHormann : public FProtoSubGhzDBase {
|
|||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
// controller
|
|
||||||
btn = (data >> 4) & 0xF;
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
130
firmware/baseband/fprotos/s-hormannbisecure.hpp
Normal file
130
firmware/baseband/fprotos/s-hormannbisecure.hpp
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
|
||||||
|
#ifndef __FPROTO_HORMANNBISECURE_H__
|
||||||
|
#define __FPROTO_HORMANNBISECURE_H__
|
||||||
|
|
||||||
|
#include "subghzdbase.hpp"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
HormannBiSecurDecoderStepReset = 0,
|
||||||
|
HormannBiSecurDecoderStepFoundPreambleAlternatingShort,
|
||||||
|
HormannBiSecurDecoderStepFoundPreambleHighVeryLong,
|
||||||
|
HormannBiSecurDecoderStepFoundPreambleAlternatingLong,
|
||||||
|
HormannBiSecurDecoderStepFoundData,
|
||||||
|
} HormannBiSecurDecoderStep;
|
||||||
|
|
||||||
|
class FProtoSubGhzDHormannBiSecure : public FProtoSubGhzDBase {
|
||||||
|
public:
|
||||||
|
FProtoSubGhzDHormannBiSecure() {
|
||||||
|
sensorType = FPS_HORMANN;
|
||||||
|
te_short = 208;
|
||||||
|
te_long = 416;
|
||||||
|
te_delta = 104;
|
||||||
|
min_count_bit_for_found = 176;
|
||||||
|
}
|
||||||
|
|
||||||
|
void subghz_protocol_decoder_hormann_bisecur_reset() {
|
||||||
|
parser_step = HormannBiSecurDecoderStepReset;
|
||||||
|
data = 0;
|
||||||
|
for (uint8_t i = 0; i < 22; ++i) dataa[i] = 0;
|
||||||
|
data_count_bit = 0;
|
||||||
|
manchester_saved_state = ManchesterStateStart1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void feed(bool level, uint32_t duration) {
|
||||||
|
ManchesterEvent event = ManchesterEventReset;
|
||||||
|
|
||||||
|
switch (parser_step) {
|
||||||
|
case HormannBiSecurDecoderStepReset:
|
||||||
|
if (!level && DURATION_DIFF(duration, duration_short + duration_half_short) < te_delta) {
|
||||||
|
parser_step = HormannBiSecurDecoderStepFoundPreambleAlternatingShort;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HormannBiSecurDecoderStepFoundPreambleAlternatingShort:
|
||||||
|
if (DURATION_DIFF(duration, duration_short) < te_delta) {
|
||||||
|
// stay on the same step, the pattern repeats around 21 times
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level && DURATION_DIFF(duration, duration_long * 4) < te_delta) {
|
||||||
|
parser_step = HormannBiSecurDecoderStepFoundPreambleHighVeryLong;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
parser_step = HormannBiSecurDecoderStepReset;
|
||||||
|
break;
|
||||||
|
case HormannBiSecurDecoderStepFoundPreambleHighVeryLong:
|
||||||
|
if (!level && DURATION_DIFF(duration, duration_long) < te_delta) {
|
||||||
|
sync_cnt = 3;
|
||||||
|
parser_step = HormannBiSecurDecoderStepFoundPreambleAlternatingLong;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
parser_step = HormannBiSecurDecoderStepReset;
|
||||||
|
break;
|
||||||
|
case HormannBiSecurDecoderStepFoundPreambleAlternatingLong:
|
||||||
|
if (level == (sync_cnt-- & 1) &&
|
||||||
|
DURATION_DIFF(duration, duration_long) < te_delta) {
|
||||||
|
if (!sync_cnt) {
|
||||||
|
FProtoGeneral::manchester_advance_alt(manchester_saved_state, event, &manchester_saved_state, NULL);
|
||||||
|
parser_step = HormannBiSecurDecoderStepFoundData;
|
||||||
|
}
|
||||||
|
|
||||||
|
// stay on the same step, or advance to the next if enough transitions are found
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
parser_step = HormannBiSecurDecoderStepReset;
|
||||||
|
break;
|
||||||
|
case HormannBiSecurDecoderStepFoundData:
|
||||||
|
if (DURATION_DIFF(duration, duration_short) < te_delta ||
|
||||||
|
(
|
||||||
|
// the last bit can be arbitrary long, but it is parsed as a short
|
||||||
|
data_count_bit == min_count_bit_for_found - 1 &&
|
||||||
|
duration > duration_short)) {
|
||||||
|
event = !level ? ManchesterEventShortHigh : ManchesterEventShortLow;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DURATION_DIFF(duration, duration_long) < te_delta) {
|
||||||
|
event = !level ? ManchesterEventLongHigh : ManchesterEventLongLow;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event == ManchesterEventReset) {
|
||||||
|
subghz_protocol_decoder_hormann_bisecur_reset();
|
||||||
|
} else {
|
||||||
|
bool new_level;
|
||||||
|
|
||||||
|
if (manchester_advance_alt(instance->manchester_saved_state, event, &instance->manchester_saved_state, &new_level)) {
|
||||||
|
subghz_protocol_decoder_hormann_bisecur_add_bit(instance, new_level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void subghz_protocol_decoder_hormann_bisecur_add_bit(bool level) {
|
||||||
|
if (data_count_bit >= min_count_bit_for_found) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level) {
|
||||||
|
uint8_t byte_index = data_count_bit / 8;
|
||||||
|
uint8_t bit_index = data_count_bit % 8;
|
||||||
|
dataa[byte_index] |= 1 << (7 - bit_index);
|
||||||
|
}
|
||||||
|
data_count_bit++;
|
||||||
|
if (data_count_bit >= min_count_bit_for_found) {
|
||||||
|
if (callback) {
|
||||||
|
callback(this);
|
||||||
|
} else {
|
||||||
|
subghz_protocol_decoder_hormann_bisecur_reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ManchesterState manchester_saved_state = ManchesterStateMid1;
|
||||||
|
uint8_t dataa[22] = {0};
|
||||||
|
uint8_t sync_cnt = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -46,12 +46,6 @@ class FProtoSubGhzDIdo : public FProtoSubGhzDBase {
|
|||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
// controller
|
|
||||||
uint64_t code_found_reverse = FProtoGeneral::subghz_protocol_blocks_reverse_key(data, data_count_bit);
|
|
||||||
uint32_t code_fix = code_found_reverse & 0xFFFFFF;
|
|
||||||
|
|
||||||
serial = code_fix & 0xFFFFF;
|
|
||||||
btn = (code_fix >> 20) & 0x0F;
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
|
@ -68,7 +68,6 @@ class FProtoSubGhzDIntertechnoV3 : public FProtoSubGhzDBase {
|
|||||||
(decode_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT)) {
|
(decode_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT)) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
remote_controller();
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -120,29 +119,6 @@ class FProtoSubGhzDIntertechnoV3 : public FProtoSubGhzDBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void remote_controller() {
|
|
||||||
if (data_count_bit == min_count_bit_for_found) {
|
|
||||||
serial = (data >> 6) & 0x3FFFFFF;
|
|
||||||
if ((data >> 5) & 0x1) {
|
|
||||||
cnt = 1 << 5;
|
|
||||||
} else {
|
|
||||||
cnt = (~data & 0xF);
|
|
||||||
}
|
|
||||||
btn = (data >> 4) & 0x1;
|
|
||||||
} else if (data_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT) {
|
|
||||||
serial = (data >> 10) & 0x3FFFFFF;
|
|
||||||
if ((data >> 9) & 0x1) {
|
|
||||||
cnt = 1 << 5;
|
|
||||||
} else {
|
|
||||||
cnt = (~(data >> 4) & 0xF);
|
|
||||||
}
|
|
||||||
btn = data & 0xF;
|
|
||||||
} else {
|
|
||||||
serial = 0;
|
|
||||||
cnt = 0;
|
|
||||||
btn = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -60,12 +60,6 @@ class FProtoSubGhzDKeeLoq : public FProtoSubGhzDBase {
|
|||||||
if (data != decode_data) {
|
if (data != decode_data) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = min_count_bit_for_found;
|
data_count_bit = min_count_bit_for_found;
|
||||||
// controller
|
|
||||||
uint64_t key = FProtoGeneral::subghz_protocol_blocks_reverse_key(data, data_count_bit);
|
|
||||||
uint32_t key_fix = key >> 32;
|
|
||||||
// uint32_t key_hop = key & 0x00000000ffffffff; //unused
|
|
||||||
serial = key_fix & 0x0FFFFFFF;
|
|
||||||
btn = key_fix >> 28;
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
|
@ -61,13 +61,8 @@ class FProtoSubGhzDKinggatesStylo4K : public FProtoSubGhzDBase {
|
|||||||
if (decode_count_bit ==
|
if (decode_count_bit ==
|
||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
data = data_2;
|
data = data_2;
|
||||||
data_2 = decode_data;
|
data_2 = decode_data; // TODO DATA2
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
// controller
|
|
||||||
uint64_t fix = FProtoGeneral::subghz_protocol_blocks_reverse_key(data, 53);
|
|
||||||
|
|
||||||
btn = (fix >> 17) & 0x0F;
|
|
||||||
serial = ((fix >> 5) & 0xFFFF0000) | (fix & 0xFFFF);
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
113
firmware/baseband/fprotos/s-legrand.hpp
Normal file
113
firmware/baseband/fprotos/s-legrand.hpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
|
||||||
|
#ifndef __FPROTO_LEGRAND_H__
|
||||||
|
#define __FPROTO_LEGRAND_H__
|
||||||
|
|
||||||
|
#include "subghzdbase.hpp"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LegrandDecoderStepReset = 0,
|
||||||
|
LegrandDecoderStepFirstBit,
|
||||||
|
LegrandDecoderStepSaveDuration,
|
||||||
|
LegrandDecoderStepCheckDuration,
|
||||||
|
} LegrandDecoderStep;
|
||||||
|
|
||||||
|
class FProtoSubGhzDLegrand : public FProtoSubGhzDBase {
|
||||||
|
public:
|
||||||
|
FProtoSubGhzDLegrand() {
|
||||||
|
sensorType = FPS_LEGRAND;
|
||||||
|
te_short = 375;
|
||||||
|
te_long = 1125;
|
||||||
|
te_delta = 150;
|
||||||
|
min_count_bit_for_found = 18;
|
||||||
|
}
|
||||||
|
|
||||||
|
void feed(bool level, uint32_t duration) {
|
||||||
|
switch (parser_step) {
|
||||||
|
case LegrandDecoderStepReset:
|
||||||
|
if (!level && DURATION_DIFF(duration, te_short * 16) < te_delta * 8) {
|
||||||
|
parser_step = LegrandDecoderStepFirstBit;
|
||||||
|
decode_data = 0;
|
||||||
|
decode_count_bit = 0;
|
||||||
|
te = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LegrandDecoderStepFirstBit:
|
||||||
|
if (level) {
|
||||||
|
if (DURATION_DIFF(duration, te_short) < te_delta) {
|
||||||
|
subghz_protocol_blocks_add_bit(0);
|
||||||
|
te += duration * 4; // long low that is part of sync, then short high
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DURATION_DIFF(duration, te_long) < te_delta * 3) {
|
||||||
|
subghz_protocol_blocks_add_bit(1);
|
||||||
|
te += duration / 3 * 4; // short low that is part of sync, then long high
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decode_count_bit > 0) {
|
||||||
|
// advance to the next step if either short or long is found
|
||||||
|
parser_step = LegrandDecoderStepSaveDuration;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parser_step = LegrandDecoderStepReset;
|
||||||
|
break;
|
||||||
|
case LegrandDecoderStepSaveDuration:
|
||||||
|
if (!level) {
|
||||||
|
te_last = duration;
|
||||||
|
te += duration;
|
||||||
|
parser_step = LegrandDecoderStepCheckDuration;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
parser_step = LegrandDecoderStepReset;
|
||||||
|
break;
|
||||||
|
case LegrandDecoderStepCheckDuration:
|
||||||
|
if (level) {
|
||||||
|
uint8_t found = 0;
|
||||||
|
|
||||||
|
if (DURATION_DIFF(te_last, te_long) < te_delta * 3 && DURATION_DIFF(duration, te_short) < te_delta) {
|
||||||
|
found = 1;
|
||||||
|
subghz_protocol_blocks_add_bit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DURATION_DIFF(te_last, te_short) < te_delta && DURATION_DIFF(duration, te_long) < te_delta * 3) {
|
||||||
|
found = 1;
|
||||||
|
subghz_protocol_blocks_add_bit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
te += duration;
|
||||||
|
|
||||||
|
if (decode_count_bit <
|
||||||
|
min_count_bit_for_found) {
|
||||||
|
parser_step = LegrandDecoderStepSaveDuration;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// enough bits for a packet found, save it only if there was a previous packet
|
||||||
|
// with the same data
|
||||||
|
if (data && (data != decode_data)) {
|
||||||
|
te /= decode_count_bit * 4;
|
||||||
|
|
||||||
|
data = decode_data;
|
||||||
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
|
if (callback) {
|
||||||
|
callback(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// fallthrough to reset, the next bit is expected to be a sync
|
||||||
|
// it also takes care of resetting the decoder state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parser_step = LegrandDecoderStepReset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint32_t te = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -54,11 +54,8 @@ class FProtoSubGhzDLinear : public FProtoSubGhzDBase {
|
|||||||
subghz_protocol_blocks_add_bit(1);
|
subghz_protocol_blocks_add_bit(1);
|
||||||
}
|
}
|
||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
serial = SD_NO_SERIAL;
|
|
||||||
btn = SD_NO_BTN;
|
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -50,12 +50,8 @@ class FProtoSubGhzDLinearDelta3 : public FProtoSubGhzDBase {
|
|||||||
}
|
}
|
||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
if ((data == decode_data) && data) {
|
if ((data == decode_data) && data) {
|
||||||
serial = SD_NO_SERIAL;
|
|
||||||
btn = SD_NO_BTN;
|
|
||||||
|
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
parser_step = LinearD3DecoderStepSaveDuration;
|
parser_step = LinearD3DecoderStepSaveDuration;
|
||||||
|
@ -92,11 +92,6 @@ class FProtoSubGhzDMagellan : public FProtoSubGhzDBase {
|
|||||||
subghz_protocol_magellan_check_crc()) {
|
subghz_protocol_magellan_check_crc()) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
// controller
|
|
||||||
uint64_t data_rev = FProtoGeneral::subghz_protocol_blocks_reverse_key(data >> 8, 24);
|
|
||||||
serial = data_rev & 0xFFFF;
|
|
||||||
btn = (data_rev >> 16) & 0xFF;
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
|
@ -45,9 +45,6 @@ class FProtoSubGhzDMarantec : public FProtoSubGhzDBase {
|
|||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
// controller
|
|
||||||
btn = (data >> 16) & 0xF;
|
|
||||||
serial = ((data >> 12) & 0xFFFFFF00) | ((data >> 8) & 0xFF);
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 1;
|
decode_data = 1;
|
||||||
|
@ -63,9 +63,7 @@ class FProtoSubGhzDMastercode : public FProtoSubGhzDBase {
|
|||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
// controller
|
|
||||||
serial = (data >> 4) & 0xFFFF;
|
|
||||||
btn = (data >> 2 & 0x03);
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
parser_step = MastercodeDecoderStepSaveDuration;
|
parser_step = MastercodeDecoderStepSaveDuration;
|
||||||
|
@ -50,16 +50,7 @@ class FProtoSubGhzDMegacode : public FProtoSubGhzDBase {
|
|||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
// controller
|
|
||||||
if ((data >> 23) == 1) {
|
|
||||||
serial = (data >> 3) & 0xFFFF;
|
|
||||||
btn = data & 0b111;
|
|
||||||
cnt = (data >> 19) & 0b1111;
|
|
||||||
} else {
|
|
||||||
serial = 0;
|
|
||||||
btn = 0;
|
|
||||||
cnt = 0;
|
|
||||||
}
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -47,9 +47,6 @@ class FProtoSubGhzDNiceflo : public FProtoSubGhzDBase {
|
|||||||
if (duration >= (te_short * 4)) {
|
if (duration >= (te_short * 4)) {
|
||||||
parser_step = NiceFloDecoderStepFoundStartBit;
|
parser_step = NiceFloDecoderStepFoundStartBit;
|
||||||
if (decode_count_bit >= min_count_bit_for_found) {
|
if (decode_count_bit >= min_count_bit_for_found) {
|
||||||
serial = SD_NO_SERIAL;
|
|
||||||
btn = SD_NO_BTN;
|
|
||||||
|
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
|
@ -58,10 +58,7 @@ class FProtoSubGhzDNiceflors : public FProtoSubGhzDBase {
|
|||||||
if ((decode_count_bit == min_count_bit_for_found) || (decode_count_bit == NICE_ONE_COUNT_BIT)) {
|
if ((decode_count_bit == min_count_bit_for_found) || (decode_count_bit == NICE_ONE_COUNT_BIT)) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
// controller-
|
|
||||||
cnt = SD_NO_CNT;
|
|
||||||
serial = SD_NO_SERIAL;
|
|
||||||
btn = SD_NO_BTN;
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -47,12 +47,6 @@ class FProtoSubGhzDPhoenixV2 : public FProtoSubGhzDBase {
|
|||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
// controller
|
|
||||||
uint64_t data_rev = FProtoGeneral::subghz_protocol_blocks_reverse_key(data, data_count_bit + 4);
|
|
||||||
serial = data_rev & 0xFFFFFFFF;
|
|
||||||
cnt = (data_rev >> 40) & 0xFFFF;
|
|
||||||
btn = (data_rev >> 32) & 0xF;
|
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
|
@ -52,11 +52,6 @@ class FProtoSubGhzDPowerSmart : public FProtoSubGhzDBase {
|
|||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = min_count_bit_for_found;
|
data_count_bit = min_count_bit_for_found;
|
||||||
|
|
||||||
// controller
|
|
||||||
btn = ((data >> 54) & 0x02) | ((data >> 40) & 0x1);
|
|
||||||
serial = ((data >> 33) & 0x3FFF00) | ((data >> 32) & 0xFF);
|
|
||||||
cnt = ((data >> 49) & 0x3F);
|
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
decode_count_bit = 0;
|
decode_count_bit = 0;
|
||||||
|
@ -44,9 +44,6 @@ class FProtoSubGhzDPrinceton : public FProtoSubGhzDBase {
|
|||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
// controller
|
|
||||||
serial = data >> 4;
|
|
||||||
btn = data & 0xF;
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
|
129
firmware/baseband/fprotos/s-somify_keytis.hpp
Normal file
129
firmware/baseband/fprotos/s-somify_keytis.hpp
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
|
||||||
|
#ifndef __FPROTO_SOMIFYKEYTIS_H__
|
||||||
|
#define __FPROTO_SOMIFYKEYTIS_H__
|
||||||
|
|
||||||
|
#include "subghzdbase.hpp"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SomfyKeytisDecoderStepReset = 0,
|
||||||
|
SomfyKeytisDecoderStepCheckPreambula,
|
||||||
|
SomfyKeytisDecoderStepFoundPreambula,
|
||||||
|
SomfyKeytisDecoderStepStartDecode,
|
||||||
|
SomfyKeytisDecoderStepDecoderData,
|
||||||
|
} SomfyKeytisDecoderStep;
|
||||||
|
|
||||||
|
class FProtoSubGhzDSomifyKeytis : public FProtoSubGhzDBase {
|
||||||
|
public:
|
||||||
|
FProtoSubGhzDSomifyKeytis() {
|
||||||
|
sensorType = FPS_SOMIFY_KEYTIS;
|
||||||
|
te_short = 640;
|
||||||
|
te_long = 1280;
|
||||||
|
te_delta = 250;
|
||||||
|
min_count_bit_for_found = 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
void feed(bool level, uint32_t duration) {
|
||||||
|
ManchesterEvent event = ManchesterEventReset;
|
||||||
|
switch (parser_step) {
|
||||||
|
case SomfyKeytisDecoderStepReset:
|
||||||
|
if ((level) && DURATION_DIFF(duration, te_short * 4) < te_delta * 4) {
|
||||||
|
parser_step = SomfyKeytisDecoderStepFoundPreambula;
|
||||||
|
header_count++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SomfyKeytisDecoderStepFoundPreambula:
|
||||||
|
if ((!level) && (DURATION_DIFF(duration, te_short * 4) < te_delta * 4)) {
|
||||||
|
parser_step = SomfyKeytisDecoderStepCheckPreambula;
|
||||||
|
} else {
|
||||||
|
header_count = 0;
|
||||||
|
parser_step = SomfyKeytisDecoderStepReset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SomfyKeytisDecoderStepCheckPreambula:
|
||||||
|
if (level) {
|
||||||
|
if (DURATION_DIFF(duration, te_short * 4) < te_delta * 4) {
|
||||||
|
parser_step = SomfyKeytisDecoderStepFoundPreambula;
|
||||||
|
header_count++;
|
||||||
|
} else if (
|
||||||
|
(header_count > 1) && (DURATION_DIFF(duration, te_short * 7) < te_delta * 4)) {
|
||||||
|
parser_step = SomfyKeytisDecoderStepDecoderData;
|
||||||
|
decode_data = 0;
|
||||||
|
decode_count_bit = 0;
|
||||||
|
// press_duration_counter = 0;
|
||||||
|
FProtoGeneral::manchester_advance(manchester_saved_state, ManchesterEventReset, &manchester_saved_state, NULL);
|
||||||
|
FProtoGeneral::manchester_advance(manchester_saved_state, ManchesterEventLongHigh, &manchester_saved_state, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SomfyKeytisDecoderStepDecoderData:
|
||||||
|
if (!level) {
|
||||||
|
if (DURATION_DIFF(duration, te_short) < te_delta) {
|
||||||
|
event = ManchesterEventShortLow;
|
||||||
|
} else if (
|
||||||
|
DURATION_DIFF(duration, te_long) < te_delta) {
|
||||||
|
event = ManchesterEventLongLow;
|
||||||
|
} else if (
|
||||||
|
duration >= (te_long + te_delta)) {
|
||||||
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
|
// check crc
|
||||||
|
uint64_t data_tmp = data ^ (data >> 8);
|
||||||
|
if (((data_tmp >> 40) & 0xF) == subghz_protocol_somfy_keytis_crc(data_tmp)) {
|
||||||
|
data = decode_data;
|
||||||
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
|
if (callback) callback(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
decode_data = 0;
|
||||||
|
decode_count_bit = 0;
|
||||||
|
FProtoGeneral::manchester_advance(manchester_saved_state, ManchesterEventReset, &manchester_saved_state, NULL);
|
||||||
|
FProtoGeneral::manchester_advance(manchester_saved_state, ManchesterEventLongHigh, &manchester_saved_state, NULL);
|
||||||
|
parser_step = SomfyKeytisDecoderStepReset;
|
||||||
|
} else {
|
||||||
|
parser_step = SomfyKeytisDecoderStepReset;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (DURATION_DIFF(duration, te_short) <
|
||||||
|
te_delta) {
|
||||||
|
event = ManchesterEventShortHigh;
|
||||||
|
} else if (
|
||||||
|
DURATION_DIFF(duration, te_long) <
|
||||||
|
te_delta) {
|
||||||
|
event = ManchesterEventLongHigh;
|
||||||
|
} else {
|
||||||
|
parser_step = SomfyKeytisDecoderStepReset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (event != ManchesterEventReset) {
|
||||||
|
bool data;
|
||||||
|
bool data_ok = FProtoGeneral::manchester_advance(manchester_saved_state, event, &manchester_saved_state, &data);
|
||||||
|
|
||||||
|
if (data_ok) {
|
||||||
|
if (decode_count_bit < 56) {
|
||||||
|
decode_data = (decode_data << 1) | data;
|
||||||
|
} else {
|
||||||
|
// press_duration_counter = (press_duration_counter << 1) | data;
|
||||||
|
}
|
||||||
|
|
||||||
|
decode_count_bit++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ManchesterState manchester_saved_state = ManchesterStateMid1;
|
||||||
|
uint8_t subghz_protocol_somfy_keytis_crc(uint64_t data) {
|
||||||
|
uint8_t crc = 0;
|
||||||
|
data &= 0xFFF0FFFFFFFFFF;
|
||||||
|
for (uint8_t i = 0; i < 56; i += 8) {
|
||||||
|
crc = crc ^ data >> i ^ (data >> (i + 4));
|
||||||
|
}
|
||||||
|
return crc & 0xf;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
123
firmware/baseband/fprotos/s-somify_telis.hpp
Normal file
123
firmware/baseband/fprotos/s-somify_telis.hpp
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
|
||||||
|
#ifndef __FPROTO_SOMIFYTELIS_H__
|
||||||
|
#define __FPROTO_SOMIFYTELIS_H__
|
||||||
|
|
||||||
|
#include "subghzdbase.hpp"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SomfyTelisDecoderStepReset = 0,
|
||||||
|
SomfyTelisDecoderStepCheckPreambula,
|
||||||
|
SomfyTelisDecoderStepFoundPreambula,
|
||||||
|
SomfyTelisDecoderStepStartDecode,
|
||||||
|
SomfyTelisDecoderStepDecoderData,
|
||||||
|
} SomfyTelisDecoderStep;
|
||||||
|
|
||||||
|
class FProtoSubGhzDSomifyTelis : public FProtoSubGhzDBase {
|
||||||
|
public:
|
||||||
|
FProtoSubGhzDSomifyTelis() {
|
||||||
|
sensorType = FPS_SOMIFY_TELIS;
|
||||||
|
te_short = 640;
|
||||||
|
te_long = 1280;
|
||||||
|
te_delta = 250;
|
||||||
|
min_count_bit_for_found = 56;
|
||||||
|
}
|
||||||
|
|
||||||
|
void feed(bool level, uint32_t duration) {
|
||||||
|
ManchesterEvent event = ManchesterEventReset;
|
||||||
|
switch (parser_step) {
|
||||||
|
case SomfyTelisDecoderStepReset:
|
||||||
|
if ((level) && DURATION_DIFF(duration, te_short * 4) < te_delta * 4) {
|
||||||
|
parser_step = SomfyTelisDecoderStepFoundPreambula;
|
||||||
|
header_count++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SomfyTelisDecoderStepFoundPreambula:
|
||||||
|
if ((!level) && (DURATION_DIFF(duration, te_short * 4) < te_delta * 4)) {
|
||||||
|
parser_step = SomfyTelisDecoderStepCheckPreambula;
|
||||||
|
} else {
|
||||||
|
header_count = 0;
|
||||||
|
parser_step = SomfyTelisDecoderStepReset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SomfyTelisDecoderStepCheckPreambula:
|
||||||
|
if (level) {
|
||||||
|
if (DURATION_DIFF(duration, te_short * 4) < te_delta * 4) {
|
||||||
|
parser_step = SomfyTelisDecoderStepFoundPreambula;
|
||||||
|
header_count++;
|
||||||
|
} else if (
|
||||||
|
(header_count > 1) &&
|
||||||
|
(DURATION_DIFF(duration, te_short * 7) < te_delta * 4)) {
|
||||||
|
parser_step = SomfyTelisDecoderStepDecoderData;
|
||||||
|
decode_data = 0;
|
||||||
|
decode_count_bit = 0;
|
||||||
|
header_count = 0;
|
||||||
|
FProtoGeneral::manchester_advance(manchester_saved_state, ManchesterEventReset, &manchester_saved_state, NULL);
|
||||||
|
FProtoGeneral::manchester_advance(manchester_saved_state, ManchesterEventLongHigh, &manchester_saved_state, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SomfyTelisDecoderStepDecoderData:
|
||||||
|
if (!level) {
|
||||||
|
if (DURATION_DIFF(duration, te_short) < te_delta) {
|
||||||
|
event = ManchesterEventShortLow;
|
||||||
|
} else if (
|
||||||
|
DURATION_DIFF(duration, te_long) < te_delta) {
|
||||||
|
event = ManchesterEventLongLow;
|
||||||
|
} else if (
|
||||||
|
duration >= (te_long + te_delta)) {
|
||||||
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
|
// check crc
|
||||||
|
uint64_t data_tmp = decode_data ^ (decode_data >> 8);
|
||||||
|
if (((data_tmp >> 40) & 0xF) == subghz_protocol_somfy_telis_crc(data_tmp)) {
|
||||||
|
data = decode_data;
|
||||||
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
|
if (callback) callback(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
decode_data = 0;
|
||||||
|
decode_count_bit = 0;
|
||||||
|
FProtoGeneral::manchester_advance(manchester_saved_state, ManchesterEventReset, &manchester_saved_state, NULL);
|
||||||
|
FProtoGeneral::manchester_advance(manchester_saved_state, ManchesterEventLongHigh, &manchester_saved_state, NULL);
|
||||||
|
parser_step = SomfyTelisDecoderStepReset;
|
||||||
|
} else {
|
||||||
|
parser_step = SomfyTelisDecoderStepReset;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (DURATION_DIFF(duration, te_short) < te_delta) {
|
||||||
|
event = ManchesterEventShortHigh;
|
||||||
|
} else if (
|
||||||
|
DURATION_DIFF(duration, te_long) < te_delta) {
|
||||||
|
event = ManchesterEventLongHigh;
|
||||||
|
} else {
|
||||||
|
parser_step = SomfyTelisDecoderStepReset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (event != ManchesterEventReset) {
|
||||||
|
bool data;
|
||||||
|
bool data_ok = FProtoGeneral::manchester_advance(manchester_saved_state, event, &manchester_saved_state, &data);
|
||||||
|
|
||||||
|
if (data_ok) {
|
||||||
|
decode_data = (decode_data << 1) | data;
|
||||||
|
decode_count_bit++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ManchesterState manchester_saved_state = ManchesterStateMid1;
|
||||||
|
uint8_t subghz_protocol_somfy_telis_crc(uint64_t data) {
|
||||||
|
uint8_t crc = 0;
|
||||||
|
data &= 0xFFF0FFFFFFFFFF;
|
||||||
|
for (uint8_t i = 0; i < 56; i += 8) {
|
||||||
|
crc = crc ^ data >> i ^ (data >> (i + 4));
|
||||||
|
}
|
||||||
|
return crc & 0xf;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -25,10 +25,7 @@ class FProtoSubGhzDBase {
|
|||||||
|
|
||||||
// General data holder, these will be passed
|
// General data holder, these will be passed
|
||||||
uint8_t sensorType = FPS_Invalid;
|
uint8_t sensorType = FPS_Invalid;
|
||||||
uint8_t btn = SD_NO_BTN;
|
|
||||||
uint16_t data_count_bit = 0;
|
uint16_t data_count_bit = 0;
|
||||||
uint32_t cnt = SD_NO_CNT;
|
|
||||||
uint32_t serial = SD_NO_SERIAL;
|
|
||||||
uint64_t data = 0;
|
uint64_t data = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -47,6 +47,10 @@ So include here the .hpp, and add a new element to the protos vector in the cons
|
|||||||
#include "s-smc5326.hpp"
|
#include "s-smc5326.hpp"
|
||||||
#include "s-star_line.hpp"
|
#include "s-star_line.hpp"
|
||||||
#include "s-x10.hpp"
|
#include "s-x10.hpp"
|
||||||
|
// #include "s-hormannbisecure.hpp" //fm
|
||||||
|
#include "s-legrand.hpp"
|
||||||
|
#include "s-somify_keytis.hpp"
|
||||||
|
#include "s-somify_telis.hpp"
|
||||||
|
|
||||||
// GENIE FROM PR
|
// GENIE FROM PR
|
||||||
|
|
||||||
@ -94,11 +98,12 @@ class SubGhzDProtos : public FProtoListGeneral {
|
|||||||
protos[FPS_SECPLUSV1] = new FProtoSubGhzDSecPlusV1();
|
protos[FPS_SECPLUSV1] = new FProtoSubGhzDSecPlusV1();
|
||||||
protos[FPS_SECPLUSV2] = new FProtoSubGhzDSecPlusV2();
|
protos[FPS_SECPLUSV2] = new FProtoSubGhzDSecPlusV2();
|
||||||
protos[FPS_SMC5326] = new FProtoSubGhzDSmc5326();
|
protos[FPS_SMC5326] = new FProtoSubGhzDSmc5326();
|
||||||
// somify keytis skipped
|
protos[FPS_SOMIFY_KEYTIS] = new FProtoSubGhzDSomifyKeytis();
|
||||||
// somify telis skipped
|
protos[FPS_SOMIFY_TELIS] = new FProtoSubGhzDSomifyTelis();
|
||||||
protos[FPS_STARLINE] = new FProtoSubGhzDStarLine();
|
protos[FPS_STARLINE] = new FProtoSubGhzDStarLine();
|
||||||
protos[FPS_X10] = new FProtoSubGhzDX10();
|
protos[FPS_X10] = new FProtoSubGhzDX10();
|
||||||
// genie skipped
|
// protos[FPS_HORMANNBISECURE] = new FProtoSubGhzDHormannBiSecure(); //fm
|
||||||
|
protos[FPS_LEGRAND] = new FProtoSubGhzDLegrand();
|
||||||
|
|
||||||
for (uint8_t i = 0; i < FPS_COUNT; ++i) {
|
for (uint8_t i = 0; i < FPS_COUNT; ++i) {
|
||||||
if (protos[i] != NULL) protos[i]->setCallback(callbackTarget);
|
if (protos[i] != NULL) protos[i]->setCallback(callbackTarget);
|
||||||
@ -115,7 +120,7 @@ class SubGhzDProtos : public FProtoListGeneral {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void callbackTarget(FProtoSubGhzDBase* instance) {
|
static void callbackTarget(FProtoSubGhzDBase* instance) {
|
||||||
SubGhzDDataMessage packet_message{instance->sensorType, instance->btn, instance->data_count_bit, instance->serial, instance->data, instance->cnt};
|
SubGhzDDataMessage packet_message{instance->sensorType, instance->data_count_bit, instance->data};
|
||||||
shared_memory.application_queue.push(packet_message);
|
shared_memory.application_queue.push(packet_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,10 +11,6 @@ Also it must have a switch-case element in the getSubGhzDSensorTypeName() functi
|
|||||||
#define FPM_AM 0
|
#define FPM_AM 0
|
||||||
#define FPM_FM 1
|
#define FPM_FM 1
|
||||||
|
|
||||||
#define SD_NO_SERIAL 0xFFFFFFFF
|
|
||||||
#define SD_NO_BTN 0xFF
|
|
||||||
#define SD_NO_CNT 0xFF
|
|
||||||
|
|
||||||
enum FPROTO_SUBGHZD_SENSOR : uint8_t {
|
enum FPROTO_SUBGHZD_SENSOR : uint8_t {
|
||||||
FPS_Invalid = 0,
|
FPS_Invalid = 0,
|
||||||
FPS_PRINCETON,
|
FPS_PRINCETON,
|
||||||
@ -35,10 +31,12 @@ enum FPROTO_SUBGHZD_SENSOR : uint8_t {
|
|||||||
FPS_HONEYWELL,
|
FPS_HONEYWELL,
|
||||||
FPS_HONEYWELLWDB,
|
FPS_HONEYWELLWDB,
|
||||||
FPS_HORMANN,
|
FPS_HORMANN,
|
||||||
|
// FPS_HORMANNBISECURE,
|
||||||
FPS_IDO,
|
FPS_IDO,
|
||||||
FPS_INTERTECHNOV3,
|
FPS_INTERTECHNOV3,
|
||||||
FPS_KEELOQ,
|
FPS_KEELOQ,
|
||||||
FPS_KINGGATESSTYLO4K,
|
FPS_KINGGATESSTYLO4K,
|
||||||
|
FPS_LEGRAND,
|
||||||
FPS_LINEAR,
|
FPS_LINEAR,
|
||||||
FPS_LINEARDELTA3,
|
FPS_LINEARDELTA3,
|
||||||
FPS_MAGELLAN,
|
FPS_MAGELLAN,
|
||||||
@ -56,7 +54,8 @@ enum FPROTO_SUBGHZD_SENSOR : uint8_t {
|
|||||||
FPS_SMC5326,
|
FPS_SMC5326,
|
||||||
FPS_STARLINE,
|
FPS_STARLINE,
|
||||||
FPS_X10,
|
FPS_X10,
|
||||||
|
FPS_SOMIFY_KEYTIS,
|
||||||
|
FPS_SOMIFY_TELIS,
|
||||||
FPS_COUNT
|
FPS_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1289,24 +1289,15 @@ class SubGhzDDataMessage : public Message {
|
|||||||
public:
|
public:
|
||||||
constexpr SubGhzDDataMessage(
|
constexpr SubGhzDDataMessage(
|
||||||
uint8_t sensorType = 0,
|
uint8_t sensorType = 0,
|
||||||
uint8_t btn = 0xFF,
|
|
||||||
uint16_t bits = 0,
|
uint16_t bits = 0,
|
||||||
uint32_t serial = 0xFFFFFFFF,
|
uint64_t data = 0)
|
||||||
uint64_t data = 0,
|
|
||||||
uint32_t cnt = 0xFF)
|
|
||||||
: Message{ID::SubGhzDData},
|
: Message{ID::SubGhzDData},
|
||||||
sensorType{sensorType},
|
sensorType{sensorType},
|
||||||
btn{btn},
|
|
||||||
bits{bits},
|
bits{bits},
|
||||||
serial{serial},
|
|
||||||
cnt{cnt},
|
|
||||||
data{data} {
|
data{data} {
|
||||||
}
|
}
|
||||||
uint8_t sensorType = 0;
|
uint8_t sensorType = 0;
|
||||||
uint8_t btn = 0xFF;
|
|
||||||
uint16_t bits = 0;
|
uint16_t bits = 0;
|
||||||
uint32_t serial = 0xFFFFFFFF;
|
|
||||||
uint32_t cnt = 0xFF;
|
|
||||||
uint64_t data = 0;
|
uint64_t data = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user