From 9890dd7ed9761b237412cb5e9c63d4de3ea6118b Mon Sep 17 00:00:00 2001 From: r3df0xx Date: Thu, 17 Mar 2022 00:06:35 +0300 Subject: [PATCH] Nice FloR-S adding save and send Making able to save and emulate rolling codes for Nice FloR-s remotes. --- lib/subghz/protocols/nice_flor_s.c | 96 ++++++++++++++++++++++++++++-- lib/subghz/protocols/nice_flor_s.h | 34 +++++++++++ 2 files changed, 124 insertions(+), 6 deletions(-) diff --git a/lib/subghz/protocols/nice_flor_s.c b/lib/subghz/protocols/nice_flor_s.c index 8a3e26a8a..92b52e02f 100644 --- a/lib/subghz/protocols/nice_flor_s.c +++ b/lib/subghz/protocols/nice_flor_s.c @@ -58,24 +58,108 @@ const SubGhzProtocolDecoder subghz_protocol_nice_flor_s_decoder = { }; const SubGhzProtocolEncoder subghz_protocol_nice_flor_s_encoder = { - .alloc = NULL, - .free = NULL, + .alloc = subghz_protocol_encoder_nice_flor_s_alloc, + .free = subghz_protocol_encoder_nice_flor_s_free, - .deserialize = NULL, - .stop = NULL, - .yield = NULL, + .deserialize = subghz_protocol_encoder_nice_flor_s_deserialize, + .stop = subghz_protocol_encoder_nice_flor_s_stop, + .yield = subghz_protocol_encoder_nice_flor_s_yield, }; const SubGhzProtocol subghz_protocol_nice_flor_s = { .name = SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME, .type = SubGhzProtocolTypeDynamic, .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_868 | SubGhzProtocolFlag_AM | - SubGhzProtocolFlag_Decodable, + SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | + SubGhzProtocolFlag_Send, .decoder = &subghz_protocol_nice_flor_s_decoder, .encoder = &subghz_protocol_nice_flor_s_encoder, }; +void* subghz_protocol_encoder_nice_flor_s_alloc(SubGhzEnvironment* environment) { + SubGhzProtocolEncoderNiceFlorS* instance = malloc(sizeof(SubGhzProtocolEncoderNiceFlorS)); + + instance->base.protocol = &subghz_protocol_nice_flor_s; + instance->generic.protocol_name = instance->base.protocol->name; + + instance->encoder.repeat = 10; + instance->encoder.size_upload = 256; + instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); + instance->encoder.is_runing = false; + return instance; +} + +void subghz_protocol_encoder_nice_flor_s_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderNiceFlorS* instance = context; + free(instance->encoder.upload); + free(instance); +} + +bool subghz_protocol_encoder_nice_flor_s_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderNiceFlorS* instance = context; + bool res = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + FURI_LOG_E(TAG, "Deserialize error"); + break; + } + + subghz_protocol_nice_flor_s_remote_controller( + &instance->generic, instance->nice_flor_s_rainbow_table_file_name); + + //optional parameter parameter + flipper_format_read_uint32( + flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + + subghz_protocol_encoder_nice_flor_s_get_upload(instance, instance->generic.btn); + + if(!flipper_format_rewind(flipper_format)) { + FURI_LOG_E(TAG, "Rewind error"); + break; + } + uint8_t key_data[sizeof(uint64_t)] = {0}; + for(size_t i = 0; i < sizeof(uint64_t); i++) { + key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data >> i * 8) & 0xFF; + } + if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) { + FURI_LOG_E(TAG, "Unable to add Key"); + break; + } + + instance->encoder.is_runing = true; + + res = true; + } while(false); + + return res; +} + +void subghz_protocol_encoder_nice_flor_s_stop(void* context) { + SubGhzProtocolEncoderNiceFlorS* instance = context; + instance->encoder.is_runing = false; +} + +LevelDuration subghz_protocol_encoder_nice_flor_s_yield(void* context) { + SubGhzProtocolEncoderNiceFlorS* instance = context; + + if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) { + instance->encoder.is_runing = false; + return level_duration_reset(); + } + + LevelDuration ret = instance->encoder.upload[instance->encoder.front]; + + if(++instance->encoder.front == instance->encoder.size_upload) { + instance->encoder.repeat--; + instance->encoder.front = 0; + } + + return ret; +} + /** * Read bytes from rainbow table * @param file_name Full path to rainbow table the file diff --git a/lib/subghz/protocols/nice_flor_s.h b/lib/subghz/protocols/nice_flor_s.h index d11264bc6..ee004d158 100644 --- a/lib/subghz/protocols/nice_flor_s.h +++ b/lib/subghz/protocols/nice_flor_s.h @@ -11,6 +11,40 @@ extern const SubGhzProtocolDecoder subghz_protocol_nice_flor_s_decoder; extern const SubGhzProtocolEncoder subghz_protocol_nice_flor_s_encoder; extern const SubGhzProtocol subghz_protocol_nice_flor_s; +/** + * Allocate SubGhzProtocolEncoderNiceFlorS. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderNiceFlorS* pointer to a SubGhzProtocolEncoderNiceFlorS instance + */ +void* subghz_protocol_encoder_nice_flor_s_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderNiceFlorS. + * @param context Pointer to a SubGhzProtocolEncoderNiceFlorS instance + */ +void subghz_protocol_encoder_nice_flor_s_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderNiceFlorS instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return true On success + */ +bool subghz_protocol_encoder_nice_flor_s_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderNiceFlorS instance + */ +void subghz_protocol_encoder_nice_flor_s_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderNiceFlorS instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_nice_flor_s_yield(void* context); + /** * Allocate SubGhzProtocolDecoderNiceFlorS. * @param environment Pointer to a SubGhzEnvironment instance