diff --git a/applications/main/subghz/helpers/subghz_custom_event.h b/applications/main/subghz/helpers/subghz_custom_event.h index 9fc607889..dffc6d193 100644 --- a/applications/main/subghz/helpers/subghz_custom_event.h +++ b/applications/main/subghz/helpers/subghz_custom_event.h @@ -65,9 +65,6 @@ typedef enum { } SubGhzCustomEvent; typedef enum { - SetTypeFaacSLH_Manual_868, - SetTypeFaacSLH_Manual_433, - SetTypeBFTClone, SetTypeFaacSLH_868, SetTypeFaacSLH_433, SetTypeBFTMitto, diff --git a/applications/main/subghz/helpers/subghz_gen_info.c b/applications/main/subghz/helpers/subghz_gen_info.c new file mode 100644 index 000000000..00ff43abc --- /dev/null +++ b/applications/main/subghz/helpers/subghz_gen_info.c @@ -0,0 +1,725 @@ +#include "subghz_gen_info.h" +#include "../helpers/subghz_txrx_create_protocol_key.h" +#include + + +void subghz_gen_info_reset(GenInfo *gen_info) { + furi_assert(gen_info); + memset(gen_info, 0, sizeof(GenInfo)); +} + +void subghz_scene_set_type_fill_generation_infos(GenInfo* infos_dest, SetType type) { + GenInfo gen_info = { 0 }; + uint64_t key = (uint64_t)rand(); + + uint64_t gangqi_key; + subghz_txrx_gen_serial_gangqi(&gangqi_key); + + uint64_t marantec_key; + subghz_txrx_gen_key_marantec(&marantec_key); + + switch(type) { + case SetTypePricenton433: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_PRINCETON_NAME, + .data.key = (key & 0x00FFFFF0) | 0x4, // btn 0x1, 0x2, 0x4, 0x8 + .data.bits = 24, + .data.te = 400}; + break; + case SetTypePricenton315: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 315000000, + .data.name = SUBGHZ_PROTOCOL_PRINCETON_NAME, + .data.key = (key & 0x00FFFFF0) | 0x4, // btn 0x1, 0x2, 0x4, 0x8 + .data.bits = 24, + .data.te = 400}; + break; + case SetTypeNiceFlo12bit: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_NICE_FLO_NAME, + .data.key = (key & 0x00000FF0) | 0x1, // btn 0x1, 0x2, 0x4 + .data.bits = 12, + .data.te = 0}; + break; + case SetTypeNiceFlo24bit: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_NICE_FLO_NAME, + .data.key = (key & 0x00FFFFF0) | 0x4, // btn 0x1, 0x2, 0x4, 0x8 + .data.bits = 24, + .data.te = 0}; + break; + case SetTypeCAME12bit: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_CAME_NAME, + .data.key = (key & 0x00000FF0) | 0x1, // btn 0x1, 0x2, 0x4 + .data.bits = 12, + .data.te = 0}; + break; + case SetTypeCAME24bit: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_CAME_NAME, + .data.key = (key & 0x00FFFFF0) | 0x4, // btn 0x1, 0x2, 0x4, 0x8 + .data.bits = 24, + .data.te = 0}; + break; + case SetTypeCAME12bit868: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 868350000, + .data.name = SUBGHZ_PROTOCOL_CAME_NAME, + .data.key = (key & 0x00000FF0) | 0x1, // btn 0x1, 0x2, 0x4 + .data.bits = 12, + .data.te = 0}; + break; + case SetTypeCAME24bit868: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 868350000, + .data.name = SUBGHZ_PROTOCOL_CAME_NAME, + .data.key = (key & 0x00FFFFF0) | 0x4, // btn 0x1, 0x2, 0x4, 0x8 + .data.bits = 24, + .data.te = 0}; + break; + case SetTypeRoger_433: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_ROGER_NAME, + .data.key = (key & 0xFFFF000) | 0x0000101, // button code 0x1 and (crc?) is 0x01 + .data.bits = 28, + .data.te = 0}; + break; + case SetTypeLinear_300_00: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 300000000, + .data.name = SUBGHZ_PROTOCOL_LINEAR_NAME, + .data.key = (key & 0x3FF), + .data.bits = 10, + .data.te = 0}; + break; + case SetTypeBETT_433: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_BETT_NAME, + .data.key = (key & 0x0000FFF0), + .data.bits = 18, + .data.te = 0}; + break; + case SetTypeCAMETwee: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_CAME_TWEE_NAME, + .data.key = 0x003FFF7200000000 | ((key & 0x0FFFFFF0) ^ 0xE0E0E0EE), // ???? + .data.bits = 54, + .data.te = 0}; + break; + case SetTypeGateTX: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_GATE_TX_NAME, // btn 0xF, 0xC, 0xA, 0x6 (?) + .data.key = subghz_protocol_blocks_reverse_key((key & 0x00F0FF00) | 0xF0040, 24), + .data.bits = 24, + .data.te = 0}; + break; + case SetTypeGangQi_433: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = + SUBGHZ_PROTOCOL_GANGQI_NAME, // Add button 0xD arm and crc sum to the end + .data.key = gangqi_key, + .data.bits = 34, + .data.te = 0}; + break; + case SetTypeHollarm_433: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_HOLLARM_NAME, // Add button 0x2 and crc sum to the end + .data.key = (key & 0x000FFF0000) | 0xF0B0002200 | + ((((((key & 0x000FFF0000) | 0xF0B0002200) >> 32) & 0xFF) + + ((((key & 0x000FFF0000) | 0xF0B0002200) >> 24) & 0xFF) + + ((((key & 0x000FFF0000) | 0xF0B0002200) >> 16) & 0xFF) + + ((((key & 0x000FFF0000) | 0xF0B0002200) >> 8) & 0xFF)) & + 0xFF), + .data.bits = 42, + .data.te = 0}; + break; + case SetTypeReversRB2_433: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_REVERSRB2_NAME, // 64bits no buttons + .data.key = (key & 0x00000FFFFFFFF000) | 0xFFFFF00000000000 | 0x0000000000000A00, + .data.bits = 64, + .data.te = 0}; + break; + case SetTypeMarantec24_868: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 868350000, + .data.name = SUBGHZ_PROTOCOL_MARANTEC24_NAME, // Add button code 0x8 to the end + .data.key = (key & 0xFFFFF0) | 0x000008, + .data.bits = 24, + .data.te = 0}; + break; + case SetTypeMarantec_433: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = + SUBGHZ_PROTOCOL_MARANTEC_NAME, // Button code is 0x4 and crc sum to the end + .data.key = marantec_key, + .data.bits = 49, + .data.te = 0}; + break; + case SetTypeMarantec_868: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 868350000, + .data.name = + SUBGHZ_PROTOCOL_MARANTEC_NAME, // Button code is 0x4 and crc sum to the end + .data.key = marantec_key, + .data.bits = 49, + .data.te = 0}; + break; + case SetTypeFaacSLH_433: + gen_info = (GenInfo){ + .type = GenFaacSLH, + .mod = "AM650", + .freq = 433920000, + .faac_slh.serial = ((key & 0x00FFFFF0) | 0xA0000006) >> 4, + .faac_slh.btn = 0x06, + .faac_slh.cnt = 0x02, + .faac_slh.seed = key, + .faac_slh.manuf = "FAAC_SLH"}; + break; + case SetTypeFaacSLH_868: + gen_info = (GenInfo){ + .type = GenFaacSLH, + .mod = "AM650", + .freq = 868350000, + .faac_slh.serial = ((key & 0x00FFFFF0) | 0xA0000006) >> 4, + .faac_slh.btn = 0x06, + .faac_slh.cnt = 0x02, + .faac_slh.seed = (key & 0x0FFFFFFF), + .faac_slh.manuf = "FAAC_SLH"}; + break; + case SetTypeBeninca433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x000FFF00) | 0x00800080, + .keeloq.btn = 0x01, + .keeloq.cnt = 0x05, + .keeloq.manuf = "Beninca"}; + break; + case SetTypeBeninca868: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 868350000, + .keeloq.serial = (key & 0x000FFF00) | 0x00800080, + .keeloq.btn = 0x01, + .keeloq.cnt = 0x05, + .keeloq.manuf = "Beninca"}; + break; + case SetTypeComunello433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x08, + .keeloq.cnt = 0x05, + .keeloq.manuf = "Comunello"}; + break; + case SetTypeComunello868: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 868460000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x08, + .keeloq.cnt = 0x05, + .keeloq.manuf = "Comunello"}; + break; + case SetTypeAllmatic433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x00FFFF00) | 0x01000011, + .keeloq.btn = 0x0C, + .keeloq.cnt = 0x05, + .keeloq.manuf = "Beninca"}; + break; + case SetTypeAllmatic868: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 868350000, + .keeloq.serial = (key & 0x00FFFF00) | 0x01000011, + .keeloq.btn = 0x0C, + .keeloq.cnt = 0x05, + .keeloq.manuf = "Beninca"}; + break; + case SetTypeCenturion433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x0000FFFF), + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Centurion"}; + break; + case SetTypeMonarch433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x0000FFFF), + .keeloq.btn = 0x0A, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Monarch"}; + break; + case SetTypeJollyMotors433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x000FFFFF), + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Jolly_Motors"}; + break; + case SetTypeElmesElectronic: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x00FFFFFF) | 0x02000000, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Elmes_Poland"}; + break; + case SetTypeANMotorsAT4: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x000FFFFF) | 0x04700000, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x21, + .keeloq.manuf = "AN-Motors"}; + break; + case SetTypeAprimatic: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x000FFFFF) | 0x00600000, + .keeloq.btn = 0x08, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Aprimatic"}; + break; + case SetTypeGibidi433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Gibidi"}; + break; + case SetTypeGSN: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x0FFFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "GSN"}; + break; + case SetTypeIronLogic: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFF0, + .keeloq.btn = 0x04, + .keeloq.cnt = 0x05, + .keeloq.manuf = "IronLogic"}; + break; + case SetTypeStilmatic: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x0FFFFFFF, + .keeloq.btn = 0x01, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Stilmatic"}; + break; + case SetTypeSommer_FM_434: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "FM476", + .freq = 434420000, + .keeloq.serial = (key & 0x0000FFFF) | 0x01700000, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Sommer(fsk476)"}; + break; + case SetTypeSommer_FM_868: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "FM476", + .freq = 868800000, + .keeloq.serial = (key & 0x0000FFFF) | 0x01700000, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Sommer(fsk476)"}; + break; + case SetTypeSommer_FM238_434: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "FM238", + .freq = 434420000, + .keeloq.serial = key & 0x0000FFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Sommer(fsk476)"}; + break; + case SetTypeSommer_FM238_868: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "FM238", + .freq = 868800000, + .keeloq.serial = key & 0x0000FFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Sommer(fsk476)"}; + break; + case SetTypeDTMNeo433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x000FFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x05, + .keeloq.manuf = "DTM_Neo"}; + break; + case SetTypeCAMESpace: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x04, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Came_Space"}; + break; + case SetTypeCameAtomo433: + gen_info = (GenInfo){ + .type = GenCameAtomo, + .mod = "AM650", + .freq = 433920000, + .came_atomo.serial = (key & 0x0FFFFFFF) | 0x10000000, + .came_atomo.cnt = 0x03}; + break; + case SetTypeCameAtomo868: + gen_info = (GenInfo){ + .type = GenCameAtomo, + .mod = "AM650", + .freq = 868350000, + .came_atomo.serial = (key & 0x0FFFFFFF) | 0x10000000, + .came_atomo.cnt = 0x03}; + break; + case SetTypeBFTMitto: + gen_info = (GenInfo){ + .type = GenKeeloqBFT, + .mod = "AM650", + .freq = 433920000, + .keeloq_bft.serial = key & 0x000FFFFF, + .keeloq_bft.btn = 0x02, + .keeloq_bft.cnt = 0x02, + .keeloq_bft.seed = key & 0x000FFFFF, + .keeloq_bft.manuf = "BFT"}; + break; + case SetTypeAlutechAT4N: + gen_info = (GenInfo){ + .type = GenAlutechAt4n, + .mod = "AM650", + .freq = 433920000, + .alutech_at_4n.serial = (key & 0x000FFFFF) | 0x00100000, + .alutech_at_4n.btn = 0x44, + .alutech_at_4n.cnt = 0x03}; + break; + case SetTypeSomfyTelis: + gen_info = (GenInfo){ + .type = GenSomfyTelis, + .mod = "AM650", + .freq = 433420000, + .somfy_telis.serial = key & 0x00FFFFFF, + .somfy_telis.btn = 0x02, + .somfy_telis.cnt = 0x03}; + break; + case SetTypeMotorline433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x0FFFFFFF, + .keeloq.btn = 0x01, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Motorline"}; + break; + case SetTypeDoorHan_433_92: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x0FFFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "DoorHan"}; + break; + case SetTypeDoorHan_315_00: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 315000000, + .keeloq.serial = key & 0x0FFFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "DoorHan"}; + break; + case SetTypeNiceFlorS_433_92: + gen_info = (GenInfo){ + .type = GenNiceFlorS, + .mod = "AM650", + .freq = 433920000, + .nice_flor_s.serial = key & 0x0FFFFFFF, + .nice_flor_s.btn = 0x01, + .nice_flor_s.cnt = 0x03, + .nice_flor_s.nice_one = false}; + break; + case SetTypeNiceOne_433_92: + gen_info = (GenInfo){ + .type = GenNiceFlorS, + .mod = "AM650", + .freq = 433920000, + .nice_flor_s.serial = key & 0x0FFFFFFF, + .nice_flor_s.btn = 0x01, + .nice_flor_s.cnt = 0x03, + .nice_flor_s.nice_one = true}; + break; + case SetTypeNiceSmilo_433_92: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "NICE_Smilo"}; + break; + case SetTypeNiceMHouse_433_92: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x09, + .keeloq.cnt = 0x03, + .keeloq.manuf = "NICE_MHOUSE"}; + break; + case SetTypeDeaMio433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x0FFFF000) | 0x00000869, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Dea_Mio"}; + break; + case SetTypeGeniusBravo433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x06, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Genius_Bravo"}; + break; + case SetTypeJCM_433_92: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "JCM_Tech"}; + break; + case SetTypeNovoferm_433_92: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x0000FFFF) | 0x018F0000, + .keeloq.btn = 0x01, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Novoferm"}; + break; + case SetTypeHormannEcoStar_433_92: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x000FFFFF) | 0x02200000, + .keeloq.btn = 0x04, + .keeloq.cnt = 0x03, + .keeloq.manuf = "EcoStar"}; + break; + case SetTypeFAACRCXT_433_92: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x0000FFFF) | 0x00100000, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "FAAC_RC,XT"}; + break; + case SetTypeFAACRCXT_868: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 868350000, + .keeloq.serial = (key & 0x0000FFFF) | 0x00100000, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "FAAC_RC,XT"}; + break; + case SetTypeNormstahl_433_92: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x0000FFFF, + .keeloq.btn = 0x04, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Normstahl"}; + break; + case SetTypeHCS101_433_92: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x000FFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "HCS101"}; + break; + case SetTypeSecPlus_v1_315_00: + gen_info = (GenInfo){.type = GenSecPlus1, .mod = "AM650", .freq = 315000000}; + break; + case SetTypeSecPlus_v1_390_00: + gen_info = (GenInfo){.type = GenSecPlus1, .mod = "AM650", .freq = 390000000}; + break; + case SetTypeSecPlus_v1_433_00: + gen_info = (GenInfo){.type = GenSecPlus1, .mod = "AM650", .freq = 433920000}; + break; + case SetTypeSecPlus_v2_310_00: + gen_info = (GenInfo){ + .type = GenSecPlus2, + .mod = "AM650", + .freq = 310000000, + .sec_plus_2.serial = (key & 0x7FFFF3FC), // 850LM pairing + .sec_plus_2.btn = 0x68, + .sec_plus_2.cnt = 0xE500000}; + break; + case SetTypeSecPlus_v2_315_00: + gen_info = (GenInfo){ + .type = GenSecPlus2, + .mod = "AM650", + .freq = 315000000, + .sec_plus_2.serial = (key & 0x7FFFF3FC), // 850LM pairing + .sec_plus_2.btn = 0x68, + .sec_plus_2.cnt = 0xE500000}; + break; + case SetTypeSecPlus_v2_390_00: + gen_info = (GenInfo){ + .type = GenSecPlus2, + .mod = "AM650", + .freq = 390000000, + .sec_plus_2.serial = (key & 0x7FFFF3FC), // 850LM pairing + .sec_plus_2.btn = 0x68, + .sec_plus_2.cnt = 0xE500000}; + break; + case SetTypeSecPlus_v2_433_00: + gen_info = (GenInfo){ + .type = GenSecPlus2, + .mod = "AM650", + .freq = 433920000, + .sec_plus_2.serial = (key & 0x7FFFF3FC), // 850LM pairing + .sec_plus_2.btn = 0x68, + .sec_plus_2.cnt = 0xE500000}; + break; + case SetTypePhoenix_V2_433: + gen_info = (GenInfo){ + .type = GenPhoenixV2, + .mod = "AM650", + .freq = 433920000, + .phoenix_v2.serial = (key & 0x0FFFFFFF) | 0xB0000000, + .phoenix_v2.cnt = 0x025D}; + break; + default: + furi_crash("Not implemented"); + break; + } + *infos_dest = gen_info; +} diff --git a/applications/main/subghz/helpers/subghz_gen_info.h b/applications/main/subghz/helpers/subghz_gen_info.h new file mode 100644 index 000000000..938c6d27a --- /dev/null +++ b/applications/main/subghz/helpers/subghz_gen_info.h @@ -0,0 +1,84 @@ +#pragma once +#include "subghz_types.h" +#include "subghz_custom_event.h" + +typedef enum { + GenData, + GenFaacSLH, + GenKeeloq, + GenCameAtomo, + GenKeeloqBFT, + GenAlutechAt4n, + GenSomfyTelis, + GenNiceFlorS, + GenSecPlus1, + GenSecPlus2, + GenPhoenixV2, +} GenType; + +typedef struct { + GenType type; + const char* mod; + uint32_t freq; + union { + struct { + const char* name; + uint64_t key; + uint8_t bits; + uint16_t te; + } data; + struct { + uint32_t serial; + uint8_t btn; + uint8_t cnt; + uint32_t seed; + const char* manuf; + } faac_slh; + struct { + uint32_t serial; + uint8_t btn; + uint8_t cnt; + const char* manuf; + } keeloq; + struct { + uint32_t serial; + uint8_t cnt; + } came_atomo; + struct { + uint32_t serial; + uint8_t btn; + uint8_t cnt; + uint32_t seed; + const char* manuf; + } keeloq_bft; + struct { + uint32_t serial; + uint8_t btn; + uint8_t cnt; + } alutech_at_4n; + struct { + uint32_t serial; + uint8_t btn; + uint8_t cnt; + } somfy_telis; + struct { + uint32_t serial; + uint8_t btn; + uint8_t cnt; + bool nice_one; + } nice_flor_s; + struct { + uint32_t serial; + uint8_t btn; + uint32_t cnt; + } sec_plus_2; + struct { + uint32_t serial; + uint16_t cnt; + } phoenix_v2; + }; +} GenInfo; + +void subghz_gen_info_reset(GenInfo *gen_info); + +void subghz_scene_set_type_fill_generation_infos(GenInfo* infos_dest, SetType type); diff --git a/applications/main/subghz/scenes/subghz_scene_config.h b/applications/main/subghz/scenes/subghz_scene_config.h index b9480b349..a23a12a2b 100644 --- a/applications/main/subghz/scenes/subghz_scene_config.h +++ b/applications/main/subghz/scenes/subghz_scene_config.h @@ -12,8 +12,10 @@ ADD_SCENE(subghz, saved_menu, SavedMenu) ADD_SCENE(subghz, delete, Delete) ADD_SCENE(subghz, delete_success, DeleteSuccess) ADD_SCENE(subghz, set_type, SetType) -ADD_SCENE(subghz, set_fix, SetFix) -ADD_SCENE(subghz, set_cnt, SetCnt) +ADD_SCENE(subghz, set_key, SetKey) +ADD_SCENE(subghz, set_serial, SetSerial) +ADD_SCENE(subghz, set_button, SetButton) +ADD_SCENE(subghz, set_counter, SetCounter) ADD_SCENE(subghz, set_seed, SetSeed) ADD_SCENE(subghz, frequency_analyzer, FrequencyAnalyzer) ADD_SCENE(subghz, radio_settings, ExtModuleSettings) diff --git a/applications/main/subghz/scenes/subghz_scene_save_name.c b/applications/main/subghz/scenes/subghz_scene_save_name.c index d31f1ce25..66121545d 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_name.c +++ b/applications/main/subghz/scenes/subghz_scene_save_name.c @@ -103,12 +103,8 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { furi_string_set(subghz->file_path, subghz->file_path_tmp); } } - if(scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneSetSeed)) { - scene_manager_search_and_switch_to_previous_scene( - subghz->scene_manager, SubGhzSceneSetType); - } else { - scene_manager_previous_scene(subghz->scene_manager); - } + + scene_manager_previous_scene(subghz->scene_manager); return true; } else if(event.type == SceneManagerEventTypeCustom) { diff --git a/applications/main/subghz/scenes/subghz_scene_set_button.c b/applications/main/subghz/scenes/subghz_scene_set_button.c new file mode 100644 index 000000000..cd5e11f47 --- /dev/null +++ b/applications/main/subghz/scenes/subghz_scene_set_button.c @@ -0,0 +1,111 @@ +#include "../subghz_i.h" +#include "../helpers/subghz_txrx_create_protocol_key.h" + +#define TAG "SubGhzSetButton" + +void subghz_scene_set_button_byte_input_callback(void* context) { + SubGhz* subghz = context; + + view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventByteInputDone); +} + +void subghz_scene_set_button_on_enter(void* context) { + SubGhz* subghz = context; + + uint8_t* byte_ptr = NULL; + uint8_t byte_count = 0; + + switch(subghz->gen_info->type) { + case GenFaacSLH: + byte_ptr = &subghz->gen_info->faac_slh.btn; + byte_count = sizeof(subghz->gen_info->faac_slh.btn); + break; + case GenKeeloq: + byte_ptr = &subghz->gen_info->keeloq.btn; + byte_count = sizeof(subghz->gen_info->keeloq.btn); + break; + case GenKeeloqBFT: + byte_ptr = &subghz->gen_info->keeloq_bft.btn; + byte_count = sizeof(subghz->gen_info->keeloq_bft.btn); + break; + case GenAlutechAt4n: + byte_ptr = &subghz->gen_info->alutech_at_4n.btn; + byte_count = sizeof(subghz->gen_info->alutech_at_4n.btn); + break; + case GenSomfyTelis: + byte_ptr = &subghz->gen_info->somfy_telis.btn; + byte_count = sizeof(subghz->gen_info->somfy_telis.btn); + break; + case GenNiceFlorS: + byte_ptr = &subghz->gen_info->nice_flor_s.btn; + byte_count = sizeof(subghz->gen_info->nice_flor_s.btn); + break; + case GenSecPlus2: + byte_ptr = &subghz->gen_info->sec_plus_2.btn; + byte_count = sizeof(subghz->gen_info->sec_plus_2.btn); + break; + // Not needed for these types + case GenPhoenixV2: + case GenData: + case GenSecPlus1: + case GenCameAtomo: + default: + furi_crash("Not implemented"); + break; + } + + furi_assert(byte_ptr); + furi_assert(byte_count > 0); + + // Setup view + ByteInput* byte_input = subghz->byte_input; + byte_input_set_header_text(byte_input, "Enter BUTTON in hex"); + byte_input_set_result_callback( + byte_input, + subghz_scene_set_button_byte_input_callback, + NULL, + subghz, + byte_ptr, + byte_count); + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdByteInput); +} + +bool subghz_scene_set_button_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubGhzCustomEventByteInputDone) { + switch(subghz->gen_info->type) { + case GenFaacSLH: + case GenKeeloq: + case GenKeeloqBFT: + case GenAlutechAt4n: + case GenSomfyTelis: + case GenNiceFlorS: + case GenSecPlus2: + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetCounter); + break; + // Not needed for these types + case GenCameAtomo: + case GenPhoenixV2: + case GenData: + case GenSecPlus1: + default: + furi_crash("Not implemented"); + break; + } + + consumed = true; + } + } + return consumed; +} + +void subghz_scene_set_button_on_exit(void* context) { + SubGhz* subghz = context; + + // Clear view + byte_input_set_result_callback(subghz->byte_input, NULL, NULL, NULL, NULL, 0); + byte_input_set_header_text(subghz->byte_input, ""); +} diff --git a/applications/main/subghz/scenes/subghz_scene_set_cnt.c b/applications/main/subghz/scenes/subghz_scene_set_cnt.c deleted file mode 100644 index b202d6d91..000000000 --- a/applications/main/subghz/scenes/subghz_scene_set_cnt.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "../subghz_i.h" - -#define TAG "SubGhzSetCnt" - -void subghz_scene_set_cnt_byte_input_callback(void* context) { - SubGhz* subghz = context; - - view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventByteInputDone); -} - -void subghz_scene_set_cnt_on_enter(void* context) { - SubGhz* subghz = context; - - // Setup view - ByteInput* byte_input = subghz->byte_input; - SubGhzCustomEvent state = - scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSetType); - - switch(state) { - case SetTypeBFTClone: - byte_input_set_header_text(byte_input, "Enter COUNTER in hex"); - byte_input_set_result_callback( - byte_input, - subghz_scene_set_cnt_byte_input_callback, - NULL, - subghz, - subghz->secure_data->cnt, - 2); - break; - case SetTypeFaacSLH_Manual_433: - case SetTypeFaacSLH_Manual_868: - byte_input_set_header_text(byte_input, "Enter COUNTER in hex 20 bits"); - byte_input_set_result_callback( - byte_input, - subghz_scene_set_cnt_byte_input_callback, - NULL, - subghz, - subghz->secure_data->cnt, - 3); - break; - default: - break; - } - view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdByteInput); -} - -bool subghz_scene_set_cnt_on_event(void* context, SceneManagerEvent event) { - SubGhz* subghz = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubGhzCustomEventByteInputDone) { - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetSeed); - consumed = true; - } - } - return consumed; -} - -void subghz_scene_set_cnt_on_exit(void* context) { - SubGhz* subghz = context; - - // Clear view - byte_input_set_result_callback(subghz->byte_input, NULL, NULL, NULL, NULL, 0); - byte_input_set_header_text(subghz->byte_input, ""); -} diff --git a/applications/main/subghz/scenes/subghz_scene_set_counter.c b/applications/main/subghz/scenes/subghz_scene_set_counter.c new file mode 100644 index 000000000..b9f241258 --- /dev/null +++ b/applications/main/subghz/scenes/subghz_scene_set_counter.c @@ -0,0 +1,189 @@ +#include "../subghz_i.h" +#include "../helpers/subghz_txrx_create_protocol_key.h" + +#define TAG "SubGhzSetCounter" + +void subghz_scene_set_counter_byte_input_callback(void* context) { + SubGhz* subghz = context; + + view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventByteInputDone); +} + +void subghz_scene_set_counter_on_enter(void* context) { + SubGhz* subghz = context; + + uint8_t* byte_ptr = NULL; + uint8_t byte_count = 0; + + switch(subghz->gen_info->type) { + case GenFaacSLH: + byte_ptr = &subghz->gen_info->faac_slh.cnt; + byte_count = sizeof(subghz->gen_info->faac_slh.cnt); + break; + case GenKeeloq: + byte_ptr = &subghz->gen_info->keeloq.cnt; + byte_count = sizeof(subghz->gen_info->keeloq.cnt); + break; + case GenCameAtomo: + byte_ptr = &subghz->gen_info->came_atomo.cnt; + byte_count = sizeof(subghz->gen_info->came_atomo.cnt); + break; + case GenKeeloqBFT: + byte_ptr = &subghz->gen_info->keeloq_bft.cnt; + byte_count = sizeof(subghz->gen_info->keeloq_bft.cnt); + break; + case GenAlutechAt4n: + byte_ptr = &subghz->gen_info->alutech_at_4n.cnt; + byte_count = sizeof(subghz->gen_info->alutech_at_4n.cnt); + break; + case GenSomfyTelis: + byte_ptr = &subghz->gen_info->somfy_telis.cnt; + byte_count = sizeof(subghz->gen_info->somfy_telis.cnt); + break; + case GenNiceFlorS: + byte_ptr = &subghz->gen_info->nice_flor_s.cnt; + byte_count = sizeof(subghz->gen_info->nice_flor_s.cnt); + break; + case GenSecPlus2: + byte_ptr = (uint8_t*)&subghz->gen_info->sec_plus_2.cnt; + byte_count = sizeof(subghz->gen_info->sec_plus_2.cnt); + break; + case GenPhoenixV2: + byte_ptr = (uint8_t*)&subghz->gen_info->phoenix_v2.cnt; + byte_count = sizeof(subghz->gen_info->phoenix_v2.cnt); + break; + // Not needed for these types + case GenData: + case GenSecPlus1: + default: + furi_crash("Not implemented"); + break; + } + + furi_assert(byte_ptr); + furi_assert(byte_count > 0); + + // Setup view + ByteInput* byte_input = subghz->byte_input; + byte_input_set_header_text(byte_input, "Enter COUNTER in hex"); + + byte_input_set_result_callback( + byte_input, + subghz_scene_set_counter_byte_input_callback, + NULL, + subghz, + byte_ptr, + byte_count); + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdByteInput); +} + +bool subghz_scene_set_counter_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + bool consumed = false; + bool generated_protocol = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubGhzCustomEventByteInputDone) { + GenInfo gen_info = *subghz->gen_info; + + switch(gen_info.type) { + case GenFaacSLH: + case GenKeeloqBFT: + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetSeed); + return true; + case GenKeeloq: + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.keeloq.serial, + gen_info.keeloq.btn, + gen_info.keeloq.cnt, + gen_info.keeloq.manuf); + break; + case GenCameAtomo: + generated_protocol = subghz_txrx_gen_came_atomo_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.came_atomo.serial, + gen_info.came_atomo.cnt); + break; + case GenAlutechAt4n: + generated_protocol = subghz_txrx_gen_alutech_at_4n_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.alutech_at_4n.serial, + gen_info.alutech_at_4n.btn, + gen_info.alutech_at_4n.cnt); + break; + case GenSomfyTelis: + generated_protocol = subghz_txrx_gen_somfy_telis_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.somfy_telis.serial, + gen_info.somfy_telis.btn, + gen_info.somfy_telis.cnt); + break; + case GenNiceFlorS: + generated_protocol = subghz_txrx_gen_nice_flor_s_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.nice_flor_s.serial, + gen_info.nice_flor_s.btn, + gen_info.nice_flor_s.cnt, + gen_info.nice_flor_s.nice_one); + break; + case GenSecPlus2: + generated_protocol = subghz_txrx_gen_secplus_v2_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.sec_plus_2.serial, + gen_info.sec_plus_2.btn, + gen_info.sec_plus_2.cnt); + break; + case GenPhoenixV2: + generated_protocol = subghz_txrx_gen_phoenix_v2_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.phoenix_v2.serial, + gen_info.phoenix_v2.cnt); + break; + // Not needed for these types + case GenData: + case GenSecPlus1: + default: + furi_crash("Not implemented"); + break; + } + + consumed = true; + + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); + } else { + subghz_file_name_clear(subghz); + + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneSetType, SubGhzCustomEventManagerSet); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); + } + } + } + return consumed; +} + +void subghz_scene_set_counter_on_exit(void* context) { + SubGhz* subghz = context; + + // Clear view + byte_input_set_result_callback(subghz->byte_input, NULL, NULL, NULL, NULL, 0); + byte_input_set_header_text(subghz->byte_input, ""); +} diff --git a/applications/main/subghz/scenes/subghz_scene_set_fix.c b/applications/main/subghz/scenes/subghz_scene_set_fix.c deleted file mode 100644 index 93df4e54d..000000000 --- a/applications/main/subghz/scenes/subghz_scene_set_fix.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "../subghz_i.h" - -#define TAG "SubGhzSetFix" - -void subghz_scene_set_fix_byte_input_callback(void* context) { - SubGhz* subghz = context; - - view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventByteInputDone); -} - -void subghz_scene_set_fix_on_enter(void* context) { - SubGhz* subghz = context; - - // Setup view - ByteInput* byte_input = subghz->byte_input; - byte_input_set_header_text(byte_input, "Enter FIX in hex"); - byte_input_set_result_callback( - byte_input, - subghz_scene_set_fix_byte_input_callback, - NULL, - subghz, - subghz->secure_data->fix, - 4); - view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdByteInput); -} - -bool subghz_scene_set_fix_on_event(void* context, SceneManagerEvent event) { - SubGhz* subghz = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubGhzCustomEventByteInputDone) { - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetCnt); - consumed = true; - } - } - return consumed; -} - -void subghz_scene_set_fix_on_exit(void* context) { - SubGhz* subghz = context; - - // Clear view - byte_input_set_result_callback(subghz->byte_input, NULL, NULL, NULL, NULL, 0); - byte_input_set_header_text(subghz->byte_input, ""); -} diff --git a/applications/main/subghz/scenes/subghz_scene_set_key.c b/applications/main/subghz/scenes/subghz_scene_set_key.c new file mode 100644 index 000000000..f9872fb11 --- /dev/null +++ b/applications/main/subghz/scenes/subghz_scene_set_key.c @@ -0,0 +1,95 @@ +#include "../subghz_i.h" +#include "../helpers/subghz_txrx_create_protocol_key.h" + +#define TAG "SubGhzSetKey" + +void subghz_scene_set_key_byte_input_callback(void* context) { + SubGhz* subghz = context; + + view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventByteInputDone); +} + +void subghz_scene_set_key_on_enter(void* context) { + SubGhz* subghz = context; + + uint8_t* byte_ptr = NULL; + uint8_t byte_count = 0; + + if(subghz->gen_info->type == GenData) { + byte_ptr = (uint8_t*)&subghz->gen_info->data.key; + byte_count = sizeof(subghz->gen_info->data.key); + } else { + furi_crash("Not implemented"); + } + + furi_assert(byte_ptr); + furi_assert(byte_count > 0); + + // Setup view + ByteInput* byte_input = subghz->byte_input; + byte_input_set_header_text(byte_input, "Enter KEY in hex"); + byte_input_set_result_callback( + byte_input, + subghz_scene_set_key_byte_input_callback, + NULL, + subghz, + byte_ptr, + byte_count); + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdByteInput); +} + +bool subghz_scene_set_key_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + bool consumed = false; + bool generated_protocol = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubGhzCustomEventByteInputDone) { + GenInfo gen_info = *subghz->gen_info; + + if(gen_info.type == GenData) { + if(gen_info.data.te) { + generated_protocol = subghz_txrx_gen_data_protocol_and_te( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.data.name, + gen_info.data.key, + gen_info.data.bits, + gen_info.data.te); + } else { + generated_protocol = subghz_txrx_gen_data_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.data.name, + gen_info.data.key, + gen_info.data.bits); + } + } + + consumed = true; + + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); + } else { + subghz_file_name_clear(subghz); + + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneSetType, SubGhzCustomEventManagerSet); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); + } + } + } + return consumed; +} + +void subghz_scene_set_key_on_exit(void* context) { + SubGhz* subghz = context; + + // Clear view + byte_input_set_result_callback(subghz->byte_input, NULL, NULL, NULL, NULL, 0); + byte_input_set_header_text(subghz->byte_input, ""); +} diff --git a/applications/main/subghz/scenes/subghz_scene_set_seed.c b/applications/main/subghz/scenes/subghz_scene_set_seed.c index c8301745f..408460518 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_seed.c +++ b/applications/main/subghz/scenes/subghz_scene_set_seed.c @@ -12,6 +12,36 @@ void subghz_scene_set_seed_byte_input_callback(void* context) { void subghz_scene_set_seed_on_enter(void* context) { SubGhz* subghz = context; + uint8_t* byte_ptr = NULL; + uint8_t byte_count = 0; + + switch(subghz->gen_info->type) { + case GenFaacSLH: + byte_ptr = (uint8_t*)&subghz->gen_info->faac_slh.seed; + byte_count = sizeof(subghz->gen_info->faac_slh.seed); + break; + case GenKeeloqBFT: + byte_ptr = (uint8_t*)&subghz->gen_info->keeloq_bft.seed; + byte_count = sizeof(subghz->gen_info->keeloq_bft.seed); + break; + // Not needed for these types + case GenKeeloq: + case GenAlutechAt4n: + case GenSomfyTelis: + case GenNiceFlorS: + case GenSecPlus2: + case GenPhoenixV2: + case GenData: + case GenSecPlus1: + case GenCameAtomo: + default: + furi_crash("Not implemented"); + break; + } + + furi_assert(byte_ptr); + furi_assert(byte_count > 0); + // Setup view ByteInput* byte_input = subghz->byte_input; byte_input_set_header_text(byte_input, "Enter SEED in hex"); @@ -20,8 +50,8 @@ void subghz_scene_set_seed_on_enter(void* context) { subghz_scene_set_seed_byte_input_callback, NULL, subghz, - subghz->secure_data->seed, - 4); + byte_ptr, + byte_count); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdByteInput); } @@ -29,97 +59,61 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; bool consumed = false; bool generated_protocol = false; - uint32_t fix_part, cnt, seed; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventByteInputDone) { - SetType state = - scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSetType); + GenInfo gen_info = *subghz->gen_info; - switch(state) { - case SetTypeBFTClone: - fix_part = subghz->secure_data->fix[0] << 24 | subghz->secure_data->fix[1] << 16 | - subghz->secure_data->fix[2] << 8 | subghz->secure_data->fix[3]; - - cnt = subghz->secure_data->cnt[0] << 8 | subghz->secure_data->cnt[1]; - - seed = subghz->secure_data->seed[0] << 24 | subghz->secure_data->seed[1] << 16 | - subghz->secure_data->seed[2] << 8 | subghz->secure_data->seed[3]; - - generated_protocol = subghz_txrx_gen_keeloq_bft_protocol( - subghz->txrx, - "AM650", - 433920000, - fix_part & 0x0FFFFFFF, - fix_part >> 28, - cnt, - seed, - "BFT"); - - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } - consumed = true; - break; - case SetTypeFaacSLH_Manual_433: - case SetTypeFaacSLH_Manual_868: - fix_part = subghz->secure_data->fix[0] << 24 | subghz->secure_data->fix[1] << 16 | - subghz->secure_data->fix[2] << 8 | subghz->secure_data->fix[3]; - - cnt = subghz->secure_data->cnt[0] << 16 | subghz->secure_data->cnt[1] << 8 | - subghz->secure_data->cnt[2]; - - seed = subghz->secure_data->seed[0] << 24 | subghz->secure_data->seed[1] << 16 | - subghz->secure_data->seed[2] << 8 | subghz->secure_data->seed[3]; - - if(state == SetTypeFaacSLH_Manual_433) { + switch(gen_info.type) { + case GenFaacSLH: generated_protocol = subghz_txrx_gen_faac_slh_protocol( subghz->txrx, - "AM650", - 433920000, - fix_part >> 4, - fix_part & 0xf, - (cnt & 0xFFFFF), - seed, - "FAAC_SLH"); - } else if(state == SetTypeFaacSLH_Manual_868) { - generated_protocol = subghz_txrx_gen_faac_slh_protocol( + gen_info.mod, + gen_info.freq, + gen_info.faac_slh.serial, + gen_info.faac_slh.btn, + gen_info.faac_slh.cnt, + gen_info.faac_slh.seed, + gen_info.faac_slh.manuf); + break; + case GenKeeloqBFT: + generated_protocol = subghz_txrx_gen_keeloq_bft_protocol( subghz->txrx, - "AM650", - 868350000, - fix_part >> 4, - fix_part & 0xf, - (cnt & 0xFFFFF), - seed, - "FAAC_SLH"); - } - - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } - consumed = true; - break; - - default: - break; + gen_info.mod, + gen_info.freq, + gen_info.keeloq_bft.serial, + gen_info.keeloq_bft.btn, + gen_info.keeloq_bft.cnt, + gen_info.keeloq_bft.seed, + gen_info.keeloq_bft.manuf); + break; + // Not needed for these types + case GenKeeloq: + case GenAlutechAt4n: + case GenSomfyTelis: + case GenNiceFlorS: + case GenSecPlus2: + case GenPhoenixV2: + case GenData: + case GenSecPlus1: + case GenCameAtomo: + default: + furi_crash("Not implemented"); + break; } - } - // Reset Seed, Fix, Cnt in secure data after successful or unsuccessful generation - memset(subghz->secure_data->seed, 0, sizeof(subghz->secure_data->seed)); - memset(subghz->secure_data->cnt, 0, sizeof(subghz->secure_data->cnt)); - memset(subghz->secure_data->fix, 0, sizeof(subghz->secure_data->fix)); + consumed = true; - if(generated_protocol) { - subghz_file_name_clear(subghz); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); + } else { + subghz_file_name_clear(subghz); - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneSetType, SubGhzCustomEventManagerSet); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); - return true; + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneSetType, SubGhzCustomEventManagerSet); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); + } } } return consumed; diff --git a/applications/main/subghz/scenes/subghz_scene_set_serial.c b/applications/main/subghz/scenes/subghz_scene_set_serial.c new file mode 100644 index 000000000..42d815dd7 --- /dev/null +++ b/applications/main/subghz/scenes/subghz_scene_set_serial.c @@ -0,0 +1,119 @@ +#include "../subghz_i.h" +#include "../helpers/subghz_txrx_create_protocol_key.h" + +#define TAG "SubGhzSetSerial" + +void subghz_scene_set_serial_byte_input_callback(void* context) { + SubGhz* subghz = context; + + view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventByteInputDone); +} + +void subghz_scene_set_serial_on_enter(void* context) { + SubGhz* subghz = context; + + uint8_t* byte_ptr = NULL; + uint8_t byte_count = 0; + + switch(subghz->gen_info->type) { + case GenFaacSLH: + byte_ptr = (uint8_t*)&subghz->gen_info->faac_slh.serial; + byte_count = sizeof(subghz->gen_info->faac_slh.serial); + break; + case GenKeeloq: + byte_ptr = (uint8_t*)&subghz->gen_info->keeloq.serial; + byte_count = sizeof(subghz->gen_info->keeloq.serial); + break; + case GenCameAtomo: + byte_ptr = (uint8_t*)&subghz->gen_info->came_atomo.serial; + byte_count = sizeof(subghz->gen_info->came_atomo.serial); + break; + case GenKeeloqBFT: + byte_ptr = (uint8_t*)&subghz->gen_info->keeloq_bft.serial; + byte_count = sizeof(subghz->gen_info->keeloq_bft.serial); + break; + case GenAlutechAt4n: + byte_ptr = (uint8_t*)&subghz->gen_info->alutech_at_4n.serial; + byte_count = sizeof(subghz->gen_info->alutech_at_4n.serial); + break; + case GenSomfyTelis: + byte_ptr = (uint8_t*)&subghz->gen_info->somfy_telis.serial; + byte_count = sizeof(subghz->gen_info->somfy_telis.serial); + break; + case GenNiceFlorS: + byte_ptr = (uint8_t*)&subghz->gen_info->nice_flor_s.serial; + byte_count = sizeof(subghz->gen_info->nice_flor_s.serial); + break; + case GenSecPlus2: + byte_ptr = (uint8_t*)&subghz->gen_info->sec_plus_2.serial; + byte_count = sizeof(subghz->gen_info->sec_plus_2.serial); + break; + case GenPhoenixV2: + byte_ptr = (uint8_t*)&subghz->gen_info->phoenix_v2.serial; + byte_count = sizeof(subghz->gen_info->phoenix_v2.serial); + break; + // Not needed for these types + case GenData: + case GenSecPlus1: + default: + furi_crash("Not implemented"); + break; + } + + furi_assert(byte_ptr); + furi_assert(byte_count > 0); + + // Setup view + ByteInput* byte_input = subghz->byte_input; + byte_input_set_header_text(byte_input, "Enter SERIAL in hex"); + byte_input_set_result_callback( + byte_input, + subghz_scene_set_serial_byte_input_callback, + NULL, + subghz, + byte_ptr, + byte_count); + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdByteInput); +} + +bool subghz_scene_set_serial_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubGhzCustomEventByteInputDone) { + switch(subghz->gen_info->type) { + case GenFaacSLH: + case GenKeeloq: + case GenKeeloqBFT: + case GenAlutechAt4n: + case GenSomfyTelis: + case GenNiceFlorS: + case GenSecPlus2: + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetButton); + break; + case GenCameAtomo: + case GenPhoenixV2: + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetCounter); + break; + // Not needed for these types + case GenData: + case GenSecPlus1: + default: + furi_crash("Not implemented"); + break; + } + + consumed = true; + } + } + return consumed; +} + +void subghz_scene_set_serial_on_exit(void* context) { + SubGhz* subghz = context; + + // Clear view + byte_input_set_result_callback(subghz->byte_input, NULL, NULL, NULL, NULL, 0); + byte_input_set_header_text(subghz->byte_input, ""); +} diff --git a/applications/main/subghz/scenes/subghz_scene_set_type.c b/applications/main/subghz/scenes/subghz_scene_set_type.c index b986c2c5d..61e5148de 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_type.c +++ b/applications/main/subghz/scenes/subghz_scene_set_type.c @@ -1,7 +1,8 @@ #include "../subghz_i.h" #include "../helpers/subghz_txrx_create_protocol_key.h" +#include "../helpers/subghz_gen_info.h" +#include "subghz_scene_start.h" #include -#include #define TAG "SubGhzSetType" @@ -11,9 +12,6 @@ void subghz_scene_set_type_submenu_callback(void* context, uint32_t index) { } static const char* submenu_names[SetTypeMAX] = { - [SetTypeFaacSLH_Manual_868] = "FAAC SLH [Man.] 868MHz", - [SetTypeFaacSLH_Manual_433] = "FAAC SLH [Man.] 433MHz", - [SetTypeBFTClone] = "BFT [Manual] 433MHz", [SetTypeFaacSLH_868] = "FAAC SLH 868MHz", [SetTypeFaacSLH_433] = "FAAC SLH 433MHz", [SetTypeBFTMitto] = "BFT Mitto 433MHz", @@ -104,813 +102,10 @@ void subghz_scene_set_type_on_enter(void* context) { view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdMenu); } -typedef enum { - GenData, - GenFaacSLH, - GenKeeloq, - GenCameAtomo, - GenKeeloqBFT, - GenAlutechAt4n, - GenSomfyTelis, - GenNiceFlorS, - GenSecPlus1, - GenSecPlus2, - GenPhoenixV2, -} GenType; - -typedef struct { - GenType type; - const char* mod; - uint32_t freq; - union { - struct { - const char* name; - uint64_t key; - uint8_t bits; - uint16_t te; - } data; - struct { - uint32_t serial; - uint8_t btn; - uint8_t cnt; - uint32_t seed; - const char* manuf; - } faac_slh; - struct { - uint32_t serial; - uint8_t btn; - uint8_t cnt; - const char* manuf; - } keeloq; - struct { - uint32_t serial; - uint8_t cnt; - } came_atomo; - struct { - uint32_t serial; - uint8_t btn; - uint8_t cnt; - uint32_t seed; - const char* manuf; - } keeloq_bft; - struct { - uint32_t serial; - uint8_t btn; - uint8_t cnt; - } alutech_at_4n; - struct { - uint32_t serial; - uint8_t btn; - uint8_t cnt; - } somfy_telis; - struct { - uint32_t serial; - uint8_t btn; - uint8_t cnt; - bool nice_one; - } nice_flor_s; - struct { - uint32_t serial; - uint8_t btn; - uint32_t cnt; - } sec_plus_2; - struct { - uint32_t serial; - uint16_t cnt; - } phoenix_v2; - }; -} GenInfo; - -bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { - SubGhz* subghz = context; +bool subghz_scene_set_type_generate_protocol_from_infos(SubGhz* subghz) { + GenInfo gen_info = *subghz->gen_info; bool generated_protocol = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event >= SetTypeMAX) { - return false; - } - scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneSetType, event.event); - - if(event.event == SetTypeFaacSLH_Manual_868 || event.event == SetTypeFaacSLH_Manual_433 || - event.event == SetTypeBFTClone) { - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFix); - return true; - } - - uint64_t key = (uint64_t)rand(); - - uint64_t gangqi_key; - subghz_txrx_gen_serial_gangqi(&gangqi_key); - - uint64_t marantec_key; - subghz_txrx_gen_key_marantec(&marantec_key); - - GenInfo gen_info = {0}; - switch(event.event) { - case SetTypePricenton433: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 433920000, - .data.name = SUBGHZ_PROTOCOL_PRINCETON_NAME, - .data.key = (key & 0x00FFFFF0) | 0x4, // btn 0x1, 0x2, 0x4, 0x8 - .data.bits = 24, - .data.te = 400}; - break; - case SetTypePricenton315: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 315000000, - .data.name = SUBGHZ_PROTOCOL_PRINCETON_NAME, - .data.key = (key & 0x00FFFFF0) | 0x4, // btn 0x1, 0x2, 0x4, 0x8 - .data.bits = 24, - .data.te = 400}; - break; - case SetTypeNiceFlo12bit: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 433920000, - .data.name = SUBGHZ_PROTOCOL_NICE_FLO_NAME, - .data.key = (key & 0x00000FF0) | 0x1, // btn 0x1, 0x2, 0x4 - .data.bits = 12, - .data.te = 0}; - break; - case SetTypeNiceFlo24bit: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 433920000, - .data.name = SUBGHZ_PROTOCOL_NICE_FLO_NAME, - .data.key = (key & 0x00FFFFF0) | 0x4, // btn 0x1, 0x2, 0x4, 0x8 - .data.bits = 24, - .data.te = 0}; - break; - case SetTypeCAME12bit: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 433920000, - .data.name = SUBGHZ_PROTOCOL_CAME_NAME, - .data.key = (key & 0x00000FF0) | 0x1, // btn 0x1, 0x2, 0x4 - .data.bits = 12, - .data.te = 0}; - break; - case SetTypeCAME24bit: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 433920000, - .data.name = SUBGHZ_PROTOCOL_CAME_NAME, - .data.key = (key & 0x00FFFFF0) | 0x4, // btn 0x1, 0x2, 0x4, 0x8 - .data.bits = 24, - .data.te = 0}; - break; - case SetTypeCAME12bit868: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 868350000, - .data.name = SUBGHZ_PROTOCOL_CAME_NAME, - .data.key = (key & 0x00000FF0) | 0x1, // btn 0x1, 0x2, 0x4 - .data.bits = 12, - .data.te = 0}; - break; - case SetTypeCAME24bit868: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 868350000, - .data.name = SUBGHZ_PROTOCOL_CAME_NAME, - .data.key = (key & 0x00FFFFF0) | 0x4, // btn 0x1, 0x2, 0x4, 0x8 - .data.bits = 24, - .data.te = 0}; - break; - case SetTypeRoger_433: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 433920000, - .data.name = SUBGHZ_PROTOCOL_ROGER_NAME, - .data.key = (key & 0xFFFF000) | 0x0000101, // button code 0x1 and (crc?) is 0x01 - .data.bits = 28, - .data.te = 0}; - break; - case SetTypeLinear_300_00: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 300000000, - .data.name = SUBGHZ_PROTOCOL_LINEAR_NAME, - .data.key = (key & 0x3FF), - .data.bits = 10, - .data.te = 0}; - break; - case SetTypeBETT_433: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 433920000, - .data.name = SUBGHZ_PROTOCOL_BETT_NAME, - .data.key = (key & 0x0000FFF0), - .data.bits = 18, - .data.te = 0}; - break; - case SetTypeCAMETwee: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 433920000, - .data.name = SUBGHZ_PROTOCOL_CAME_TWEE_NAME, - .data.key = 0x003FFF7200000000 | ((key & 0x0FFFFFF0) ^ 0xE0E0E0EE), // ???? - .data.bits = 54, - .data.te = 0}; - break; - case SetTypeGateTX: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 433920000, - .data.name = SUBGHZ_PROTOCOL_GATE_TX_NAME, // btn 0xF, 0xC, 0xA, 0x6 (?) - .data.key = subghz_protocol_blocks_reverse_key((key & 0x00F0FF00) | 0xF0040, 24), - .data.bits = 24, - .data.te = 0}; - break; - case SetTypeGangQi_433: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 433920000, - .data.name = - SUBGHZ_PROTOCOL_GANGQI_NAME, // Add button 0xD arm and crc sum to the end - .data.key = gangqi_key, - .data.bits = 34, - .data.te = 0}; - break; - case SetTypeHollarm_433: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 433920000, - .data.name = SUBGHZ_PROTOCOL_HOLLARM_NAME, // Add button 0x2 and crc sum to the end - .data.key = (key & 0x000FFF0000) | 0xF0B0002200 | - ((((((key & 0x000FFF0000) | 0xF0B0002200) >> 32) & 0xFF) + - ((((key & 0x000FFF0000) | 0xF0B0002200) >> 24) & 0xFF) + - ((((key & 0x000FFF0000) | 0xF0B0002200) >> 16) & 0xFF) + - ((((key & 0x000FFF0000) | 0xF0B0002200) >> 8) & 0xFF)) & - 0xFF), - .data.bits = 42, - .data.te = 0}; - break; - case SetTypeReversRB2_433: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 433920000, - .data.name = SUBGHZ_PROTOCOL_REVERSRB2_NAME, // 64bits no buttons - .data.key = (key & 0x00000FFFFFFFF000) | 0xFFFFF00000000000 | 0x0000000000000A00, - .data.bits = 64, - .data.te = 0}; - break; - case SetTypeMarantec24_868: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 868350000, - .data.name = SUBGHZ_PROTOCOL_MARANTEC24_NAME, // Add button code 0x8 to the end - .data.key = (key & 0xFFFFF0) | 0x000008, - .data.bits = 24, - .data.te = 0}; - break; - case SetTypeMarantec_433: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 433920000, - .data.name = - SUBGHZ_PROTOCOL_MARANTEC_NAME, // Button code is 0x4 and crc sum to the end - .data.key = marantec_key, - .data.bits = 49, - .data.te = 0}; - break; - case SetTypeMarantec_868: - gen_info = (GenInfo){ - .type = GenData, - .mod = "AM650", - .freq = 868350000, - .data.name = - SUBGHZ_PROTOCOL_MARANTEC_NAME, // Button code is 0x4 and crc sum to the end - .data.key = marantec_key, - .data.bits = 49, - .data.te = 0}; - break; - case SetTypeFaacSLH_433: - gen_info = (GenInfo){ - .type = GenFaacSLH, - .mod = "AM650", - .freq = 433920000, - .faac_slh.serial = ((key & 0x00FFFFF0) | 0xA0000006) >> 4, - .faac_slh.btn = 0x06, - .faac_slh.cnt = 0x02, - .faac_slh.seed = key, - .faac_slh.manuf = "FAAC_SLH"}; - break; - case SetTypeFaacSLH_868: - gen_info = (GenInfo){ - .type = GenFaacSLH, - .mod = "AM650", - .freq = 868350000, - .faac_slh.serial = ((key & 0x00FFFFF0) | 0xA0000006) >> 4, - .faac_slh.btn = 0x06, - .faac_slh.cnt = 0x02, - .faac_slh.seed = (key & 0x0FFFFFFF), - .faac_slh.manuf = "FAAC_SLH"}; - break; - case SetTypeBeninca433: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = (key & 0x000FFF00) | 0x00800080, - .keeloq.btn = 0x01, - .keeloq.cnt = 0x05, - .keeloq.manuf = "Beninca"}; - break; - case SetTypeBeninca868: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 868350000, - .keeloq.serial = (key & 0x000FFF00) | 0x00800080, - .keeloq.btn = 0x01, - .keeloq.cnt = 0x05, - .keeloq.manuf = "Beninca"}; - break; - case SetTypeComunello433: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = key & 0x00FFFFFF, - .keeloq.btn = 0x08, - .keeloq.cnt = 0x05, - .keeloq.manuf = "Comunello"}; - break; - case SetTypeComunello868: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 868460000, - .keeloq.serial = key & 0x00FFFFFF, - .keeloq.btn = 0x08, - .keeloq.cnt = 0x05, - .keeloq.manuf = "Comunello"}; - break; - case SetTypeAllmatic433: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = (key & 0x00FFFF00) | 0x01000011, - .keeloq.btn = 0x0C, - .keeloq.cnt = 0x05, - .keeloq.manuf = "Beninca"}; - break; - case SetTypeAllmatic868: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 868350000, - .keeloq.serial = (key & 0x00FFFF00) | 0x01000011, - .keeloq.btn = 0x0C, - .keeloq.cnt = 0x05, - .keeloq.manuf = "Beninca"}; - break; - case SetTypeCenturion433: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = (key & 0x0000FFFF), - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Centurion"}; - break; - case SetTypeMonarch433: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = (key & 0x0000FFFF), - .keeloq.btn = 0x0A, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Monarch"}; - break; - case SetTypeJollyMotors433: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = (key & 0x000FFFFF), - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Jolly_Motors"}; - break; - case SetTypeElmesElectronic: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = (key & 0x00FFFFFF) | 0x02000000, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Elmes_Poland"}; - break; - case SetTypeANMotorsAT4: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = (key & 0x000FFFFF) | 0x04700000, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x21, - .keeloq.manuf = "AN-Motors"}; - break; - case SetTypeAprimatic: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = (key & 0x000FFFFF) | 0x00600000, - .keeloq.btn = 0x08, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Aprimatic"}; - break; - case SetTypeGibidi433: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = key & 0x00FFFFFF, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Gibidi"}; - break; - case SetTypeGSN: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = key & 0x0FFFFFFF, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "GSN"}; - break; - case SetTypeIronLogic: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = key & 0x00FFFFF0, - .keeloq.btn = 0x04, - .keeloq.cnt = 0x05, - .keeloq.manuf = "IronLogic"}; - break; - case SetTypeStilmatic: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = key & 0x0FFFFFFF, - .keeloq.btn = 0x01, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Stilmatic"}; - break; - case SetTypeSommer_FM_434: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "FM476", - .freq = 434420000, - .keeloq.serial = (key & 0x0000FFFF) | 0x01700000, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Sommer(fsk476)"}; - break; - case SetTypeSommer_FM_868: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "FM476", - .freq = 868800000, - .keeloq.serial = (key & 0x0000FFFF) | 0x01700000, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Sommer(fsk476)"}; - break; - case SetTypeSommer_FM238_434: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "FM238", - .freq = 434420000, - .keeloq.serial = key & 0x0000FFFF, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Sommer(fsk476)"}; - break; - case SetTypeSommer_FM238_868: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "FM238", - .freq = 868800000, - .keeloq.serial = key & 0x0000FFFF, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Sommer(fsk476)"}; - break; - case SetTypeDTMNeo433: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = key & 0x000FFFFF, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x05, - .keeloq.manuf = "DTM_Neo"}; - break; - case SetTypeCAMESpace: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = key & 0x00FFFFFF, - .keeloq.btn = 0x04, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Came_Space"}; - break; - case SetTypeCameAtomo433: - gen_info = (GenInfo){ - .type = GenCameAtomo, - .mod = "AM650", - .freq = 433920000, - .came_atomo.serial = (key & 0x0FFFFFFF) | 0x10000000, - .came_atomo.cnt = 0x03}; - break; - case SetTypeCameAtomo868: - gen_info = (GenInfo){ - .type = GenCameAtomo, - .mod = "AM650", - .freq = 868350000, - .came_atomo.serial = (key & 0x0FFFFFFF) | 0x10000000, - .came_atomo.cnt = 0x03}; - break; - case SetTypeBFTMitto: - gen_info = (GenInfo){ - .type = GenKeeloqBFT, - .mod = "AM650", - .freq = 433920000, - .keeloq_bft.serial = key & 0x000FFFFF, - .keeloq_bft.btn = 0x02, - .keeloq_bft.cnt = 0x02, - .keeloq_bft.seed = key & 0x000FFFFF, - .keeloq_bft.manuf = "BFT"}; - break; - case SetTypeAlutechAT4N: - gen_info = (GenInfo){ - .type = GenAlutechAt4n, - .mod = "AM650", - .freq = 433920000, - .alutech_at_4n.serial = (key & 0x000FFFFF) | 0x00100000, - .alutech_at_4n.btn = 0x44, - .alutech_at_4n.cnt = 0x03}; - break; - case SetTypeSomfyTelis: - gen_info = (GenInfo){ - .type = GenSomfyTelis, - .mod = "AM650", - .freq = 433420000, - .somfy_telis.serial = key & 0x00FFFFFF, - .somfy_telis.btn = 0x02, - .somfy_telis.cnt = 0x03}; - break; - case SetTypeMotorline433: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = key & 0x0FFFFFFF, - .keeloq.btn = 0x01, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Motorline"}; - break; - case SetTypeDoorHan_433_92: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = key & 0x0FFFFFFF, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "DoorHan"}; - break; - case SetTypeDoorHan_315_00: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 315000000, - .keeloq.serial = key & 0x0FFFFFFF, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "DoorHan"}; - break; - case SetTypeNiceFlorS_433_92: - gen_info = (GenInfo){ - .type = GenNiceFlorS, - .mod = "AM650", - .freq = 433920000, - .nice_flor_s.serial = key & 0x0FFFFFFF, - .nice_flor_s.btn = 0x01, - .nice_flor_s.cnt = 0x03, - .nice_flor_s.nice_one = false}; - break; - case SetTypeNiceOne_433_92: - gen_info = (GenInfo){ - .type = GenNiceFlorS, - .mod = "AM650", - .freq = 433920000, - .nice_flor_s.serial = key & 0x0FFFFFFF, - .nice_flor_s.btn = 0x01, - .nice_flor_s.cnt = 0x03, - .nice_flor_s.nice_one = true}; - break; - case SetTypeNiceSmilo_433_92: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = key & 0x00FFFFFF, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "NICE_Smilo"}; - break; - case SetTypeNiceMHouse_433_92: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = key & 0x00FFFFFF, - .keeloq.btn = 0x09, - .keeloq.cnt = 0x03, - .keeloq.manuf = "NICE_MHOUSE"}; - break; - case SetTypeDeaMio433: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = (key & 0x0FFFF000) | 0x00000869, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Dea_Mio"}; - break; - case SetTypeGeniusBravo433: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = key & 0x00FFFFFF, - .keeloq.btn = 0x06, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Genius_Bravo"}; - break; - case SetTypeJCM_433_92: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = key & 0x00FFFFFF, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "JCM_Tech"}; - break; - case SetTypeNovoferm_433_92: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = (key & 0x0000FFFF) | 0x018F0000, - .keeloq.btn = 0x01, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Novoferm"}; - break; - case SetTypeHormannEcoStar_433_92: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = (key & 0x000FFFFF) | 0x02200000, - .keeloq.btn = 0x04, - .keeloq.cnt = 0x03, - .keeloq.manuf = "EcoStar"}; - break; - case SetTypeFAACRCXT_433_92: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = (key & 0x0000FFFF) | 0x00100000, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "FAAC_RC,XT"}; - break; - case SetTypeFAACRCXT_868: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 868350000, - .keeloq.serial = (key & 0x0000FFFF) | 0x00100000, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "FAAC_RC,XT"}; - break; - case SetTypeNormstahl_433_92: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = key & 0x0000FFFF, - .keeloq.btn = 0x04, - .keeloq.cnt = 0x03, - .keeloq.manuf = "Normstahl"}; - break; - case SetTypeHCS101_433_92: - gen_info = (GenInfo){ - .type = GenKeeloq, - .mod = "AM650", - .freq = 433920000, - .keeloq.serial = key & 0x000FFFFF, - .keeloq.btn = 0x02, - .keeloq.cnt = 0x03, - .keeloq.manuf = "HCS101"}; - break; - case SetTypeSecPlus_v1_315_00: - gen_info = (GenInfo){.type = GenSecPlus1, .mod = "AM650", .freq = 315000000}; - break; - case SetTypeSecPlus_v1_390_00: - gen_info = (GenInfo){.type = GenSecPlus1, .mod = "AM650", .freq = 390000000}; - break; - case SetTypeSecPlus_v1_433_00: - gen_info = (GenInfo){.type = GenSecPlus1, .mod = "AM650", .freq = 433920000}; - break; - case SetTypeSecPlus_v2_310_00: - gen_info = (GenInfo){ - .type = GenSecPlus2, - .mod = "AM650", - .freq = 310000000, - .sec_plus_2.serial = (key & 0x7FFFF3FC), // 850LM pairing - .sec_plus_2.btn = 0x68, - .sec_plus_2.cnt = 0xE500000}; - break; - case SetTypeSecPlus_v2_315_00: - gen_info = (GenInfo){ - .type = GenSecPlus2, - .mod = "AM650", - .freq = 315000000, - .sec_plus_2.serial = (key & 0x7FFFF3FC), // 850LM pairing - .sec_plus_2.btn = 0x68, - .sec_plus_2.cnt = 0xE500000}; - break; - case SetTypeSecPlus_v2_390_00: - gen_info = (GenInfo){ - .type = GenSecPlus2, - .mod = "AM650", - .freq = 390000000, - .sec_plus_2.serial = (key & 0x7FFFF3FC), // 850LM pairing - .sec_plus_2.btn = 0x68, - .sec_plus_2.cnt = 0xE500000}; - break; - case SetTypeSecPlus_v2_433_00: - gen_info = (GenInfo){ - .type = GenSecPlus2, - .mod = "AM650", - .freq = 433920000, - .sec_plus_2.serial = (key & 0x7FFFF3FC), // 850LM pairing - .sec_plus_2.btn = 0x68, - .sec_plus_2.cnt = 0xE500000}; - break; - case SetTypePhoenix_V2_433: - gen_info = (GenInfo){ - .type = GenPhoenixV2, - .mod = "AM650", - .freq = 433920000, - .phoenix_v2.serial = (key & 0x0FFFFFFF) | 0xB0000000, - .phoenix_v2.cnt = 0x025D}; - break; - default: - furi_crash("Not implemented"); - break; - } - - switch(gen_info.type) { + switch(gen_info.type) { case GenData: if(gen_info.data.te) { generated_protocol = subghz_txrx_gen_data_protocol_and_te( @@ -1023,15 +218,54 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { default: furi_crash("Not implemented"); break; - } + } - if(generated_protocol) { - subghz_file_name_clear(subghz); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); - } else { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); + if(generated_protocol) { + subghz_file_name_clear(subghz); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); + } else { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); + } + return generated_protocol; +} + +bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + bool generated_protocol = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event >= SetTypeMAX) { + return false; + } + scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneSetType, event.event); + + subghz_gen_info_reset(subghz->gen_info); + subghz_scene_set_type_fill_generation_infos(subghz->gen_info, event.event); + + if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneStart) == SubmenuIndexAddManually) { + generated_protocol = subghz_scene_set_type_generate_protocol_from_infos(subghz); + } else if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneStart) == SubmenuIndexAddManuallyAdvanced) { + switch(subghz->gen_info->type) { + case GenData: // Key (u64) + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetKey); + break; + case GenSecPlus1: // None + return subghz_txrx_gen_secplus_v1_protocol(subghz->txrx, subghz->gen_info->mod, subghz->gen_info->freq); + case GenFaacSLH: // Serial (u32), Button (u8), Counter (u8), Seed (u32) + case GenKeeloq: // Serial (u32), Button (u8), Counter (u8) + case GenCameAtomo: // Serial (u32), Counter (u8) + case GenKeeloqBFT: // Serial (u32), Button (u8), Counter (u8), Seed (u32) + case GenAlutechAt4n: // Serial (u32), Button (u8), Counter (u8) + case GenSomfyTelis: // Serial (u32), Button (u8), Counter (u8) + case GenNiceFlorS: // Serial (u32), Button (u8), Counter (u8) + case GenSecPlus2: // Serial (u32), Button (u8), Counter (u32) + case GenPhoenixV2: // Serial (u32), Counter (u16) + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetSerial); + break; + } + return true; } } diff --git a/applications/main/subghz/scenes/subghz_scene_start.c b/applications/main/subghz/scenes/subghz_scene_start.c index fd5ce9990..6046b2c6d 100644 --- a/applications/main/subghz/scenes/subghz_scene_start.c +++ b/applications/main/subghz/scenes/subghz_scene_start.c @@ -1,18 +1,9 @@ #include "../subghz_i.h" +#include "subghz_scene_start.h" #include #include -enum SubmenuIndex { - SubmenuIndexRead = 10, - SubmenuIndexSaved, - SubmenuIndexAddManually, - SubmenuIndexFrequencyAnalyzer, - SubmenuIndexReadRAW, - SubmenuIndexExtSettings, - SubmenuIndexRadioSetting, -}; - void subghz_scene_start_submenu_callback(void* context, uint32_t index) { SubGhz* subghz = context; view_dispatcher_send_custom_event(subghz->view_dispatcher, index); @@ -40,6 +31,12 @@ void subghz_scene_start_on_enter(void* context) { SubmenuIndexAddManually, subghz_scene_start_submenu_callback, subghz); + submenu_add_item( + subghz->submenu, + "Add Manually [Advanced]", + SubmenuIndexAddManuallyAdvanced, + subghz_scene_start_submenu_callback, + subghz); submenu_add_item( subghz->submenu, "Frequency Analyzer", @@ -88,6 +85,11 @@ bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) { subghz->scene_manager, SubGhzSceneStart, SubmenuIndexAddManually); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetType); return true; + } else if(event.event == SubmenuIndexAddManuallyAdvanced) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneStart, SubmenuIndexAddManuallyAdvanced); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetType); + return true; } else if(event.event == SubmenuIndexFrequencyAnalyzer) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneStart, SubmenuIndexFrequencyAnalyzer); diff --git a/applications/main/subghz/scenes/subghz_scene_start.h b/applications/main/subghz/scenes/subghz_scene_start.h new file mode 100644 index 000000000..8e446f0c0 --- /dev/null +++ b/applications/main/subghz/scenes/subghz_scene_start.h @@ -0,0 +1,12 @@ +#pragma once + +enum SubmenuIndex { + SubmenuIndexRead = 10, + SubmenuIndexSaved, + SubmenuIndexAddManually, + SubmenuIndexAddManuallyAdvanced, + SubmenuIndexFrequencyAnalyzer, + SubmenuIndexReadRAW, + SubmenuIndexExtSettings, + SubmenuIndexRadioSetting, +}; diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index 83e68229b..f8877551d 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -213,7 +213,7 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); - subghz->secure_data = malloc(sizeof(SecureData)); + subghz->gen_info = malloc(sizeof(GenInfo)); if(!alloc_for_tx_only) { subghz->ignore_filter = subghz->last_settings->ignore_filter; @@ -319,7 +319,7 @@ void subghz_free(SubGhz* subghz, bool alloc_for_tx_only) { subghz_history_free(subghz->history); } - free(subghz->secure_data); + free(subghz->gen_info); //TxRx subghz_txrx_free(subghz->txrx); diff --git a/applications/main/subghz/subghz_i.h b/applications/main/subghz/subghz_i.h index b9fc47f79..10a2ce9f8 100644 --- a/applications/main/subghz/subghz_i.h +++ b/applications/main/subghz/subghz_i.h @@ -1,6 +1,7 @@ #pragma once #include "helpers/subghz_types.h" +#include "helpers/subghz_gen_info.h" #include #include "subghz.h" #include "views/receiver.h" @@ -44,12 +45,6 @@ #define SUBGHZ_RAW_THRESHOLD_MIN (-90.0f) #define SUBGHZ_MEASURE_LOADING false -typedef struct { - uint8_t fix[4]; - uint8_t cnt[4]; - uint8_t seed[4]; -} SecureData; - struct SubGhz { Gui* gui; NotificationApp* notifications; @@ -88,7 +83,7 @@ struct SubGhz { FuriString* error_str; SubGhzLock lock; - SecureData* secure_data; + GenInfo* gen_info; SubGhzFileEncoderWorker* decode_raw_file_worker_encoder;