SubGhz: share the deserialize bodies that only differ by a callback

Two more shared helpers in common.c:
- subghz_protocol_encoder_common_deserialize(ctx, ff, min_count_bit, get_upload)
  covers 11 encoders whose bodies were identical apart from the bit count and
  their get_upload
- subghz_protocol_decoder_common_deserialize_te(ctx, ff, min_count_bit) covers
  the three decoders that read TE back, mirroring the serialize_te helper

The per-protocol get_upload functions now take void* instead of being cast to
the callback type. Calling through an incompatible function pointer type is
formally undefined even though it is harmless on AAPCS, and enabling LTO is on
the roadmap for this same effort - not a combination worth keeping.

Deliberately not converted:

The 35 decoders whose deserialize is just a tail call to
subghz_block_generic_deserialize_check_count_bit compile to 8 bytes each. A
decoder thunk is 6 bytes, so folding them would gain about 70 B - real, but a
poor return for touching 35 files and adding a second hop to a call that is
already a tail call into shared code.

The six encoders that call a per-protocol check_remote_controller before
get_upload would need a fifth argument, which spills to the stack on AAPCS and
costs more per thunk than it saves. They can instead be folded into the helper
above by giving their get_upload a bool return and moving the check inside it,
which also reaches allstar_firefly/elplast and, once the shared stop resets
encoder.front, came_twee/marantec/power_smart/hormann/magellan - about 390 B
across 13 protocols with no new helper. Left as a follow-up because it changes
those functions rather than just moving them.

.text 693,396 -> 692,900 (-496 B), .rodata unchanged, api_symbols.csv untouched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mykhailo ShevchukandClaude Opus 5 committed 2026-08-31 15:05:04 +03:00
1 parent 84aca75eb8
commit 5f4f4cc2b7
16 files changed
+163 -343

No files matched your search

