diff --git a/applications/main/subghz/helpers/subghz_custom_event.h b/applications/main/subghz/helpers/subghz_custom_event.h index cd163a653..bf3c71d3a 100644 --- a/applications/main/subghz/helpers/subghz_custom_event.h +++ b/applications/main/subghz/helpers/subghz_custom_event.h @@ -36,6 +36,8 @@ typedef enum { SubmenuIndexCAME24bit868, SubmenuIndexCAMETwee, SubmenuIndexCAMESpace, + SubmenuIndexCameAtomo433, + SubmenuIndexCameAtomo868, SubmenuIndexPricenton433, SubmenuIndexPricenton315, SubmenuIndexBETT_433, diff --git a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c index 0631c7c15..4854bc882 100644 --- a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c +++ b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c @@ -266,6 +266,34 @@ bool subghz_txrx_gen_alutech_at_4n_protocol( return res; } +bool subghz_txrx_gen_came_atomo_protocol( + void* context, + const char* preset_name, + uint32_t frequency, + uint32_t serial, + uint16_t cnt) { + SubGhzTxRx* txrx = context; + + bool res = false; + + txrx->transmitter = + subghz_transmitter_alloc_init(txrx->environment, SUBGHZ_PROTOCOL_CAME_ATOMO_NAME); + subghz_txrx_set_preset(txrx, preset_name, frequency, NULL, 0); + + if(txrx->transmitter && subghz_protocol_came_atomo_create_data( + subghz_transmitter_get_protocol_instance(txrx->transmitter), + txrx->fff_data, + serial, + cnt, + txrx->preset)) { + res = true; + } + + subghz_transmitter_free(txrx->transmitter); + + return res; +} + bool subghz_txrx_gen_somfy_telis_protocol( void* context, const char* preset_name, diff --git a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h index a5fa2a802..dc7dfbe7e 100644 --- a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h +++ b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h @@ -108,6 +108,13 @@ bool subghz_txrx_gen_somfy_telis_protocol( uint8_t btn, uint16_t cnt); +bool subghz_txrx_gen_came_atomo_protocol( + void* context, + const char* preset_name, + uint32_t frequency, + uint32_t serial, + uint16_t cnt); + /** * Generate data SecPlus v2 protocol * diff --git a/applications/main/subghz/scenes/subghz_scene_set_type.c b/applications/main/subghz/scenes/subghz_scene_set_type.c index ef53006da..14d8ba0d8 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_type.c +++ b/applications/main/subghz/scenes/subghz_scene_set_type.c @@ -199,6 +199,18 @@ void subghz_scene_set_type_on_enter(void* context) { SubmenuIndexCAMETwee, subghz_scene_set_type_submenu_callback, subghz); + submenu_add_item( + subghz->submenu, + "CAME Atomo 433MHz", + SubmenuIndexCameAtomo433, + subghz_scene_set_type_submenu_callback, + subghz); + submenu_add_item( + subghz->submenu, + "CAME Atomo 868MHz", + SubmenuIndexCameAtomo868, + subghz_scene_set_type_submenu_callback, + subghz); submenu_add_item( subghz->submenu, "KL: CAME Space 433MHz", @@ -534,6 +546,14 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; + case SubmenuIndexCameAtomo433: + generated_protocol = subghz_txrx_gen_came_atomo_protocol( + subghz->txrx, "AM650", 433920000, (key & 0x0FFFFFFF) | 0x10000000, 0x0003); + break; + case SubmenuIndexCameAtomo868: + generated_protocol = subghz_txrx_gen_came_atomo_protocol( + subghz->txrx, "AM650", 868350000, (key & 0x0FFFFFFF) | 0x10000000, 0x0003); + break; case SubmenuIndexBFTMitto: generated_protocol = subghz_txrx_gen_keeloq_bft_protocol( subghz->txrx, diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 7d77d7de8..9016f9274 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -2757,6 +2757,7 @@ Function,+,subghz_protocol_blocks_parity_bytes,uint8_t,"const uint8_t[], size_t" Function,+,subghz_protocol_blocks_reverse_key,uint64_t,"uint64_t, uint8_t" Function,+,subghz_protocol_blocks_set_bit_array,void,"_Bool, uint8_t[], size_t, size_t" Function,+,subghz_protocol_blocks_xor_bytes,uint8_t,"const uint8_t[], size_t" +Function,-,subghz_protocol_came_atomo_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint16_t, SubGhzRadioPreset*" Function,-,subghz_protocol_decoder_alutech_at_4n_alloc,void*,SubGhzEnvironment* Function,-,subghz_protocol_decoder_alutech_at_4n_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" Function,-,subghz_protocol_decoder_alutech_at_4n_feed,void,"void*, _Bool, uint32_t" diff --git a/lib/subghz/protocols/came_atomo.c b/lib/subghz/protocols/came_atomo.c index 870afede3..18e0214bb 100644 --- a/lib/subghz/protocols/came_atomo.c +++ b/lib/subghz/protocols/came_atomo.c @@ -120,6 +120,46 @@ static LevelDuration return level_duration_make(data.level, data.duration); } +bool subghz_protocol_came_atomo_create_data( + void* context, + FlipperFormat* flipper_format, + uint32_t serial, + uint16_t cnt, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolEncoderCameAtomo* instance = context; + instance->generic.btn = 0x1; + instance->generic.serial = serial; + instance->generic.cnt = cnt; + instance->generic.cnt_2 = 0x7e; + instance->generic.data_count_bit = 62; + instance->generic.data_2 = + ((uint64_t)0x7e << 56 | (uint64_t)cnt << 40 | (uint64_t)serial << 8); + + uint8_t pack[8] = {}; + + pack[0] = (instance->generic.cnt_2); + pack[1] = (instance->generic.cnt >> 8); + pack[2] = (instance->generic.cnt & 0xFF); + pack[3] = ((instance->generic.data_2 >> 32) & 0xFF); + pack[4] = ((instance->generic.data_2 >> 24) & 0xFF); + pack[5] = ((instance->generic.data_2 >> 16) & 0xFF); + pack[6] = ((instance->generic.data_2 >> 8) & 0xFF); + pack[7] = (instance->generic.data_2 & 0xFF); + + atomo_encrypt(pack); + uint32_t hi = pack[0] << 24 | pack[1] << 16 | pack[2] << 8 | pack[3]; + uint32_t lo = pack[4] << 24 | pack[5] << 16 | pack[6] << 8 | pack[7]; + instance->generic.data = (uint64_t)hi << 32 | lo; + + instance->generic.data ^= 0xFFFFFFFFFFFFFFFF; + instance->generic.data >>= 4; + instance->generic.data &= 0xFFFFFFFFFFFFFFF; + + return SubGhzProtocolStatusOk == + subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + /** * Generating an upload from data. * @param instance Pointer to a SubGhzProtocolEncoderCameAtomo instance diff --git a/lib/subghz/protocols/came_atomo.h b/lib/subghz/protocols/came_atomo.h index c5e45a68d..8183877b0 100644 --- a/lib/subghz/protocols/came_atomo.h +++ b/lib/subghz/protocols/came_atomo.h @@ -14,6 +14,22 @@ void atomo_decrypt(uint8_t* buff); void atomo_encrypt(uint8_t* buff); +/** + * Key generation from simple data. + * @param context Pointer to a SubGhzProtocolEncoderCameAtomo instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param serial Serial number, 24 bit + * @param cnt Counter value, 16 bit + * @param preset Modulation, SubGhzRadioPreset + * @return true On success + */ +bool subghz_protocol_came_atomo_create_data( + void* context, + FlipperFormat* flipper_format, + uint32_t serial, + uint16_t cnt, + SubGhzRadioPreset* preset); + /** * Allocate SubGhzProtocolEncoderCameAtomo. * @param environment Pointer to a SubGhzEnvironment instance