+7 -25
View File
@@ -97,7 +97,8 @@ void* subghz_protocol_encoder_clemsa_alloc(SubGhzEnvironment* environment) {
* @param instance Pointer to a SubGhzProtocolEncoderClemsa instance
* @return true On success
*/
static bool subghz_protocol_encoder_clemsa_get_upload(SubGhzProtocolEncoderClemsa* instance) {
static bool subghz_protocol_encoder_clemsa_get_upload(void* context) {
SubGhzProtocolEncoderClemsa* instance = context;
furi_assert(instance);
size_t index = 0;
size_t size_upload = (instance->generic.data_count_bit * 2);
@@ -145,30 +146,11 @@ static bool subghz_protocol_encoder_clemsa_get_upload(SubGhzProtocolEncoderClems
SubGhzProtocolStatus
subghz_protocol_encoder_clemsa_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolEncoderClemsa* instance = context;
SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
do {
ret = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
subghz_protocol_clemsa_const.min_count_bit_for_found);
if(ret != SubGhzProtocolStatusOk) {
break;
}
// Optional value
flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
if(!subghz_protocol_encoder_clemsa_get_upload(instance)) {
ret = SubGhzProtocolStatusErrorEncoderGetUpload;
break;
}
instance->encoder.is_running = true;
} while(false);
return ret;
return subghz_protocol_encoder_common_deserialize(
context,
flipper_format,
subghz_protocol_clemsa_const.min_count_bit_for_found,
subghz_protocol_encoder_clemsa_get_upload);
}
void* subghz_protocol_decoder_clemsa_alloc(SubGhzEnvironment* environment) {
+45
View File
@@ -128,3 +128,48 @@ void* subghz_protocol_encoder_common_alloc(
instance->common.encoder.is_running = false;
return instance;
}
SubGhzProtocolStatus subghz_protocol_encoder_common_deserialize(
void* context,
FlipperFormat* flipper_format,
uint8_t min_count_bit,
SubGhzProtocolEncoderGetUpload get_upload) {
furi_assert(context);
SubGhzProtocolEncoderCommonGeneric* instance = context;
SubGhzProtocolStatus ret = subghz_block_generic_deserialize_check_count_bit(
&instance->generic, flipper_format, min_count_bit);
if(ret != SubGhzProtocolStatusOk) {
return ret;
}
// Optional value
flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->common.encoder.repeat, 1);
if(!get_upload(instance)) {
return SubGhzProtocolStatusErrorEncoderGetUpload;
}
instance->common.encoder.is_running = true;
return ret;
}
SubGhzProtocolStatus subghz_protocol_decoder_common_deserialize_te(
void* context,
FlipperFormat* flipper_format,
uint8_t min_count_bit) {
furi_assert(context);
SubGhzProtocolDecoderCommonTe* instance = context;
SubGhzProtocolStatus ret = subghz_block_generic_deserialize_check_count_bit(
&instance->common.generic, flipper_format, min_count_bit);
if(ret != SubGhzProtocolStatusOk) {
return ret;
}
if(!flipper_format_rewind(flipper_format)) {
FURI_LOG_E(instance->common.generic.protocol_name, "Rewind error");
return SubGhzProtocolStatusErrorParserOthers;
}
if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) {
FURI_LOG_E(instance->common.generic.protocol_name, "Missing TE");
return SubGhzProtocolStatusErrorParserTe;
}
return ret;
}
+35 -2
View File
@@ -21,8 +21,8 @@ extern "C" {
* Protocols needing extra work in a slot either keep their own copy, or call the shared helper
* and then write their own fields the way princeton does.
*
* subghz_protocol_common_append_data_2 is the exception: a plain helper rather than a slot,
* shared by the serialize slots and the encoder create_data paths.
* Helpers that need a per-protocol constant or callback cannot be slots themselves, so the
* protocol keeps a thunk that supplies it; the rest are pointed at directly.
*/
typedef struct {
@@ -98,6 +98,39 @@ void* subghz_protocol_encoder_common_alloc(
size_t repeat,
size_t size_upload);
/**
* Turns the deserialized generic block into an upload.
* @param instance Pointer to an encoder instance
* @return true On success
*/
typedef bool (*SubGhzProtocolEncoderGetUpload)(void* instance);
/**
* Deserialize an encoder that needs the generic block, an optional Repeat, and an upload.
* @param context Pointer to a SubGhzProtocolEncoderCommonGeneric instance
* @param flipper_format Pointer to a FlipperFormat instance
* @param min_count_bit Minimum number of bits the protocol needs
* @param get_upload Per-protocol upload generator
* @return status
*/
SubGhzProtocolStatus subghz_protocol_encoder_common_deserialize(
void* context,
FlipperFormat* flipper_format,
uint8_t min_count_bit,
SubGhzProtocolEncoderGetUpload get_upload);
/**
* Deserialize decoder data and read the TE value back.
* @param context Pointer to a SubGhzProtocolDecoderCommonTe instance
* @param flipper_format Pointer to a FlipperFormat instance
* @param min_count_bit Minimum number of bits the protocol needs
* @return status
*/
SubGhzProtocolStatus subghz_protocol_decoder_common_deserialize_te(
void* context,
FlipperFormat* flipper_format,
uint8_t min_count_bit);
/**
* Free an encoder instance along with its upload buffer.
* @param context Pointer to an encoder instance
+7 -24
View File
@@ -89,7 +89,8 @@ void* subghz_protocol_encoder_doitrand_alloc(SubGhzEnvironment* environment) {
* @param instance Pointer to a SubGhzProtocolEncoderDoitrand instance
* @return true On success
*/
static bool subghz_protocol_encoder_doitrand_get_upload(SubGhzProtocolEncoderDoitrand* instance) {
static bool subghz_protocol_encoder_doitrand_get_upload(void* context) {
SubGhzProtocolEncoderDoitrand* instance = context;
furi_assert(instance);
size_t index = 0;
size_t size_upload = (instance->generic.data_count_bit * 2) + 2;
@@ -126,29 +127,11 @@ static bool subghz_protocol_encoder_doitrand_get_upload(SubGhzProtocolEncoderDoi
SubGhzProtocolStatus
subghz_protocol_encoder_doitrand_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolEncoderDoitrand* instance = context;
SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
do {
ret = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
subghz_protocol_doitrand_const.min_count_bit_for_found);
if(ret != SubGhzProtocolStatusOk) {
break;
}
// Optional value
flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
if(!subghz_protocol_encoder_doitrand_get_upload(instance)) {
ret = SubGhzProtocolStatusErrorEncoderGetUpload;
break;
}
instance->encoder.is_running = true;
} while(false);
return ret;
return subghz_protocol_encoder_common_deserialize(
context,
flipper_format,
subghz_protocol_doitrand_const.min_count_bit_for_found,
subghz_protocol_encoder_doitrand_get_upload);
}
void* subghz_protocol_decoder_doitrand_alloc(SubGhzEnvironment* environment) {
+7 -24
View File
@@ -84,7 +84,8 @@ void* subghz_protocol_encoder_dooya_alloc(SubGhzEnvironment* environment) {
* @param instance Pointer to a SubGhzProtocolEncoderDooya instance
* @return true On success
*/
static bool subghz_protocol_encoder_dooya_get_upload(SubGhzProtocolEncoderDooya* instance) {
static bool subghz_protocol_encoder_dooya_get_upload(void* context) {
SubGhzProtocolEncoderDooya* instance = context;
furi_assert(instance);
size_t index = 0;
@@ -136,29 +137,11 @@ static bool subghz_protocol_encoder_dooya_get_upload(SubGhzProtocolEncoderDooya*
SubGhzProtocolStatus
subghz_protocol_encoder_dooya_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolEncoderDooya* instance = context;
SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
do {
ret = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
subghz_protocol_dooya_const.min_count_bit_for_found);
if(ret != SubGhzProtocolStatusOk) {
break;
}
// Optional value
flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
if(!subghz_protocol_encoder_dooya_get_upload(instance)) {
ret = SubGhzProtocolStatusErrorEncoderGetUpload;
break;
}
instance->encoder.is_running = true;
} while(false);
return ret;
return subghz_protocol_encoder_common_deserialize(
context,
flipper_format,
subghz_protocol_dooya_const.min_count_bit_for_found,
subghz_protocol_encoder_dooya_get_upload);
}
void* subghz_protocol_decoder_dooya_alloc(SubGhzEnvironment* environment) {
+7 -24
View File
@@ -85,7 +85,8 @@ void* subghz_protocol_encoder_gate_tx_alloc(SubGhzEnvironment* environment) {
* @param instance Pointer to a SubGhzProtocolEncoderGateTx instance
* @return true On success
*/
static bool subghz_protocol_encoder_gate_tx_get_upload(SubGhzProtocolEncoderGateTx* instance) {
static bool subghz_protocol_encoder_gate_tx_get_upload(void* context) {
SubGhzProtocolEncoderGateTx* instance = context;
furi_assert(instance);
size_t index = 0;
size_t size_upload = (instance->generic.data_count_bit * 2) + 2;
@@ -122,29 +123,11 @@ static bool subghz_protocol_encoder_gate_tx_get_upload(SubGhzProtocolEncoderGate
SubGhzProtocolStatus
subghz_protocol_encoder_gate_tx_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolEncoderGateTx* instance = context;
SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
do {
ret = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
subghz_protocol_gate_tx_const.min_count_bit_for_found);
if(ret != SubGhzProtocolStatusOk) {
break;
}
// Optional value
flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
if(!subghz_protocol_encoder_gate_tx_get_upload(instance)) {
ret = SubGhzProtocolStatusErrorEncoderGetUpload;
break;
}
instance->encoder.is_running = true;
} while(false);
return ret;
return subghz_protocol_encoder_common_deserialize(
context,
flipper_format,
subghz_protocol_gate_tx_const.min_count_bit_for_found,
subghz_protocol_encoder_gate_tx_get_upload);
}
void* subghz_protocol_decoder_gate_tx_alloc(SubGhzEnvironment* environment) {
+7 -24
View File
@@ -93,7 +93,8 @@ void* subghz_protocol_encoder_holtek_alloc(SubGhzEnvironment* environment) {
* @param instance Pointer to a SubGhzProtocolEncoderHoltek instance
* @return true On success
*/
static bool subghz_protocol_encoder_holtek_get_upload(SubGhzProtocolEncoderHoltek* instance) {
static bool subghz_protocol_encoder_holtek_get_upload(void* context) {
SubGhzProtocolEncoderHoltek* instance = context;
furi_assert(instance);
size_t index = 0;
@@ -132,29 +133,11 @@ static bool subghz_protocol_encoder_holtek_get_upload(SubGhzProtocolEncoderHolte
SubGhzProtocolStatus
subghz_protocol_encoder_holtek_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolEncoderHoltek* instance = context;
SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
do {
ret = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
subghz_protocol_holtek_const.min_count_bit_for_found);
if(ret != SubGhzProtocolStatusOk) {
break;
}
// Optional value
flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
if(!subghz_protocol_encoder_holtek_get_upload(instance)) {
ret = SubGhzProtocolStatusErrorEncoderGetUpload;
break;
}
instance->encoder.is_running = true;
} while(false);
return ret;
return subghz_protocol_encoder_common_deserialize(
context,
flipper_format,
subghz_protocol_holtek_const.min_count_bit_for_found,
subghz_protocol_encoder_holtek_get_upload);
}
void* subghz_protocol_decoder_holtek_alloc(SubGhzEnvironment* environment) {
+2 -23
View File
@@ -275,29 +275,8 @@ static void subghz_protocol_holtek_th12x_check_remote_controller(SubGhzBlockGene
SubGhzProtocolStatus
subghz_protocol_decoder_holtek_th12x_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolDecoderHoltek_HT12X* instance = context;
SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
do {
ret = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
subghz_protocol_holtek_th12x_const.min_count_bit_for_found);
if(ret != SubGhzProtocolStatusOk) {
break;
}
if(!flipper_format_rewind(flipper_format)) {
FURI_LOG_E(TAG, "Rewind error");
ret = SubGhzProtocolStatusErrorParserOthers;
break;
}
if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) {
FURI_LOG_E(TAG, "Missing TE");
ret = SubGhzProtocolStatusErrorParserTe;
break;
}
} while(false);
return ret;
return subghz_protocol_decoder_common_deserialize_te(
context, flipper_format, subghz_protocol_holtek_th12x_const.min_count_bit_for_found);
}
static void subghz_protocol_holtek_th12x_event_serialize(uint8_t event, FuriString* output) {
+7 -25
View File
@@ -94,8 +94,8 @@ void* subghz_protocol_encoder_honeywell_wdb_alloc(SubGhzEnvironment* environment
* @param instance Pointer to a SubGhzProtocolEncoderHoneywell_WDB instance
* @return true On success
*/
static bool subghz_protocol_encoder_honeywell_wdb_get_upload(
SubGhzProtocolEncoderHoneywell_WDB* instance) {
static bool subghz_protocol_encoder_honeywell_wdb_get_upload(void* context) {
SubGhzProtocolEncoderHoneywell_WDB* instance = context;
furi_assert(instance);
size_t index = 0;
size_t size_upload = (instance->generic.data_count_bit * 2) + 2;
@@ -132,29 +132,11 @@ static bool subghz_protocol_encoder_honeywell_wdb_get_upload(
SubGhzProtocolStatus subghz_protocol_encoder_honeywell_wdb_deserialize(
void* context,
FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolEncoderHoneywell_WDB* instance = context;
SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
do {
ret = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
subghz_protocol_honeywell_wdb_const.min_count_bit_for_found);
if(ret != SubGhzProtocolStatusOk) {
break;
}
// Optional value
flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
if(!subghz_protocol_encoder_honeywell_wdb_get_upload(instance)) {
ret = SubGhzProtocolStatusErrorEncoderGetUpload;
break;
}
instance->encoder.is_running = true;
} while(false);
return ret;
return subghz_protocol_encoder_common_deserialize(
context,
flipper_format,
subghz_protocol_honeywell_wdb_const.min_count_bit_for_found,
subghz_protocol_encoder_honeywell_wdb_get_upload);
}
void* subghz_protocol_decoder_honeywell_wdb_alloc(SubGhzEnvironment* environment) {
+2 -24
View File
@@ -274,30 +274,8 @@ void subghz_protocol_decoder_legrand_feed(void* context, bool level, uint32_t du
SubGhzProtocolStatus
subghz_protocol_decoder_legrand_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolDecoderLegrand* instance = context;
SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
do {
ret = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
subghz_protocol_legrand_const.min_count_bit_for_found);
if(ret != SubGhzProtocolStatusOk) {
break;
}
if(!flipper_format_rewind(flipper_format)) {
FURI_LOG_E(TAG, "Rewind error");
ret = SubGhzProtocolStatusErrorParserOthers;
break;
}
if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) {
FURI_LOG_E(TAG, "Missing TE");
ret = SubGhzProtocolStatusErrorParserTe;
break;
}
} while(false);
return ret;
return subghz_protocol_decoder_common_deserialize_te(
context, flipper_format, subghz_protocol_legrand_const.min_count_bit_for_found);
}
void subghz_protocol_decoder_legrand_get_string(void* context, FuriString* output) {
+7 -24
View File
@@ -91,7 +91,8 @@ void* subghz_protocol_encoder_linear_alloc(SubGhzEnvironment* environment) {
* @param instance Pointer to a SubGhzProtocolEncoderLinear instance
* @return true On success
*/
static bool subghz_protocol_encoder_linear_get_upload(SubGhzProtocolEncoderLinear* instance) {
static bool subghz_protocol_encoder_linear_get_upload(void* context) {
SubGhzProtocolEncoderLinear* instance = context;
furi_assert(instance);
size_t index = 0;
size_t size_upload = (instance->generic.data_count_bit * 2);
@@ -140,29 +141,11 @@ static bool subghz_protocol_encoder_linear_get_upload(SubGhzProtocolEncoderLinea
SubGhzProtocolStatus
subghz_protocol_encoder_linear_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolEncoderLinear* instance = context;
SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
do {
ret = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
subghz_protocol_linear_const.min_count_bit_for_found);
if(ret != SubGhzProtocolStatusOk) {
break;
}
// Optional value
flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
if(!subghz_protocol_encoder_linear_get_upload(instance)) {
ret = SubGhzProtocolStatusErrorEncoderGetUpload;
break;
}
instance->encoder.is_running = true;
} while(false);
return ret;
return subghz_protocol_encoder_common_deserialize(
context,
flipper_format,
subghz_protocol_linear_const.min_count_bit_for_found,
subghz_protocol_encoder_linear_get_upload);
}
void* subghz_protocol_decoder_linear_alloc(SubGhzEnvironment* environment) {
+7 -25
View File
@@ -89,8 +89,8 @@ void* subghz_protocol_encoder_linear_delta3_alloc(SubGhzEnvironment* environment
* @param instance Pointer to a SubGhzProtocolEncoderLinearDelta3 instance
* @return true On success
*/
static bool
subghz_protocol_encoder_linear_delta3_get_upload(SubGhzProtocolEncoderLinearDelta3* instance) {
static bool subghz_protocol_encoder_linear_delta3_get_upload(void* context) {
SubGhzProtocolEncoderLinearDelta3* instance = context;
furi_assert(instance);
size_t index = 0;
size_t size_upload = (instance->generic.data_count_bit * 2);
@@ -140,29 +140,11 @@ static bool
SubGhzProtocolStatus subghz_protocol_encoder_linear_delta3_deserialize(
void* context,
FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolEncoderLinearDelta3* instance = context;
SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
do {
ret = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
subghz_protocol_linear_delta3_const.min_count_bit_for_found);
if(ret != SubGhzProtocolStatusOk) {
break;
}
// Optional value
flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
if(!subghz_protocol_encoder_linear_delta3_get_upload(instance)) {
ret = SubGhzProtocolStatusErrorEncoderGetUpload;
break;
}
instance->encoder.is_running = true;
} while(false);
return ret;
return subghz_protocol_encoder_common_deserialize(
context,
flipper_format,
subghz_protocol_linear_delta3_const.min_count_bit_for_found,
subghz_protocol_encoder_linear_delta3_get_upload);
}
void* subghz_protocol_decoder_linear_delta3_alloc(SubGhzEnvironment* environment) {
+7 -26
View File
@@ -96,8 +96,8 @@ void* subghz_protocol_encoder_mastercode_alloc(SubGhzEnvironment* environment) {
* @param instance Pointer to a SubGhzProtocolEncoderMastercode instance
* @return true On success
*/
static bool
subghz_protocol_encoder_mastercode_get_upload(SubGhzProtocolEncoderMastercode* instance) {
static bool subghz_protocol_encoder_mastercode_get_upload(void* context) {
SubGhzProtocolEncoderMastercode* instance = context;
furi_assert(instance);
size_t index = 0;
size_t size_upload = (instance->generic.data_count_bit * 2);
@@ -145,30 +145,11 @@ static bool
SubGhzProtocolStatus
subghz_protocol_encoder_mastercode_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolEncoderMastercode* instance = context;
SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
do {
ret = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
subghz_protocol_mastercode_const.min_count_bit_for_found);
if(ret != SubGhzProtocolStatusOk) {
break;
}
// Optional value
flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
if(!subghz_protocol_encoder_mastercode_get_upload(instance)) {
ret = SubGhzProtocolStatusErrorEncoderGetUpload;
break;
}
instance->encoder.is_running = true;
} while(false);
return ret;
return subghz_protocol_encoder_common_deserialize(
context,
flipper_format,
subghz_protocol_mastercode_const.min_count_bit_for_found,
subghz_protocol_encoder_mastercode_get_upload);
}
void* subghz_protocol_decoder_mastercode_alloc(SubGhzEnvironment* environment) {
+7 -24
View File
@@ -94,7 +94,8 @@ void* subghz_protocol_encoder_megacode_alloc(SubGhzEnvironment* environment) {
* @param instance Pointer to a SubGhzProtocolEncoderMegaCode instance
* @return true On success
*/
static bool subghz_protocol_encoder_megacode_get_upload(SubGhzProtocolEncoderMegaCode* instance) {
static bool subghz_protocol_encoder_megacode_get_upload(void* context) {
SubGhzProtocolEncoderMegaCode* instance = context;
furi_assert(instance);
uint8_t last_bit = 0;
size_t size_upload = (instance->generic.data_count_bit * 2);
@@ -165,29 +166,11 @@ static bool subghz_protocol_encoder_megacode_get_upload(SubGhzProtocolEncoderMeg
SubGhzProtocolStatus
subghz_protocol_encoder_megacode_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolEncoderMegaCode* instance = context;
SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
do {
ret = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
subghz_protocol_megacode_const.min_count_bit_for_found);
if(ret != SubGhzProtocolStatusOk) {
break;
}
// Optional value
flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
if(!subghz_protocol_encoder_megacode_get_upload(instance)) {
ret = SubGhzProtocolStatusErrorEncoderGetUpload;
break;
}
instance->encoder.is_running = true;
} while(false);
return ret;
return subghz_protocol_encoder_common_deserialize(
context,
flipper_format,
subghz_protocol_megacode_const.min_count_bit_for_found,
subghz_protocol_encoder_megacode_get_upload);
}
void* subghz_protocol_decoder_megacode_alloc(SubGhzEnvironment* environment) {
+7 -25
View File
@@ -83,8 +83,8 @@ void* subghz_protocol_encoder_nero_sketch_alloc(SubGhzEnvironment* environment)
* @param instance Pointer to a SubGhzProtocolEncoderNeroSketch instance
* @return true On success
*/
static bool
subghz_protocol_encoder_nero_sketch_get_upload(SubGhzProtocolEncoderNeroSketch* instance) {
static bool subghz_protocol_encoder_nero_sketch_get_upload(void* context) {
SubGhzProtocolEncoderNeroSketch* instance = context;
furi_assert(instance);
size_t index = 0;
@@ -138,29 +138,11 @@ static bool
SubGhzProtocolStatus
subghz_protocol_encoder_nero_sketch_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolEncoderNeroSketch* instance = context;
SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
do {
ret = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
subghz_protocol_nero_sketch_const.min_count_bit_for_found);
if(ret != SubGhzProtocolStatusOk) {
break;
}
// Optional value
flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
if(!subghz_protocol_encoder_nero_sketch_get_upload(instance)) {
ret = SubGhzProtocolStatusErrorEncoderGetUpload;
break;
}
instance->encoder.is_running = true;
} while(false);
return ret;
return subghz_protocol_encoder_common_deserialize(
context,
flipper_format,
subghz_protocol_nero_sketch_const.min_count_bit_for_found,
subghz_protocol_encoder_nero_sketch_get_upload);
}
void* subghz_protocol_decoder_nero_sketch_alloc(SubGhzEnvironment* environment) {
+2 -24
View File
@@ -267,30 +267,8 @@ void subghz_protocol_decoder_smc5326_feed(void* context, bool level, uint32_t du
SubGhzProtocolStatus
subghz_protocol_decoder_smc5326_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolDecoderSMC5326* instance = context;
SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
do {
ret = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
subghz_protocol_smc5326_const.min_count_bit_for_found);
if(ret != SubGhzProtocolStatusOk) {
break;
}
if(!flipper_format_rewind(flipper_format)) {
FURI_LOG_E(TAG, "Rewind error");
ret = SubGhzProtocolStatusErrorParserOthers;
break;
}
if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) {
FURI_LOG_E(TAG, "Missing TE");
ret = SubGhzProtocolStatusErrorParserTe;
break;
}
} while(false);
return ret;
return subghz_protocol_decoder_common_deserialize_te(
context, flipper_format, subghz_protocol_smc5326_const.min_count_bit_for_found);
}
static void subghz_protocol_smc5326_get_event_serialize(uint8_t event, FuriString* output) {