Sfoglia il codice sorgente

[FL-3106] SubGhz: better and more verbose error handling in protocols, stricter CAME validation (#2443)

* SubGhz: add error protocol
* WS: add error protocol
* SubGhz: error processing
* SubGhz: more stringent CAME protocol restrictions
* SubGhz: fix header duration CAME protocol
* SubGhz: delete comments
* SubGhz: sync SubGhzProtocolStatus with FuriStatus
* SubGhz: update documentation and bump api_version

Co-authored-by: あく <alleteam@gmail.com>
Skorpionm 2 anni fa
parent
commit
72ca6b25e9
100 ha cambiato i file con 1090 aggiunte e 1179 eliminazioni
  1. 1 0
      applications/main/subghz/helpers/subghz_types.h
  2. 2 1
      applications/main/subghz/scenes/subghz_scene_receiver_info.c
  3. 3 2
      applications/main/subghz/scenes/subghz_scene_set_type.c
  4. 18 20
      applications/main/subghz/scenes/subghz_scene_transmitter.c
  5. 17 4
      applications/main/subghz/subghz_i.c
  6. 1 1
      applications/plugins/weather_station/helpers/weather_station_types.h
  7. 7 15
      applications/plugins/weather_station/protocols/acurite_592txr.c
  8. 5 4
      applications/plugins/weather_station/protocols/acurite_592txr.h
  9. 7 15
      applications/plugins/weather_station/protocols/acurite_606tx.c
  10. 5 4
      applications/plugins/weather_station/protocols/acurite_606tx.h
  11. 7 15
      applications/plugins/weather_station/protocols/acurite_609txc.c
  12. 5 4
      applications/plugins/weather_station/protocols/acurite_609txc.h
  13. 7 15
      applications/plugins/weather_station/protocols/ambient_weather.c
  14. 5 4
      applications/plugins/weather_station/protocols/ambient_weather.h
  15. 5 15
      applications/plugins/weather_station/protocols/auriol_hg0601a.c
  16. 5 4
      applications/plugins/weather_station/protocols/auriol_hg0601a.h
  17. 5 15
      applications/plugins/weather_station/protocols/gt_wt_02.c
  18. 5 4
      applications/plugins/weather_station/protocols/gt_wt_02.h
  19. 5 15
      applications/plugins/weather_station/protocols/gt_wt_03.c
  20. 5 4
      applications/plugins/weather_station/protocols/gt_wt_03.h
  21. 5 15
      applications/plugins/weather_station/protocols/infactory.c
  22. 5 4
      applications/plugins/weather_station/protocols/infactory.h
  23. 5 15
      applications/plugins/weather_station/protocols/lacrosse_tx.c
  24. 5 4
      applications/plugins/weather_station/protocols/lacrosse_tx.h
  25. 6 15
      applications/plugins/weather_station/protocols/lacrosse_tx141thbv2.c
  26. 4 4
      applications/plugins/weather_station/protocols/lacrosse_tx141thbv2.h
  27. 5 15
      applications/plugins/weather_station/protocols/nexus_th.c
  28. 5 4
      applications/plugins/weather_station/protocols/nexus_th.h
  29. 15 9
      applications/plugins/weather_station/protocols/oregon2.c
  30. 5 15
      applications/plugins/weather_station/protocols/oregon_v1.c
  31. 5 4
      applications/plugins/weather_station/protocols/oregon_v1.h
  32. 7 15
      applications/plugins/weather_station/protocols/thermopro_tx4.c
  33. 5 4
      applications/plugins/weather_station/protocols/thermopro_tx4.h
  34. 5 14
      applications/plugins/weather_station/protocols/tx_8300.c
  35. 5 4
      applications/plugins/weather_station/protocols/tx_8300.h
  36. 51 6
      applications/plugins/weather_station/protocols/ws_generic.c
  37. 17 4
      applications/plugins/weather_station/protocols/ws_generic.h
  38. 1 1
      firmware/targets/f18/api_symbols.csv
  39. 9 8
      firmware/targets/f7/api_symbols.csv
  40. 37 6
      lib/subghz/blocks/generic.c
  41. 17 4
      lib/subghz/blocks/generic.h
  42. 15 15
      lib/subghz/protocols/alutech_at_4n.c
  43. 5 6
      lib/subghz/protocols/alutech_at_4n.h
  44. 17 26
      lib/subghz/protocols/ansonic.c
  45. 5 3
      lib/subghz/protocols/ansonic.h
  46. 4 4
      lib/subghz/protocols/base.c
  47. 4 4
      lib/subghz/protocols/base.h
  48. 18 27
      lib/subghz/protocols/bett.c
  49. 8 6
      lib/subghz/protocols/bett.h
  50. 38 10
      lib/subghz/protocols/bin_raw.c
  51. 8 6
      lib/subghz/protocols/bin_raw.h
  52. 47 22
      lib/subghz/protocols/came.c
  53. 8 6
      lib/subghz/protocols/came.h
  54. 7 15
      lib/subghz/protocols/came_atomo.c
  55. 5 4
      lib/subghz/protocols/came_atomo.h
  56. 15 26
      lib/subghz/protocols/came_twee.c
  57. 8 6
      lib/subghz/protocols/came_twee.h
  58. 18 12
      lib/subghz/protocols/chamberlain_code.c
  59. 8 6
      lib/subghz/protocols/chamberlain_code.h
  60. 18 27
      lib/subghz/protocols/clemsa.c
  61. 8 6
      lib/subghz/protocols/clemsa.h
  62. 20 28
      lib/subghz/protocols/doitrand.c
  63. 8 6
      lib/subghz/protocols/doitrand.h
  64. 18 28
      lib/subghz/protocols/dooya.c
  65. 8 6
      lib/subghz/protocols/dooya.h
  66. 7 15
      lib/subghz/protocols/faac_slh.c
  67. 5 4
      lib/subghz/protocols/faac_slh.h
  68. 18 28
      lib/subghz/protocols/gate_tx.c
  69. 8 6
      lib/subghz/protocols/gate_tx.h
  70. 18 28
      lib/subghz/protocols/holtek.c
  71. 8 6
      lib/subghz/protocols/holtek.h
  72. 32 27
      lib/subghz/protocols/holtek_ht12x.c
  73. 8 6
      lib/subghz/protocols/holtek_ht12x.h
  74. 18 28
      lib/subghz/protocols/honeywell_wdb.c
  75. 8 10
      lib/subghz/protocols/honeywell_wdb.h
  76. 18 28
      lib/subghz/protocols/hormann.c
  77. 8 6
      lib/subghz/protocols/hormann.h
  78. 5 14
      lib/subghz/protocols/ido.c
  79. 5 4
      lib/subghz/protocols/ido.h
  80. 16 13
      lib/subghz/protocols/intertechno_v3.c
  81. 6 6
      lib/subghz/protocols/intertechno_v3.h
  82. 27 35
      lib/subghz/protocols/keeloq.c
  83. 8 6
      lib/subghz/protocols/keeloq.h
  84. 5 14
      lib/subghz/protocols/kia.c
  85. 5 4
      lib/subghz/protocols/kia.h
  86. 16 16
      lib/subghz/protocols/kinggates_stylo_4k.c
  87. 4 4
      lib/subghz/protocols/kinggates_stylo_4k.h
  88. 18 28
      lib/subghz/protocols/linear.c
  89. 8 6
      lib/subghz/protocols/linear.h
  90. 18 28
      lib/subghz/protocols/linear_delta3.c
  91. 8 10
      lib/subghz/protocols/linear_delta3.h
  92. 20 28
      lib/subghz/protocols/magellan.c
  93. 8 6
      lib/subghz/protocols/magellan.h
  94. 16 27
      lib/subghz/protocols/marantec.c
  95. 8 6
      lib/subghz/protocols/marantec.h
  96. 20 28
      lib/subghz/protocols/megacode.c
  97. 8 6
      lib/subghz/protocols/megacode.h
  98. 20 28
      lib/subghz/protocols/nero_radio.c
  99. 8 6
      lib/subghz/protocols/nero_radio.h
  100. 20 28
      lib/subghz/protocols/nero_sketch.c

+ 1 - 0
applications/main/subghz/helpers/subghz_types.h

@@ -53,6 +53,7 @@ typedef enum {
     SubGhzLoadKeyStateUnknown,
     SubGhzLoadKeyStateUnknown,
     SubGhzLoadKeyStateOK,
     SubGhzLoadKeyStateOK,
     SubGhzLoadKeyStateParseErr,
     SubGhzLoadKeyStateParseErr,
+    SubGhzLoadKeyStateProtocolDescriptionErr,
 } SubGhzLoadKeyState;
 } SubGhzLoadKeyState;
 
 
 /** SubGhzLock */
 /** SubGhzLock */

+ 2 - 1
applications/main/subghz/scenes/subghz_scene_receiver_info.c

@@ -22,7 +22,9 @@ static bool subghz_scene_receiver_info_update_parser(void* context) {
     subghz->txrx->decoder_result = subghz_receiver_search_decoder_base_by_name(
     subghz->txrx->decoder_result = subghz_receiver_search_decoder_base_by_name(
         subghz->txrx->receiver,
         subghz->txrx->receiver,
         subghz_history_get_protocol_name(subghz->txrx->history, subghz->txrx->idx_menu_chosen));
         subghz_history_get_protocol_name(subghz->txrx->history, subghz->txrx->idx_menu_chosen));
+
     if(subghz->txrx->decoder_result) {
     if(subghz->txrx->decoder_result) {
+        //todo we are trying to deserialize without checking for errors, since it is assumed that we just received this chignal
         subghz_protocol_decoder_base_deserialize(
         subghz_protocol_decoder_base_deserialize(
             subghz->txrx->decoder_result,
             subghz->txrx->decoder_result,
             subghz_history_get_raw_data(subghz->txrx->history, subghz->txrx->idx_menu_chosen));
             subghz_history_get_raw_data(subghz->txrx->history, subghz->txrx->idx_menu_chosen));
@@ -128,7 +130,6 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event)
                        subghz,
                        subghz,
                        subghz_history_get_raw_data(
                        subghz_history_get_raw_data(
                            subghz->txrx->history, subghz->txrx->idx_menu_chosen))) {
                            subghz->txrx->history, subghz->txrx->idx_menu_chosen))) {
-                    scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx);
                     if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
                     if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
                         subghz_tx_stop(subghz);
                         subghz_tx_stop(subghz);
                     }
                     }

+ 3 - 2
applications/main/subghz/scenes/subghz_scene_set_type.c

@@ -34,8 +34,9 @@ bool subghz_scene_set_type_submenu_gen_data_protocol(
     do {
     do {
         Stream* fff_data_stream = flipper_format_get_raw_stream(subghz->txrx->fff_data);
         Stream* fff_data_stream = flipper_format_get_raw_stream(subghz->txrx->fff_data);
         stream_clean(fff_data_stream);
         stream_clean(fff_data_stream);
-        if(!subghz_protocol_decoder_base_serialize(
-               subghz->txrx->decoder_result, subghz->txrx->fff_data, subghz->txrx->preset)) {
+        if(subghz_protocol_decoder_base_serialize(
+               subghz->txrx->decoder_result, subghz->txrx->fff_data, subghz->txrx->preset) !=
+           SubGhzProtocolStatusOk) {
             FURI_LOG_E(TAG, "Unable to serialize");
             FURI_LOG_E(TAG, "Unable to serialize");
             break;
             break;
         }
         }

+ 18 - 20
applications/main/subghz/scenes/subghz_scene_transmitter.c

@@ -9,9 +9,8 @@ void subghz_scene_transmitter_callback(SubGhzCustomEvent event, void* context) {
 }
 }
 
 
 bool subghz_scene_transmitter_update_data_show(void* context) {
 bool subghz_scene_transmitter_update_data_show(void* context) {
-    //ToDo Fix
     SubGhz* subghz = context;
     SubGhz* subghz = context;
-
+    bool ret = false;
     if(subghz->txrx->decoder_result) {
     if(subghz->txrx->decoder_result) {
         FuriString* key_str;
         FuriString* key_str;
         FuriString* frequency_str;
         FuriString* frequency_str;
@@ -22,30 +21,29 @@ bool subghz_scene_transmitter_update_data_show(void* context) {
         modulation_str = furi_string_alloc();
         modulation_str = furi_string_alloc();
         uint8_t show_button = 0;
         uint8_t show_button = 0;
 
 
-        subghz_protocol_decoder_base_deserialize(
-            subghz->txrx->decoder_result, subghz->txrx->fff_data);
-        subghz_protocol_decoder_base_get_string(subghz->txrx->decoder_result, key_str);
-
-        if((subghz->txrx->decoder_result->protocol->flag & SubGhzProtocolFlag_Send) ==
-           SubGhzProtocolFlag_Send) {
-            show_button = 1;
-        }
+        if(subghz_protocol_decoder_base_deserialize(
+               subghz->txrx->decoder_result, subghz->txrx->fff_data) == SubGhzProtocolStatusOk) {
+            subghz_protocol_decoder_base_get_string(subghz->txrx->decoder_result, key_str);
 
 
-        subghz_get_frequency_modulation(subghz, frequency_str, modulation_str);
-        subghz_view_transmitter_add_data_to_show(
-            subghz->subghz_transmitter,
-            furi_string_get_cstr(key_str),
-            furi_string_get_cstr(frequency_str),
-            furi_string_get_cstr(modulation_str),
-            show_button);
+            if((subghz->txrx->decoder_result->protocol->flag & SubGhzProtocolFlag_Send) ==
+               SubGhzProtocolFlag_Send) {
+                show_button = 1;
+            }
 
 
+            subghz_get_frequency_modulation(subghz, frequency_str, modulation_str);
+            subghz_view_transmitter_add_data_to_show(
+                subghz->subghz_transmitter,
+                furi_string_get_cstr(key_str),
+                furi_string_get_cstr(frequency_str),
+                furi_string_get_cstr(modulation_str),
+                show_button);
+            ret = true;
+        }
         furi_string_free(frequency_str);
         furi_string_free(frequency_str);
         furi_string_free(modulation_str);
         furi_string_free(modulation_str);
         furi_string_free(key_str);
         furi_string_free(key_str);
-
-        return true;
     }
     }
-    return false;
+    return ret;
 }
 }
 
 
 void subghz_scene_transmitter_on_enter(void* context) {
 void subghz_scene_transmitter_on_enter(void* context) {

+ 17 - 4
applications/main/subghz/subghz_i.c

@@ -153,7 +153,6 @@ bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format) {
             FURI_LOG_E(TAG, "Missing Protocol");
             FURI_LOG_E(TAG, "Missing Protocol");
             break;
             break;
         }
         }
-        //ToDo FIX
         if(!flipper_format_insert_or_update_uint32(flipper_format, "Repeat", &repeat, 1)) {
         if(!flipper_format_insert_or_update_uint32(flipper_format, "Repeat", &repeat, 1)) {
             FURI_LOG_E(TAG, "Unable Repeat");
             FURI_LOG_E(TAG, "Unable Repeat");
             break;
             break;
@@ -163,7 +162,8 @@ bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format) {
             subghz->txrx->environment, furi_string_get_cstr(temp_str));
             subghz->txrx->environment, furi_string_get_cstr(temp_str));
 
 
         if(subghz->txrx->transmitter) {
         if(subghz->txrx->transmitter) {
-            if(subghz_transmitter_deserialize(subghz->txrx->transmitter, flipper_format)) {
+            if(subghz_transmitter_deserialize(subghz->txrx->transmitter, flipper_format) ==
+               SubGhzProtocolStatusOk) {
                 if(strcmp(furi_string_get_cstr(subghz->txrx->preset->name), "") != 0) {
                 if(strcmp(furi_string_get_cstr(subghz->txrx->preset->name), "") != 0) {
                     subghz_begin(
                     subghz_begin(
                         subghz,
                         subghz,
@@ -186,7 +186,12 @@ bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format) {
                     //Start TX
                     //Start TX
                     furi_hal_subghz_start_async_tx(
                     furi_hal_subghz_start_async_tx(
                         subghz_transmitter_yield, subghz->txrx->transmitter);
                         subghz_transmitter_yield, subghz->txrx->transmitter);
+                } else {
+                    subghz_dialog_message_show_only_rx(subghz);
                 }
                 }
+            } else {
+                dialog_message_show_storage_error(
+                    subghz->dialogs, "Error in protocol\nparameters\ndescription");
             }
             }
         }
         }
         if(!ret) {
         if(!ret) {
@@ -333,8 +338,10 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) {
         subghz->txrx->decoder_result = subghz_receiver_search_decoder_base_by_name(
         subghz->txrx->decoder_result = subghz_receiver_search_decoder_base_by_name(
             subghz->txrx->receiver, furi_string_get_cstr(temp_str));
             subghz->txrx->receiver, furi_string_get_cstr(temp_str));
         if(subghz->txrx->decoder_result) {
         if(subghz->txrx->decoder_result) {
-            if(!subghz_protocol_decoder_base_deserialize(
-                   subghz->txrx->decoder_result, subghz->txrx->fff_data)) {
+            SubGhzProtocolStatus status = subghz_protocol_decoder_base_deserialize(
+                subghz->txrx->decoder_result, subghz->txrx->fff_data);
+            if(status != SubGhzProtocolStatusOk) {
+                load_key_state = SubGhzLoadKeyStateProtocolDescriptionErr;
                 break;
                 break;
             }
             }
         } else {
         } else {
@@ -355,6 +362,12 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) {
             dialog_message_show_storage_error(subghz->dialogs, "Cannot parse\nfile");
             dialog_message_show_storage_error(subghz->dialogs, "Cannot parse\nfile");
         }
         }
         return false;
         return false;
+    case SubGhzLoadKeyStateProtocolDescriptionErr:
+        if(show_dialog) {
+            dialog_message_show_storage_error(
+                subghz->dialogs, "Error in protocol\nparameters\ndescription");
+        }
+        return false;
 
 
     case SubGhzLoadKeyStateOK:
     case SubGhzLoadKeyStateOK:
         return true;
         return true;

+ 1 - 1
applications/plugins/weather_station/helpers/weather_station_types.h

@@ -3,7 +3,7 @@
 #include <furi.h>
 #include <furi.h>
 #include <furi_hal.h>
 #include <furi_hal.h>
 
 
-#define WS_VERSION_APP "0.7"
+#define WS_VERSION_APP "0.8"
 #define WS_DEVELOPED "SkorP"
 #define WS_DEVELOPED "SkorP"
 #define WS_GITHUB "https://github.com/flipperdevices/flipperzero-firmware"
 #define WS_GITHUB "https://github.com/flipperdevices/flipperzero-firmware"
 
 

+ 7 - 15
applications/plugins/weather_station/protocols/acurite_592txr.c

@@ -258,7 +258,7 @@ uint8_t ws_protocol_decoder_acurite_592txr_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool ws_protocol_decoder_acurite_592txr_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_acurite_592txr_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -267,22 +267,14 @@ bool ws_protocol_decoder_acurite_592txr_serialize(
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool ws_protocol_decoder_acurite_592txr_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    ws_protocol_decoder_acurite_592txr_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     WSProtocolDecoderAcurite_592TXR* instance = context;
     WSProtocolDecoderAcurite_592TXR* instance = context;
-    bool ret = false;
-    do {
-        if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           ws_protocol_acurite_592txr_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return ws_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        ws_protocol_acurite_592txr_const.min_count_bit_for_found);
 }
 }
 
 
 void ws_protocol_decoder_acurite_592txr_get_string(void* context, FuriString* output) {
 void ws_protocol_decoder_acurite_592txr_get_string(void* context, FuriString* output) {

+ 5 - 4
applications/plugins/weather_station/protocols/acurite_592txr.h

@@ -56,9 +56,9 @@ uint8_t ws_protocol_decoder_acurite_592txr_get_hash_data(void* context);
  * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance
  * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_acurite_592txr_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_acurite_592txr_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -67,9 +67,10 @@ bool ws_protocol_decoder_acurite_592txr_serialize(
  * Deserialize data WSProtocolDecoderAcurite_592TXR.
  * Deserialize data WSProtocolDecoderAcurite_592TXR.
  * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance
  * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_acurite_592txr_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    ws_protocol_decoder_acurite_592txr_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 7 - 15
applications/plugins/weather_station/protocols/acurite_606tx.c

@@ -199,7 +199,7 @@ uint8_t ws_protocol_decoder_acurite_606tx_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool ws_protocol_decoder_acurite_606tx_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_acurite_606tx_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -208,22 +208,14 @@ bool ws_protocol_decoder_acurite_606tx_serialize(
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool ws_protocol_decoder_acurite_606tx_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    ws_protocol_decoder_acurite_606tx_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     WSProtocolDecoderAcurite_606TX* instance = context;
     WSProtocolDecoderAcurite_606TX* instance = context;
-    bool ret = false;
-    do {
-        if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           ws_protocol_acurite_606tx_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return ws_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        ws_protocol_acurite_606tx_const.min_count_bit_for_found);
 }
 }
 
 
 void ws_protocol_decoder_acurite_606tx_get_string(void* context, FuriString* output) {
 void ws_protocol_decoder_acurite_606tx_get_string(void* context, FuriString* output) {

+ 5 - 4
applications/plugins/weather_station/protocols/acurite_606tx.h

@@ -56,9 +56,9 @@ uint8_t ws_protocol_decoder_acurite_606tx_get_hash_data(void* context);
  * @param context Pointer to a WSProtocolDecoderAcurite_606TX instance
  * @param context Pointer to a WSProtocolDecoderAcurite_606TX instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_acurite_606tx_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_acurite_606tx_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -67,9 +67,10 @@ bool ws_protocol_decoder_acurite_606tx_serialize(
  * Deserialize data WSProtocolDecoderAcurite_606TX.
  * Deserialize data WSProtocolDecoderAcurite_606TX.
  * @param context Pointer to a WSProtocolDecoderAcurite_606TX instance
  * @param context Pointer to a WSProtocolDecoderAcurite_606TX instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_acurite_606tx_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    ws_protocol_decoder_acurite_606tx_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 7 - 15
applications/plugins/weather_station/protocols/acurite_609txc.c

@@ -199,7 +199,7 @@ uint8_t ws_protocol_decoder_acurite_609txc_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool ws_protocol_decoder_acurite_609txc_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_acurite_609txc_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -208,22 +208,14 @@ bool ws_protocol_decoder_acurite_609txc_serialize(
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool ws_protocol_decoder_acurite_609txc_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    ws_protocol_decoder_acurite_609txc_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     WSProtocolDecoderAcurite_609TXC* instance = context;
     WSProtocolDecoderAcurite_609TXC* instance = context;
-    bool ret = false;
-    do {
-        if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           ws_protocol_acurite_609txc_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return ws_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        ws_protocol_acurite_609txc_const.min_count_bit_for_found);
 }
 }
 
 
 void ws_protocol_decoder_acurite_609txc_get_string(void* context, FuriString* output) {
 void ws_protocol_decoder_acurite_609txc_get_string(void* context, FuriString* output) {

+ 5 - 4
applications/plugins/weather_station/protocols/acurite_609txc.h

@@ -56,9 +56,9 @@ uint8_t ws_protocol_decoder_acurite_609txc_get_hash_data(void* context);
  * @param context Pointer to a WSProtocolDecoderAcurite_609TXC instance
  * @param context Pointer to a WSProtocolDecoderAcurite_609TXC instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_acurite_609txc_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_acurite_609txc_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -67,9 +67,10 @@ bool ws_protocol_decoder_acurite_609txc_serialize(
  * Deserialize data WSProtocolDecoderAcurite_609TXC.
  * Deserialize data WSProtocolDecoderAcurite_609TXC.
  * @param context Pointer to a WSProtocolDecoderAcurite_609TXC instance
  * @param context Pointer to a WSProtocolDecoderAcurite_609TXC instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_acurite_609txc_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    ws_protocol_decoder_acurite_609txc_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 7 - 15
applications/plugins/weather_station/protocols/ambient_weather.c

@@ -228,7 +228,7 @@ uint8_t ws_protocol_decoder_ambient_weather_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool ws_protocol_decoder_ambient_weather_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_ambient_weather_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -237,22 +237,14 @@ bool ws_protocol_decoder_ambient_weather_serialize(
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool ws_protocol_decoder_ambient_weather_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    ws_protocol_decoder_ambient_weather_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     WSProtocolDecoderAmbient_Weather* instance = context;
     WSProtocolDecoderAmbient_Weather* instance = context;
-    bool ret = false;
-    do {
-        if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           ws_protocol_ambient_weather_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return ws_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        ws_protocol_ambient_weather_const.min_count_bit_for_found);
 }
 }
 
 
 void ws_protocol_decoder_ambient_weather_get_string(void* context, FuriString* output) {
 void ws_protocol_decoder_ambient_weather_get_string(void* context, FuriString* output) {

+ 5 - 4
applications/plugins/weather_station/protocols/ambient_weather.h

@@ -56,9 +56,9 @@ uint8_t ws_protocol_decoder_ambient_weather_get_hash_data(void* context);
  * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance
  * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_ambient_weather_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_ambient_weather_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -67,9 +67,10 @@ bool ws_protocol_decoder_ambient_weather_serialize(
  * Deserialize data WSProtocolDecoderAmbient_Weather.
  * Deserialize data WSProtocolDecoderAmbient_Weather.
  * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance
  * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_ambient_weather_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    ws_protocol_decoder_ambient_weather_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 5 - 15
applications/plugins/weather_station/protocols/auriol_hg0601a.c

@@ -210,7 +210,7 @@ uint8_t ws_protocol_decoder_auriol_th_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool ws_protocol_decoder_auriol_th_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_auriol_th_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -219,22 +219,12 @@ bool ws_protocol_decoder_auriol_th_serialize(
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool ws_protocol_decoder_auriol_th_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    ws_protocol_decoder_auriol_th_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     WSProtocolDecoderAuriol_TH* instance = context;
     WSProtocolDecoderAuriol_TH* instance = context;
-    bool ret = false;
-    do {
-        if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           ws_protocol_auriol_th_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return ws_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, ws_protocol_auriol_th_const.min_count_bit_for_found);
 }
 }
 
 
 void ws_protocol_decoder_auriol_th_get_string(void* context, FuriString* output) {
 void ws_protocol_decoder_auriol_th_get_string(void* context, FuriString* output) {

+ 5 - 4
applications/plugins/weather_station/protocols/auriol_hg0601a.h

@@ -56,9 +56,9 @@ uint8_t ws_protocol_decoder_auriol_th_get_hash_data(void* context);
  * @param context Pointer to a WSProtocolDecoderAuriol_TH instance
  * @param context Pointer to a WSProtocolDecoderAuriol_TH instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_auriol_th_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_auriol_th_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -67,9 +67,10 @@ bool ws_protocol_decoder_auriol_th_serialize(
  * Deserialize data WSProtocolDecoderAuriol_TH.
  * Deserialize data WSProtocolDecoderAuriol_TH.
  * @param context Pointer to a WSProtocolDecoderAuriol_TH instance
  * @param context Pointer to a WSProtocolDecoderAuriol_TH instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_auriol_th_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    ws_protocol_decoder_auriol_th_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 5 - 15
applications/plugins/weather_station/protocols/gt_wt_02.c

@@ -217,7 +217,7 @@ uint8_t ws_protocol_decoder_gt_wt_02_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool ws_protocol_decoder_gt_wt_02_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_gt_wt_02_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -226,22 +226,12 @@ bool ws_protocol_decoder_gt_wt_02_serialize(
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool ws_protocol_decoder_gt_wt_02_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    ws_protocol_decoder_gt_wt_02_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     WSProtocolDecoderGT_WT02* instance = context;
     WSProtocolDecoderGT_WT02* instance = context;
-    bool ret = false;
-    do {
-        if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           ws_protocol_gt_wt_02_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return ws_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, ws_protocol_gt_wt_02_const.min_count_bit_for_found);
 }
 }
 
 
 void ws_protocol_decoder_gt_wt_02_get_string(void* context, FuriString* output) {
 void ws_protocol_decoder_gt_wt_02_get_string(void* context, FuriString* output) {

+ 5 - 4
applications/plugins/weather_station/protocols/gt_wt_02.h

@@ -56,9 +56,9 @@ uint8_t ws_protocol_decoder_gt_wt_02_get_hash_data(void* context);
  * @param context Pointer to a WSProtocolDecoderGT_WT02 instance
  * @param context Pointer to a WSProtocolDecoderGT_WT02 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_gt_wt_02_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_gt_wt_02_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -67,9 +67,10 @@ bool ws_protocol_decoder_gt_wt_02_serialize(
  * Deserialize data WSProtocolDecoderGT_WT02.
  * Deserialize data WSProtocolDecoderGT_WT02.
  * @param context Pointer to a WSProtocolDecoderGT_WT02 instance
  * @param context Pointer to a WSProtocolDecoderGT_WT02 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_gt_wt_02_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    ws_protocol_decoder_gt_wt_02_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 5 - 15
applications/plugins/weather_station/protocols/gt_wt_03.c

@@ -292,7 +292,7 @@ uint8_t ws_protocol_decoder_gt_wt_03_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool ws_protocol_decoder_gt_wt_03_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_gt_wt_03_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -301,22 +301,12 @@ bool ws_protocol_decoder_gt_wt_03_serialize(
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool ws_protocol_decoder_gt_wt_03_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    ws_protocol_decoder_gt_wt_03_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     WSProtocolDecoderGT_WT03* instance = context;
     WSProtocolDecoderGT_WT03* instance = context;
-    bool ret = false;
-    do {
-        if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           ws_protocol_gt_wt_03_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return ws_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, ws_protocol_gt_wt_03_const.min_count_bit_for_found);
 }
 }
 
 
 void ws_protocol_decoder_gt_wt_03_get_string(void* context, FuriString* output) {
 void ws_protocol_decoder_gt_wt_03_get_string(void* context, FuriString* output) {

+ 5 - 4
applications/plugins/weather_station/protocols/gt_wt_03.h

@@ -56,9 +56,9 @@ uint8_t ws_protocol_decoder_gt_wt_03_get_hash_data(void* context);
  * @param context Pointer to a WSProtocolDecoderGT_WT03 instance
  * @param context Pointer to a WSProtocolDecoderGT_WT03 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_gt_wt_03_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_gt_wt_03_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -67,9 +67,10 @@ bool ws_protocol_decoder_gt_wt_03_serialize(
  * Deserialize data WSProtocolDecoderGT_WT03.
  * Deserialize data WSProtocolDecoderGT_WT03.
  * @param context Pointer to a WSProtocolDecoderGT_WT03 instance
  * @param context Pointer to a WSProtocolDecoderGT_WT03 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_gt_wt_03_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    ws_protocol_decoder_gt_wt_03_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 5 - 15
applications/plugins/weather_station/protocols/infactory.c

@@ -248,7 +248,7 @@ uint8_t ws_protocol_decoder_infactory_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool ws_protocol_decoder_infactory_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_infactory_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -257,22 +257,12 @@ bool ws_protocol_decoder_infactory_serialize(
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool ws_protocol_decoder_infactory_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    ws_protocol_decoder_infactory_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     WSProtocolDecoderInfactory* instance = context;
     WSProtocolDecoderInfactory* instance = context;
-    bool ret = false;
-    do {
-        if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           ws_protocol_infactory_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return ws_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, ws_protocol_infactory_const.min_count_bit_for_found);
 }
 }
 
 
 void ws_protocol_decoder_infactory_get_string(void* context, FuriString* output) {
 void ws_protocol_decoder_infactory_get_string(void* context, FuriString* output) {

+ 5 - 4
applications/plugins/weather_station/protocols/infactory.h

@@ -56,9 +56,9 @@ uint8_t ws_protocol_decoder_infactory_get_hash_data(void* context);
  * @param context Pointer to a WSProtocolDecoderInfactory instance
  * @param context Pointer to a WSProtocolDecoderInfactory instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_infactory_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_infactory_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -67,9 +67,10 @@ bool ws_protocol_decoder_infactory_serialize(
  * Deserialize data WSProtocolDecoderInfactory.
  * Deserialize data WSProtocolDecoderInfactory.
  * @param context Pointer to a WSProtocolDecoderInfactory instance
  * @param context Pointer to a WSProtocolDecoderInfactory instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_infactory_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    ws_protocol_decoder_infactory_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 5 - 15
applications/plugins/weather_station/protocols/lacrosse_tx.c

@@ -281,7 +281,7 @@ uint8_t ws_protocol_decoder_lacrosse_tx_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool ws_protocol_decoder_lacrosse_tx_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_lacrosse_tx_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -290,22 +290,12 @@ bool ws_protocol_decoder_lacrosse_tx_serialize(
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool ws_protocol_decoder_lacrosse_tx_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    ws_protocol_decoder_lacrosse_tx_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     WSProtocolDecoderLaCrosse_TX* instance = context;
     WSProtocolDecoderLaCrosse_TX* instance = context;
-    bool ret = false;
-    do {
-        if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           ws_protocol_lacrosse_tx_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return ws_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, ws_protocol_lacrosse_tx_const.min_count_bit_for_found);
 }
 }
 
 
 void ws_protocol_decoder_lacrosse_tx_get_string(void* context, FuriString* output) {
 void ws_protocol_decoder_lacrosse_tx_get_string(void* context, FuriString* output) {

+ 5 - 4
applications/plugins/weather_station/protocols/lacrosse_tx.h

@@ -56,9 +56,9 @@ uint8_t ws_protocol_decoder_lacrosse_tx_get_hash_data(void* context);
  * @param context Pointer to a WSProtocolDecoderLaCrosse_TX instance
  * @param context Pointer to a WSProtocolDecoderLaCrosse_TX instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_lacrosse_tx_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_lacrosse_tx_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -67,9 +67,10 @@ bool ws_protocol_decoder_lacrosse_tx_serialize(
  * Deserialize data WSProtocolDecoderLaCrosse_TX.
  * Deserialize data WSProtocolDecoderLaCrosse_TX.
  * @param context Pointer to a WSProtocolDecoderLaCrosse_TX instance
  * @param context Pointer to a WSProtocolDecoderLaCrosse_TX instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_lacrosse_tx_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    ws_protocol_decoder_lacrosse_tx_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 6 - 15
applications/plugins/weather_station/protocols/lacrosse_tx141thbv2.c

@@ -247,7 +247,7 @@ uint8_t ws_protocol_decoder_lacrosse_tx141thbv2_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool ws_protocol_decoder_lacrosse_tx141thbv2_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_lacrosse_tx141thbv2_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -256,24 +256,15 @@ bool ws_protocol_decoder_lacrosse_tx141thbv2_serialize(
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool ws_protocol_decoder_lacrosse_tx141thbv2_deserialize(
+SubGhzProtocolStatus ws_protocol_decoder_lacrosse_tx141thbv2_deserialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format) {
     FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     WSProtocolDecoderLaCrosse_TX141THBv2* instance = context;
     WSProtocolDecoderLaCrosse_TX141THBv2* instance = context;
-    bool ret = false;
-    do {
-        if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           ws_protocol_lacrosse_tx141thbv2_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return ws_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        ws_protocol_lacrosse_tx141thbv2_const.min_count_bit_for_found);
 }
 }
 
 
 void ws_protocol_decoder_lacrosse_tx141thbv2_get_string(void* context, FuriString* output) {
 void ws_protocol_decoder_lacrosse_tx141thbv2_get_string(void* context, FuriString* output) {

+ 4 - 4
applications/plugins/weather_station/protocols/lacrosse_tx141thbv2.h

@@ -56,9 +56,9 @@ uint8_t ws_protocol_decoder_lacrosse_tx141thbv2_get_hash_data(void* context);
  * @param context Pointer to a WSProtocolDecoderLaCrosse_TX141THBv2 instance
  * @param context Pointer to a WSProtocolDecoderLaCrosse_TX141THBv2 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_lacrosse_tx141thbv2_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_lacrosse_tx141thbv2_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -67,9 +67,9 @@ bool ws_protocol_decoder_lacrosse_tx141thbv2_serialize(
  * Deserialize data WSProtocolDecoderLaCrosse_TX141THBv2.
  * Deserialize data WSProtocolDecoderLaCrosse_TX141THBv2.
  * @param context Pointer to a WSProtocolDecoderLaCrosse_TX141THBv2 instance
  * @param context Pointer to a WSProtocolDecoderLaCrosse_TX141THBv2 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_lacrosse_tx141thbv2_deserialize(
+SubGhzProtocolStatus ws_protocol_decoder_lacrosse_tx141thbv2_deserialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format);
     FlipperFormat* flipper_format);
 
 

+ 5 - 15
applications/plugins/weather_station/protocols/nexus_th.c

@@ -216,7 +216,7 @@ uint8_t ws_protocol_decoder_nexus_th_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool ws_protocol_decoder_nexus_th_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_nexus_th_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -225,22 +225,12 @@ bool ws_protocol_decoder_nexus_th_serialize(
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool ws_protocol_decoder_nexus_th_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    ws_protocol_decoder_nexus_th_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     WSProtocolDecoderNexus_TH* instance = context;
     WSProtocolDecoderNexus_TH* instance = context;
-    bool ret = false;
-    do {
-        if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           ws_protocol_nexus_th_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return ws_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, ws_protocol_nexus_th_const.min_count_bit_for_found);
 }
 }
 
 
 void ws_protocol_decoder_nexus_th_get_string(void* context, FuriString* output) {
 void ws_protocol_decoder_nexus_th_get_string(void* context, FuriString* output) {

+ 5 - 4
applications/plugins/weather_station/protocols/nexus_th.h

@@ -56,9 +56,9 @@ uint8_t ws_protocol_decoder_nexus_th_get_hash_data(void* context);
  * @param context Pointer to a WSProtocolDecoderNexus_TH instance
  * @param context Pointer to a WSProtocolDecoderNexus_TH instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_nexus_th_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_nexus_th_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -67,9 +67,10 @@ bool ws_protocol_decoder_nexus_th_serialize(
  * Deserialize data WSProtocolDecoderNexus_TH.
  * Deserialize data WSProtocolDecoderNexus_TH.
  * @param context Pointer to a WSProtocolDecoderNexus_TH instance
  * @param context Pointer to a WSProtocolDecoderNexus_TH instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_nexus_th_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    ws_protocol_decoder_nexus_th_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 15 - 9
applications/plugins/weather_station/protocols/oregon2.c

@@ -302,17 +302,19 @@ uint8_t ws_protocol_decoder_oregon2_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool ws_protocol_decoder_oregon2_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_oregon2_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
     furi_assert(context);
     furi_assert(context);
     WSProtocolDecoderOregon2* instance = context;
     WSProtocolDecoderOregon2* instance = context;
-    if(!ws_block_generic_serialize(&instance->generic, flipper_format, preset)) return false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
+    ret = ws_block_generic_serialize(&instance->generic, flipper_format, preset);
+    if(ret != SubGhzProtocolStatusOk) return ret;
     uint32_t temp = instance->var_bits;
     uint32_t temp = instance->var_bits;
     if(!flipper_format_write_uint32(flipper_format, "VarBits", &temp, 1)) {
     if(!flipper_format_write_uint32(flipper_format, "VarBits", &temp, 1)) {
         FURI_LOG_E(TAG, "Error adding VarBits");
         FURI_LOG_E(TAG, "Error adding VarBits");
-        return false;
+        return SubGhzProtocolStatusErrorParserOthers;
     }
     }
     if(!flipper_format_write_hex(
     if(!flipper_format_write_hex(
            flipper_format,
            flipper_format,
@@ -320,22 +322,25 @@ bool ws_protocol_decoder_oregon2_serialize(
            (const uint8_t*)&instance->var_data,
            (const uint8_t*)&instance->var_data,
            sizeof(instance->var_data))) {
            sizeof(instance->var_data))) {
         FURI_LOG_E(TAG, "Error adding VarData");
         FURI_LOG_E(TAG, "Error adding VarData");
-        return false;
+        return SubGhzProtocolStatusErrorParserOthers;
     }
     }
-    return true;
+    return ret;
 }
 }
 
 
-bool ws_protocol_decoder_oregon2_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    ws_protocol_decoder_oregon2_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     WSProtocolDecoderOregon2* instance = context;
     WSProtocolDecoderOregon2* instance = context;
-    bool ret = false;
     uint32_t temp_data;
     uint32_t temp_data;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) {
+        ret = ws_block_generic_deserialize(&instance->generic, flipper_format);
+        if(ret != SubGhzProtocolStatusOk) {
             break;
             break;
         }
         }
         if(!flipper_format_read_uint32(flipper_format, "VarBits", &temp_data, 1)) {
         if(!flipper_format_read_uint32(flipper_format, "VarBits", &temp_data, 1)) {
             FURI_LOG_E(TAG, "Missing VarLen");
             FURI_LOG_E(TAG, "Missing VarLen");
+            ret = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         instance->var_bits = (uint8_t)temp_data;
         instance->var_bits = (uint8_t)temp_data;
@@ -345,13 +350,14 @@ bool ws_protocol_decoder_oregon2_deserialize(void* context, FlipperFormat* flipp
                (uint8_t*)&instance->var_data,
                (uint8_t*)&instance->var_data,
                sizeof(instance->var_data))) { //-V1051
                sizeof(instance->var_data))) { //-V1051
             FURI_LOG_E(TAG, "Missing VarData");
             FURI_LOG_E(TAG, "Missing VarData");
+            ret = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         if(instance->generic.data_count_bit != ws_oregon2_const.min_count_bit_for_found) {
         if(instance->generic.data_count_bit != ws_oregon2_const.min_count_bit_for_found) {
             FURI_LOG_E(TAG, "Wrong number of bits in key: %d", instance->generic.data_count_bit);
             FURI_LOG_E(TAG, "Wrong number of bits in key: %d", instance->generic.data_count_bit);
+            ret = SubGhzProtocolStatusErrorValueBitCount;
             break;
             break;
         }
         }
-        ret = true;
     } while(false);
     } while(false);
     return ret;
     return ret;
 }
 }

+ 5 - 15
applications/plugins/weather_station/protocols/oregon_v1.c

@@ -283,7 +283,7 @@ uint8_t ws_protocol_decoder_oregon_v1_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool ws_protocol_decoder_oregon_v1_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_oregon_v1_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -292,22 +292,12 @@ bool ws_protocol_decoder_oregon_v1_serialize(
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool ws_protocol_decoder_oregon_v1_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    ws_protocol_decoder_oregon_v1_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     WSProtocolDecoderOregon_V1* instance = context;
     WSProtocolDecoderOregon_V1* instance = context;
-    bool ret = false;
-    do {
-        if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           ws_protocol_oregon_v1_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return ws_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, ws_protocol_oregon_v1_const.min_count_bit_for_found);
 }
 }
 
 
 void ws_protocol_decoder_oregon_v1_get_string(void* context, FuriString* output) {
 void ws_protocol_decoder_oregon_v1_get_string(void* context, FuriString* output) {

+ 5 - 4
applications/plugins/weather_station/protocols/oregon_v1.h

@@ -56,9 +56,9 @@ uint8_t ws_protocol_decoder_oregon_v1_get_hash_data(void* context);
  * @param context Pointer to a WSProtocolDecoderOregon_V1 instance
  * @param context Pointer to a WSProtocolDecoderOregon_V1 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_oregon_v1_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_oregon_v1_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -67,9 +67,10 @@ bool ws_protocol_decoder_oregon_v1_serialize(
  * Deserialize data WSProtocolDecoderOregon_V1.
  * Deserialize data WSProtocolDecoderOregon_V1.
  * @param context Pointer to a WSProtocolDecoderOregon_V1 instance
  * @param context Pointer to a WSProtocolDecoderOregon_V1 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_oregon_v1_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    ws_protocol_decoder_oregon_v1_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 7 - 15
applications/plugins/weather_station/protocols/thermopro_tx4.c

@@ -211,7 +211,7 @@ uint8_t ws_protocol_decoder_thermopro_tx4_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool ws_protocol_decoder_thermopro_tx4_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_thermopro_tx4_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -220,22 +220,14 @@ bool ws_protocol_decoder_thermopro_tx4_serialize(
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool ws_protocol_decoder_thermopro_tx4_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    ws_protocol_decoder_thermopro_tx4_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     WSProtocolDecoderThermoPRO_TX4* instance = context;
     WSProtocolDecoderThermoPRO_TX4* instance = context;
-    bool ret = false;
-    do {
-        if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           ws_protocol_thermopro_tx4_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return ws_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        ws_protocol_thermopro_tx4_const.min_count_bit_for_found);
 }
 }
 
 
 void ws_protocol_decoder_thermopro_tx4_get_string(void* context, FuriString* output) {
 void ws_protocol_decoder_thermopro_tx4_get_string(void* context, FuriString* output) {

+ 5 - 4
applications/plugins/weather_station/protocols/thermopro_tx4.h

@@ -56,9 +56,9 @@ uint8_t ws_protocol_decoder_thermopro_tx4_get_hash_data(void* context);
  * @param context Pointer to a WSProtocolDecoderThermoPRO_TX4 instance
  * @param context Pointer to a WSProtocolDecoderThermoPRO_TX4 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_thermopro_tx4_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_thermopro_tx4_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -67,9 +67,10 @@ bool ws_protocol_decoder_thermopro_tx4_serialize(
  * Deserialize data WSProtocolDecoderThermoPRO_TX4.
  * Deserialize data WSProtocolDecoderThermoPRO_TX4.
  * @param context Pointer to a WSProtocolDecoderThermoPRO_TX4 instance
  * @param context Pointer to a WSProtocolDecoderThermoPRO_TX4 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_thermopro_tx4_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    ws_protocol_decoder_thermopro_tx4_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 5 - 14
applications/plugins/weather_station/protocols/tx_8300.c

@@ -246,7 +246,7 @@ uint8_t ws_protocol_decoder_tx_8300_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool ws_protocol_decoder_tx_8300_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_tx_8300_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -255,21 +255,12 @@ bool ws_protocol_decoder_tx_8300_serialize(
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
     return ws_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool ws_protocol_decoder_tx_8300_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    ws_protocol_decoder_tx_8300_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     WSProtocolDecoderTX_8300* instance = context;
     WSProtocolDecoderTX_8300* instance = context;
-    bool ret = false;
-    do {
-        if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit != ws_protocol_tx_8300_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return ws_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, ws_protocol_tx_8300_const.min_count_bit_for_found);
 }
 }
 
 
 void ws_protocol_decoder_tx_8300_get_string(void* context, FuriString* output) {
 void ws_protocol_decoder_tx_8300_get_string(void* context, FuriString* output) {

+ 5 - 4
applications/plugins/weather_station/protocols/tx_8300.h

@@ -56,9 +56,9 @@ uint8_t ws_protocol_decoder_tx_8300_get_hash_data(void* context);
  * @param context Pointer to a WSProtocolDecoderTX_8300 instance
  * @param context Pointer to a WSProtocolDecoderTX_8300 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_tx_8300_serialize(
+SubGhzProtocolStatus ws_protocol_decoder_tx_8300_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -67,9 +67,10 @@ bool ws_protocol_decoder_tx_8300_serialize(
  * Deserialize data WSProtocolDecoderTX_8300.
  * Deserialize data WSProtocolDecoderTX_8300.
  * @param context Pointer to a WSProtocolDecoderTX_8300 instance
  * @param context Pointer to a WSProtocolDecoderTX_8300 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool ws_protocol_decoder_tx_8300_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    ws_protocol_decoder_tx_8300_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 51 - 6
applications/plugins/weather_station/protocols/ws_generic.c

@@ -21,12 +21,12 @@ void ws_block_generic_get_preset_name(const char* preset_name, FuriString* prese
     furi_string_set(preset_str, preset_name_temp);
     furi_string_set(preset_str, preset_name_temp);
 }
 }
 
 
-bool ws_block_generic_serialize(
+SubGhzProtocolStatus ws_block_generic_serialize(
     WSBlockGeneric* instance,
     WSBlockGeneric* instance,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
     furi_assert(instance);
     furi_assert(instance);
-    bool res = false;
+    SubGhzProtocolStatus res = SubGhzProtocolStatusError;
     FuriString* temp_str;
     FuriString* temp_str;
     temp_str = furi_string_alloc();
     temp_str = furi_string_alloc();
     do {
     do {
@@ -34,11 +34,13 @@ bool ws_block_generic_serialize(
         if(!flipper_format_write_header_cstr(
         if(!flipper_format_write_header_cstr(
                flipper_format, WS_KEY_FILE_TYPE, WS_KEY_FILE_VERSION)) {
                flipper_format, WS_KEY_FILE_TYPE, WS_KEY_FILE_VERSION)) {
             FURI_LOG_E(TAG, "Unable to add header");
             FURI_LOG_E(TAG, "Unable to add header");
+            res = SubGhzProtocolStatusErrorParserHeader;
             break;
             break;
         }
         }
 
 
         if(!flipper_format_write_uint32(flipper_format, "Frequency", &preset->frequency, 1)) {
         if(!flipper_format_write_uint32(flipper_format, "Frequency", &preset->frequency, 1)) {
             FURI_LOG_E(TAG, "Unable to add Frequency");
             FURI_LOG_E(TAG, "Unable to add Frequency");
+            res = SubGhzProtocolStatusErrorParserFrequency;
             break;
             break;
         }
         }
 
 
@@ -46,34 +48,40 @@ bool ws_block_generic_serialize(
         if(!flipper_format_write_string_cstr(
         if(!flipper_format_write_string_cstr(
                flipper_format, "Preset", furi_string_get_cstr(temp_str))) {
                flipper_format, "Preset", furi_string_get_cstr(temp_str))) {
             FURI_LOG_E(TAG, "Unable to add Preset");
             FURI_LOG_E(TAG, "Unable to add Preset");
+            res = SubGhzProtocolStatusErrorParserPreset;
             break;
             break;
         }
         }
         if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) {
         if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) {
             if(!flipper_format_write_string_cstr(
             if(!flipper_format_write_string_cstr(
                    flipper_format, "Custom_preset_module", "CC1101")) {
                    flipper_format, "Custom_preset_module", "CC1101")) {
                 FURI_LOG_E(TAG, "Unable to add Custom_preset_module");
                 FURI_LOG_E(TAG, "Unable to add Custom_preset_module");
+                res = SubGhzProtocolStatusErrorParserCustomPreset;
                 break;
                 break;
             }
             }
             if(!flipper_format_write_hex(
             if(!flipper_format_write_hex(
                    flipper_format, "Custom_preset_data", preset->data, preset->data_size)) {
                    flipper_format, "Custom_preset_data", preset->data, preset->data_size)) {
                 FURI_LOG_E(TAG, "Unable to add Custom_preset_data");
                 FURI_LOG_E(TAG, "Unable to add Custom_preset_data");
+                res = SubGhzProtocolStatusErrorParserCustomPreset;
                 break;
                 break;
             }
             }
         }
         }
         if(!flipper_format_write_string_cstr(flipper_format, "Protocol", instance->protocol_name)) {
         if(!flipper_format_write_string_cstr(flipper_format, "Protocol", instance->protocol_name)) {
             FURI_LOG_E(TAG, "Unable to add Protocol");
             FURI_LOG_E(TAG, "Unable to add Protocol");
+            res = SubGhzProtocolStatusErrorParserProtocolName;
             break;
             break;
         }
         }
 
 
         uint32_t temp_data = instance->id;
         uint32_t temp_data = instance->id;
         if(!flipper_format_write_uint32(flipper_format, "Id", &temp_data, 1)) {
         if(!flipper_format_write_uint32(flipper_format, "Id", &temp_data, 1)) {
             FURI_LOG_E(TAG, "Unable to add Id");
             FURI_LOG_E(TAG, "Unable to add Id");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
 
 
         temp_data = instance->data_count_bit;
         temp_data = instance->data_count_bit;
         if(!flipper_format_write_uint32(flipper_format, "Bit", &temp_data, 1)) {
         if(!flipper_format_write_uint32(flipper_format, "Bit", &temp_data, 1)) {
             FURI_LOG_E(TAG, "Unable to add Bit");
             FURI_LOG_E(TAG, "Unable to add Bit");
+            res = SubGhzProtocolStatusErrorParserBitCount;
             break;
             break;
         }
         }
 
 
@@ -84,18 +92,21 @@ bool ws_block_generic_serialize(
 
 
         if(!flipper_format_write_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
         if(!flipper_format_write_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
             FURI_LOG_E(TAG, "Unable to add Data");
             FURI_LOG_E(TAG, "Unable to add Data");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
 
 
         temp_data = instance->battery_low;
         temp_data = instance->battery_low;
         if(!flipper_format_write_uint32(flipper_format, "Batt", &temp_data, 1)) {
         if(!flipper_format_write_uint32(flipper_format, "Batt", &temp_data, 1)) {
             FURI_LOG_E(TAG, "Unable to add Battery_low");
             FURI_LOG_E(TAG, "Unable to add Battery_low");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
 
 
         temp_data = instance->humidity;
         temp_data = instance->humidity;
         if(!flipper_format_write_uint32(flipper_format, "Hum", &temp_data, 1)) {
         if(!flipper_format_write_uint32(flipper_format, "Hum", &temp_data, 1)) {
             FURI_LOG_E(TAG, "Unable to add Humidity");
             FURI_LOG_E(TAG, "Unable to add Humidity");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
 
 
@@ -107,52 +118,60 @@ bool ws_block_generic_serialize(
         temp_data = curr_ts;
         temp_data = curr_ts;
         if(!flipper_format_write_uint32(flipper_format, "Ts", &temp_data, 1)) {
         if(!flipper_format_write_uint32(flipper_format, "Ts", &temp_data, 1)) {
             FURI_LOG_E(TAG, "Unable to add timestamp");
             FURI_LOG_E(TAG, "Unable to add timestamp");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
 
 
         temp_data = instance->channel;
         temp_data = instance->channel;
         if(!flipper_format_write_uint32(flipper_format, "Ch", &temp_data, 1)) {
         if(!flipper_format_write_uint32(flipper_format, "Ch", &temp_data, 1)) {
             FURI_LOG_E(TAG, "Unable to add Channel");
             FURI_LOG_E(TAG, "Unable to add Channel");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
 
 
         temp_data = instance->btn;
         temp_data = instance->btn;
         if(!flipper_format_write_uint32(flipper_format, "Btn", &temp_data, 1)) {
         if(!flipper_format_write_uint32(flipper_format, "Btn", &temp_data, 1)) {
             FURI_LOG_E(TAG, "Unable to add Btn");
             FURI_LOG_E(TAG, "Unable to add Btn");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
 
 
         float temp = instance->temp;
         float temp = instance->temp;
         if(!flipper_format_write_float(flipper_format, "Temp", &temp, 1)) {
         if(!flipper_format_write_float(flipper_format, "Temp", &temp, 1)) {
             FURI_LOG_E(TAG, "Unable to add Temperature");
             FURI_LOG_E(TAG, "Unable to add Temperature");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
 
 
-        res = true;
+        res = SubGhzProtocolStatusOk;
     } while(false);
     } while(false);
     furi_string_free(temp_str);
     furi_string_free(temp_str);
     return res;
     return res;
 }
 }
 
 
-bool ws_block_generic_deserialize(WSBlockGeneric* instance, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    ws_block_generic_deserialize(WSBlockGeneric* instance, FlipperFormat* flipper_format) {
     furi_assert(instance);
     furi_assert(instance);
-    bool res = false;
+    SubGhzProtocolStatus res = SubGhzProtocolStatusError;
     uint32_t temp_data = 0;
     uint32_t temp_data = 0;
 
 
     do {
     do {
         if(!flipper_format_rewind(flipper_format)) {
         if(!flipper_format_rewind(flipper_format)) {
             FURI_LOG_E(TAG, "Rewind error");
             FURI_LOG_E(TAG, "Rewind error");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
 
 
         if(!flipper_format_read_uint32(flipper_format, "Id", (uint32_t*)&temp_data, 1)) {
         if(!flipper_format_read_uint32(flipper_format, "Id", (uint32_t*)&temp_data, 1)) {
             FURI_LOG_E(TAG, "Missing Id");
             FURI_LOG_E(TAG, "Missing Id");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         instance->id = (uint32_t)temp_data;
         instance->id = (uint32_t)temp_data;
 
 
         if(!flipper_format_read_uint32(flipper_format, "Bit", (uint32_t*)&temp_data, 1)) {
         if(!flipper_format_read_uint32(flipper_format, "Bit", (uint32_t*)&temp_data, 1)) {
             FURI_LOG_E(TAG, "Missing Bit");
             FURI_LOG_E(TAG, "Missing Bit");
+            res = SubGhzProtocolStatusErrorParserBitCount;
             break;
             break;
         }
         }
         instance->data_count_bit = (uint8_t)temp_data;
         instance->data_count_bit = (uint8_t)temp_data;
@@ -160,6 +179,7 @@ bool ws_block_generic_deserialize(WSBlockGeneric* instance, FlipperFormat* flipp
         uint8_t key_data[sizeof(uint64_t)] = {0};
         uint8_t key_data[sizeof(uint64_t)] = {0};
         if(!flipper_format_read_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
         if(!flipper_format_read_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
             FURI_LOG_E(TAG, "Missing Data");
             FURI_LOG_E(TAG, "Missing Data");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
 
 
@@ -169,30 +189,35 @@ bool ws_block_generic_deserialize(WSBlockGeneric* instance, FlipperFormat* flipp
 
 
         if(!flipper_format_read_uint32(flipper_format, "Batt", (uint32_t*)&temp_data, 1)) {
         if(!flipper_format_read_uint32(flipper_format, "Batt", (uint32_t*)&temp_data, 1)) {
             FURI_LOG_E(TAG, "Missing Battery_low");
             FURI_LOG_E(TAG, "Missing Battery_low");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         instance->battery_low = (uint8_t)temp_data;
         instance->battery_low = (uint8_t)temp_data;
 
 
         if(!flipper_format_read_uint32(flipper_format, "Hum", (uint32_t*)&temp_data, 1)) {
         if(!flipper_format_read_uint32(flipper_format, "Hum", (uint32_t*)&temp_data, 1)) {
             FURI_LOG_E(TAG, "Missing Humidity");
             FURI_LOG_E(TAG, "Missing Humidity");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         instance->humidity = (uint8_t)temp_data;
         instance->humidity = (uint8_t)temp_data;
 
 
         if(!flipper_format_read_uint32(flipper_format, "Ts", (uint32_t*)&temp_data, 1)) {
         if(!flipper_format_read_uint32(flipper_format, "Ts", (uint32_t*)&temp_data, 1)) {
             FURI_LOG_E(TAG, "Missing timestamp");
             FURI_LOG_E(TAG, "Missing timestamp");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         instance->timestamp = (uint32_t)temp_data;
         instance->timestamp = (uint32_t)temp_data;
 
 
         if(!flipper_format_read_uint32(flipper_format, "Ch", (uint32_t*)&temp_data, 1)) {
         if(!flipper_format_read_uint32(flipper_format, "Ch", (uint32_t*)&temp_data, 1)) {
             FURI_LOG_E(TAG, "Missing Channel");
             FURI_LOG_E(TAG, "Missing Channel");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         instance->channel = (uint8_t)temp_data;
         instance->channel = (uint8_t)temp_data;
 
 
         if(!flipper_format_read_uint32(flipper_format, "Btn", (uint32_t*)&temp_data, 1)) {
         if(!flipper_format_read_uint32(flipper_format, "Btn", (uint32_t*)&temp_data, 1)) {
             FURI_LOG_E(TAG, "Missing Btn");
             FURI_LOG_E(TAG, "Missing Btn");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         instance->btn = (uint8_t)temp_data;
         instance->btn = (uint8_t)temp_data;
@@ -200,12 +225,32 @@ bool ws_block_generic_deserialize(WSBlockGeneric* instance, FlipperFormat* flipp
         float temp;
         float temp;
         if(!flipper_format_read_float(flipper_format, "Temp", (float*)&temp, 1)) {
         if(!flipper_format_read_float(flipper_format, "Temp", (float*)&temp, 1)) {
             FURI_LOG_E(TAG, "Missing Temperature");
             FURI_LOG_E(TAG, "Missing Temperature");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         instance->temp = temp;
         instance->temp = temp;
 
 
-        res = true;
+        res = SubGhzProtocolStatusOk;
     } while(0);
     } while(0);
 
 
     return res;
     return res;
+}
+
+SubGhzProtocolStatus ws_block_generic_deserialize_check_count_bit(
+    WSBlockGeneric* instance,
+    FlipperFormat* flipper_format,
+    uint16_t count_bit) {
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
+    do {
+        ret = ws_block_generic_deserialize(instance, flipper_format);
+        if(ret != SubGhzProtocolStatusOk) {
+            break;
+        }
+        if(instance->data_count_bit != count_bit) {
+            FURI_LOG_E(TAG, "Wrong number of bits in key");
+            ret = SubGhzProtocolStatusErrorValueBitCount;
+            break;
+        }
+    } while(false);
+    return ret;
 }
 }

+ 17 - 4
applications/plugins/weather_station/protocols/ws_generic.h

@@ -48,9 +48,9 @@ void ws_block_generic_get_preset_name(const char* preset_name, FuriString* prese
  * @param instance Pointer to a WSBlockGeneric instance
  * @param instance Pointer to a WSBlockGeneric instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool ws_block_generic_serialize(
+SubGhzProtocolStatus ws_block_generic_serialize(
     WSBlockGeneric* instance,
     WSBlockGeneric* instance,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -59,9 +59,22 @@ bool ws_block_generic_serialize(
  * Deserialize data WSBlockGeneric.
  * Deserialize data WSBlockGeneric.
  * @param instance Pointer to a WSBlockGeneric instance
  * @param instance Pointer to a WSBlockGeneric instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool ws_block_generic_deserialize(WSBlockGeneric* instance, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    ws_block_generic_deserialize(WSBlockGeneric* instance, FlipperFormat* flipper_format);
+
+/**
+ * Deserialize data WSBlockGeneric.
+ * @param instance Pointer to a WSBlockGeneric instance
+ * @param flipper_format Pointer to a FlipperFormat instance
+ * @param count_bit Count bit protocol
+ * @return status
+ */
+SubGhzProtocolStatus ws_block_generic_deserialize_check_count_bit(
+    WSBlockGeneric* instance,
+    FlipperFormat* flipper_format,
+    uint16_t count_bit);
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }

+ 1 - 1
firmware/targets/f18/api_symbols.csv

@@ -1,5 +1,5 @@
 entry,status,name,type,params
 entry,status,name,type,params
-Version,+,16.0,,
+Version,+,17.0,,
 Header,+,applications/services/bt/bt_service/bt.h,,
 Header,+,applications/services/bt/bt_service/bt.h,,
 Header,+,applications/services/cli/cli.h,,
 Header,+,applications/services/cli/cli.h,,
 Header,+,applications/services/cli/cli_vcp.h,,
 Header,+,applications/services/cli/cli_vcp.h,,

+ 9 - 8
firmware/targets/f7/api_symbols.csv

@@ -1,5 +1,5 @@
 entry,status,name,type,params
 entry,status,name,type,params
-Version,+,16.0,,
+Version,+,17.0,,
 Header,+,applications/services/bt/bt_service/bt.h,,
 Header,+,applications/services/bt/bt_service/bt.h,,
 Header,+,applications/services/cli/cli.h,,
 Header,+,applications/services/cli/cli.h,,
 Header,+,applications/services/cli/cli_vcp.h,,
 Header,+,applications/services/cli/cli_vcp.h,,
@@ -2588,9 +2588,10 @@ Function,-,strupr,char*,char*
 Function,-,strverscmp,int,"const char*, const char*"
 Function,-,strverscmp,int,"const char*, const char*"
 Function,-,strxfrm,size_t,"char*, const char*, size_t"
 Function,-,strxfrm,size_t,"char*, const char*, size_t"
 Function,-,strxfrm_l,size_t,"char*, const char*, size_t, locale_t"
 Function,-,strxfrm_l,size_t,"char*, const char*, size_t, locale_t"
-Function,+,subghz_block_generic_deserialize,_Bool,"SubGhzBlockGeneric*, FlipperFormat*"
+Function,+,subghz_block_generic_deserialize,SubGhzProtocolStatus,"SubGhzBlockGeneric*, FlipperFormat*"
+Function,+,subghz_block_generic_deserialize_check_count_bit,SubGhzProtocolStatus,"SubGhzBlockGeneric*, FlipperFormat*, uint16_t"
 Function,+,subghz_block_generic_get_preset_name,void,"const char*, FuriString*"
 Function,+,subghz_block_generic_get_preset_name,void,"const char*, FuriString*"
-Function,+,subghz_block_generic_serialize,_Bool,"SubGhzBlockGeneric*, FlipperFormat*, SubGhzRadioPreset*"
+Function,+,subghz_block_generic_serialize,SubGhzProtocolStatus,"SubGhzBlockGeneric*, FlipperFormat*, SubGhzRadioPreset*"
 Function,+,subghz_environment_alloc,SubGhzEnvironment*,
 Function,+,subghz_environment_alloc,SubGhzEnvironment*,
 Function,+,subghz_environment_free,void,SubGhzEnvironment*
 Function,+,subghz_environment_free,void,SubGhzEnvironment*
 Function,+,subghz_environment_get_alutech_at_4n_rainbow_table_file_name,const char*,SubGhzEnvironment*
 Function,+,subghz_environment_get_alutech_at_4n_rainbow_table_file_name,const char*,SubGhzEnvironment*
@@ -2632,19 +2633,19 @@ 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_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_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_blocks_xor_bytes,uint8_t,"const uint8_t[], size_t"
-Function,-,subghz_protocol_decoder_base_deserialize,_Bool,"SubGhzProtocolDecoderBase*, FlipperFormat*"
+Function,+,subghz_protocol_decoder_base_deserialize,SubGhzProtocolStatus,"SubGhzProtocolDecoderBase*, FlipperFormat*"
 Function,+,subghz_protocol_decoder_base_get_hash_data,uint8_t,SubGhzProtocolDecoderBase*
 Function,+,subghz_protocol_decoder_base_get_hash_data,uint8_t,SubGhzProtocolDecoderBase*
 Function,+,subghz_protocol_decoder_base_get_string,_Bool,"SubGhzProtocolDecoderBase*, FuriString*"
 Function,+,subghz_protocol_decoder_base_get_string,_Bool,"SubGhzProtocolDecoderBase*, FuriString*"
-Function,+,subghz_protocol_decoder_base_serialize,_Bool,"SubGhzProtocolDecoderBase*, FlipperFormat*, SubGhzRadioPreset*"
+Function,+,subghz_protocol_decoder_base_serialize,SubGhzProtocolStatus,"SubGhzProtocolDecoderBase*, FlipperFormat*, SubGhzRadioPreset*"
 Function,-,subghz_protocol_decoder_base_set_decoder_callback,void,"SubGhzProtocolDecoderBase*, SubGhzProtocolDecoderBaseRxCallback, void*"
 Function,-,subghz_protocol_decoder_base_set_decoder_callback,void,"SubGhzProtocolDecoderBase*, SubGhzProtocolDecoderBaseRxCallback, void*"
 Function,+,subghz_protocol_decoder_raw_alloc,void*,SubGhzEnvironment*
 Function,+,subghz_protocol_decoder_raw_alloc,void*,SubGhzEnvironment*
-Function,+,subghz_protocol_decoder_raw_deserialize,_Bool,"void*, FlipperFormat*"
+Function,+,subghz_protocol_decoder_raw_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*"
 Function,+,subghz_protocol_decoder_raw_feed,void,"void*, _Bool, uint32_t"
 Function,+,subghz_protocol_decoder_raw_feed,void,"void*, _Bool, uint32_t"
 Function,+,subghz_protocol_decoder_raw_free,void,void*
 Function,+,subghz_protocol_decoder_raw_free,void,void*
 Function,+,subghz_protocol_decoder_raw_get_string,void,"void*, FuriString*"
 Function,+,subghz_protocol_decoder_raw_get_string,void,"void*, FuriString*"
 Function,+,subghz_protocol_decoder_raw_reset,void,void*
 Function,+,subghz_protocol_decoder_raw_reset,void,void*
 Function,+,subghz_protocol_encoder_raw_alloc,void*,SubGhzEnvironment*
 Function,+,subghz_protocol_encoder_raw_alloc,void*,SubGhzEnvironment*
-Function,+,subghz_protocol_encoder_raw_deserialize,_Bool,"void*, FlipperFormat*"
+Function,+,subghz_protocol_encoder_raw_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*"
 Function,+,subghz_protocol_encoder_raw_free,void,void*
 Function,+,subghz_protocol_encoder_raw_free,void,void*
 Function,+,subghz_protocol_encoder_raw_stop,void,void*
 Function,+,subghz_protocol_encoder_raw_stop,void,void*
 Function,+,subghz_protocol_encoder_raw_yield,LevelDuration,void*
 Function,+,subghz_protocol_encoder_raw_yield,LevelDuration,void*
@@ -2682,7 +2683,7 @@ Function,+,subghz_setting_get_preset_name,const char*,"SubGhzSetting*, size_t"
 Function,+,subghz_setting_load,void,"SubGhzSetting*, const char*"
 Function,+,subghz_setting_load,void,"SubGhzSetting*, const char*"
 Function,+,subghz_setting_load_custom_preset,_Bool,"SubGhzSetting*, const char*, FlipperFormat*"
 Function,+,subghz_setting_load_custom_preset,_Bool,"SubGhzSetting*, const char*, FlipperFormat*"
 Function,+,subghz_transmitter_alloc_init,SubGhzTransmitter*,"SubGhzEnvironment*, const char*"
 Function,+,subghz_transmitter_alloc_init,SubGhzTransmitter*,"SubGhzEnvironment*, const char*"
-Function,+,subghz_transmitter_deserialize,_Bool,"SubGhzTransmitter*, FlipperFormat*"
+Function,+,subghz_transmitter_deserialize,SubGhzProtocolStatus,"SubGhzTransmitter*, FlipperFormat*"
 Function,+,subghz_transmitter_free,void,SubGhzTransmitter*
 Function,+,subghz_transmitter_free,void,SubGhzTransmitter*
 Function,+,subghz_transmitter_get_protocol_instance,SubGhzProtocolEncoderBase*,SubGhzTransmitter*
 Function,+,subghz_transmitter_get_protocol_instance,SubGhzProtocolEncoderBase*,SubGhzTransmitter*
 Function,+,subghz_transmitter_stop,_Bool,SubGhzTransmitter*
 Function,+,subghz_transmitter_stop,_Bool,SubGhzTransmitter*

+ 37 - 6
lib/subghz/blocks/generic.c

@@ -20,12 +20,12 @@ void subghz_block_generic_get_preset_name(const char* preset_name, FuriString* p
     furi_string_set(preset_str, preset_name_temp);
     furi_string_set(preset_str, preset_name_temp);
 }
 }
 
 
-bool subghz_block_generic_serialize(
+SubGhzProtocolStatus subghz_block_generic_serialize(
     SubGhzBlockGeneric* instance,
     SubGhzBlockGeneric* instance,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
     furi_assert(instance);
     furi_assert(instance);
-    bool res = false;
+    SubGhzProtocolStatus res = SubGhzProtocolStatusError;
     FuriString* temp_str;
     FuriString* temp_str;
     temp_str = furi_string_alloc();
     temp_str = furi_string_alloc();
     do {
     do {
@@ -33,11 +33,13 @@ bool subghz_block_generic_serialize(
         if(!flipper_format_write_header_cstr(
         if(!flipper_format_write_header_cstr(
                flipper_format, SUBGHZ_KEY_FILE_TYPE, SUBGHZ_KEY_FILE_VERSION)) {
                flipper_format, SUBGHZ_KEY_FILE_TYPE, SUBGHZ_KEY_FILE_VERSION)) {
             FURI_LOG_E(TAG, "Unable to add header");
             FURI_LOG_E(TAG, "Unable to add header");
+            res = SubGhzProtocolStatusErrorParserHeader;
             break;
             break;
         }
         }
 
 
         if(!flipper_format_write_uint32(flipper_format, "Frequency", &preset->frequency, 1)) {
         if(!flipper_format_write_uint32(flipper_format, "Frequency", &preset->frequency, 1)) {
             FURI_LOG_E(TAG, "Unable to add Frequency");
             FURI_LOG_E(TAG, "Unable to add Frequency");
+            res = SubGhzProtocolStatusErrorParserFrequency;
             break;
             break;
         }
         }
 
 
@@ -45,27 +47,32 @@ bool subghz_block_generic_serialize(
         if(!flipper_format_write_string_cstr(
         if(!flipper_format_write_string_cstr(
                flipper_format, "Preset", furi_string_get_cstr(temp_str))) {
                flipper_format, "Preset", furi_string_get_cstr(temp_str))) {
             FURI_LOG_E(TAG, "Unable to add Preset");
             FURI_LOG_E(TAG, "Unable to add Preset");
+            res = SubGhzProtocolStatusErrorParserPreset;
             break;
             break;
         }
         }
         if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) {
         if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) {
             if(!flipper_format_write_string_cstr(
             if(!flipper_format_write_string_cstr(
                    flipper_format, "Custom_preset_module", "CC1101")) {
                    flipper_format, "Custom_preset_module", "CC1101")) {
                 FURI_LOG_E(TAG, "Unable to add Custom_preset_module");
                 FURI_LOG_E(TAG, "Unable to add Custom_preset_module");
+                res = SubGhzProtocolStatusErrorParserCustomPreset;
                 break;
                 break;
             }
             }
             if(!flipper_format_write_hex(
             if(!flipper_format_write_hex(
                    flipper_format, "Custom_preset_data", preset->data, preset->data_size)) {
                    flipper_format, "Custom_preset_data", preset->data, preset->data_size)) {
                 FURI_LOG_E(TAG, "Unable to add Custom_preset_data");
                 FURI_LOG_E(TAG, "Unable to add Custom_preset_data");
+                res = SubGhzProtocolStatusErrorParserCustomPreset;
                 break;
                 break;
             }
             }
         }
         }
         if(!flipper_format_write_string_cstr(flipper_format, "Protocol", instance->protocol_name)) {
         if(!flipper_format_write_string_cstr(flipper_format, "Protocol", instance->protocol_name)) {
             FURI_LOG_E(TAG, "Unable to add Protocol");
             FURI_LOG_E(TAG, "Unable to add Protocol");
+            res = SubGhzProtocolStatusErrorParserProtocolName;
             break;
             break;
         }
         }
         uint32_t temp = instance->data_count_bit;
         uint32_t temp = instance->data_count_bit;
         if(!flipper_format_write_uint32(flipper_format, "Bit", &temp, 1)) {
         if(!flipper_format_write_uint32(flipper_format, "Bit", &temp, 1)) {
             FURI_LOG_E(TAG, "Unable to add Bit");
             FURI_LOG_E(TAG, "Unable to add Bit");
+            res = SubGhzProtocolStatusErrorParserBitCount;
             break;
             break;
         }
         }
 
 
@@ -76,17 +83,19 @@ bool subghz_block_generic_serialize(
 
 
         if(!flipper_format_write_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) {
         if(!flipper_format_write_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) {
             FURI_LOG_E(TAG, "Unable to add Key");
             FURI_LOG_E(TAG, "Unable to add Key");
+            res = SubGhzProtocolStatusErrorParserKey;
             break;
             break;
         }
         }
-        res = true;
+        res = SubGhzProtocolStatusOk;
     } while(false);
     } while(false);
     furi_string_free(temp_str);
     furi_string_free(temp_str);
     return res;
     return res;
 }
 }
 
 
-bool subghz_block_generic_deserialize(SubGhzBlockGeneric* instance, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_block_generic_deserialize(SubGhzBlockGeneric* instance, FlipperFormat* flipper_format) {
     furi_assert(instance);
     furi_assert(instance);
-    bool res = false;
+    SubGhzProtocolStatus res = SubGhzProtocolStatusError;
     FuriString* temp_str;
     FuriString* temp_str;
     temp_str = furi_string_alloc();
     temp_str = furi_string_alloc();
     uint32_t temp_data = 0;
     uint32_t temp_data = 0;
@@ -94,10 +103,12 @@ bool subghz_block_generic_deserialize(SubGhzBlockGeneric* instance, FlipperForma
     do {
     do {
         if(!flipper_format_rewind(flipper_format)) {
         if(!flipper_format_rewind(flipper_format)) {
             FURI_LOG_E(TAG, "Rewind error");
             FURI_LOG_E(TAG, "Rewind error");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         if(!flipper_format_read_uint32(flipper_format, "Bit", (uint32_t*)&temp_data, 1)) {
         if(!flipper_format_read_uint32(flipper_format, "Bit", (uint32_t*)&temp_data, 1)) {
             FURI_LOG_E(TAG, "Missing Bit");
             FURI_LOG_E(TAG, "Missing Bit");
+            res = SubGhzProtocolStatusErrorParserBitCount;
             break;
             break;
         }
         }
         instance->data_count_bit = (uint16_t)temp_data;
         instance->data_count_bit = (uint16_t)temp_data;
@@ -105,16 +116,36 @@ bool subghz_block_generic_deserialize(SubGhzBlockGeneric* instance, FlipperForma
         uint8_t key_data[sizeof(uint64_t)] = {0};
         uint8_t key_data[sizeof(uint64_t)] = {0};
         if(!flipper_format_read_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) {
         if(!flipper_format_read_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) {
             FURI_LOG_E(TAG, "Missing Key");
             FURI_LOG_E(TAG, "Missing Key");
+            res = SubGhzProtocolStatusErrorParserKey;
             break;
             break;
         }
         }
         for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
         for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
             instance->data = instance->data << 8 | key_data[i];
             instance->data = instance->data << 8 | key_data[i];
         }
         }
 
 
-        res = true;
+        res = SubGhzProtocolStatusOk;
     } while(0);
     } while(0);
 
 
     furi_string_free(temp_str);
     furi_string_free(temp_str);
 
 
     return res;
     return res;
 }
 }
+
+SubGhzProtocolStatus subghz_block_generic_deserialize_check_count_bit(
+    SubGhzBlockGeneric* instance,
+    FlipperFormat* flipper_format,
+    uint16_t count_bit) {
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
+    do {
+        ret = subghz_block_generic_deserialize(instance, flipper_format);
+        if(ret != SubGhzProtocolStatusOk) {
+            break;
+        }
+        if(instance->data_count_bit != count_bit) {
+            FURI_LOG_E(TAG, "Wrong number of bits in key");
+            ret = SubGhzProtocolStatusErrorValueBitCount;
+            break;
+        }
+    } while(false);
+    return ret;
+}

+ 17 - 4
lib/subghz/blocks/generic.h

@@ -36,9 +36,9 @@ void subghz_block_generic_get_preset_name(const char* preset_name, FuriString* p
  * @param instance Pointer to a SubGhzBlockGeneric instance
  * @param instance Pointer to a SubGhzBlockGeneric instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return Status Error
  */
  */
-bool subghz_block_generic_serialize(
+SubGhzProtocolStatus subghz_block_generic_serialize(
     SubGhzBlockGeneric* instance,
     SubGhzBlockGeneric* instance,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -47,9 +47,22 @@ bool subghz_block_generic_serialize(
  * Deserialize data SubGhzBlockGeneric.
  * Deserialize data SubGhzBlockGeneric.
  * @param instance Pointer to a SubGhzBlockGeneric instance
  * @param instance Pointer to a SubGhzBlockGeneric instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return Status Error
  */
  */
-bool subghz_block_generic_deserialize(SubGhzBlockGeneric* instance, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_block_generic_deserialize(SubGhzBlockGeneric* instance, FlipperFormat* flipper_format);
+
+/**
+ * Deserialize data SubGhzBlockGeneric.
+ * @param instance Pointer to a SubGhzBlockGeneric instance
+ * @param flipper_format Pointer to a FlipperFormat instance
+ * @param count_bit Count bit protocol
+ * @return Status Error
+ */
+SubGhzProtocolStatus subghz_block_generic_deserialize_check_count_bit(
+    SubGhzBlockGeneric* instance,
+    FlipperFormat* flipper_format,
+    uint16_t count_bit);
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }

+ 15 - 15
lib/subghz/protocols/alutech_at_4n.c

@@ -385,46 +385,46 @@ uint8_t subghz_protocol_decoder_alutech_at_4n_get_hash_data(void* context) {
     return (uint8_t)instance->crc;
     return (uint8_t)instance->crc;
 }
 }
 
 
-bool subghz_protocol_decoder_alutech_at_4n_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_alutech_at_4n_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderAlutech_at_4n* instance = context;
     SubGhzProtocolDecoderAlutech_at_4n* instance = context;
-    bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
-    if(res && !flipper_format_write_uint32(flipper_format, "CRC", &instance->crc, 1)) {
+    SubGhzProtocolStatus res =
+        subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
+    if((res == SubGhzProtocolStatusOk) &&
+       !flipper_format_write_uint32(flipper_format, "CRC", &instance->crc, 1)) {
         FURI_LOG_E(TAG, "Unable to add CRC");
         FURI_LOG_E(TAG, "Unable to add CRC");
-        res = false;
+        res = SubGhzProtocolStatusErrorParserOthers;
     }
     }
     return res;
     return res;
-
-    return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_alutech_at_4n_deserialize(
+SubGhzProtocolStatus subghz_protocol_decoder_alutech_at_4n_deserialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format) {
     FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderAlutech_at_4n* instance = context;
     SubGhzProtocolDecoderAlutech_at_4n* instance = context;
-    bool ret = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_alutech_at_4n_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        ret = subghz_block_generic_deserialize_check_count_bit(
+            &instance->generic,
+            flipper_format,
+            subghz_protocol_alutech_at_4n_const.min_count_bit_for_found);
+        if(ret != SubGhzProtocolStatusOk) {
             break;
             break;
         }
         }
         if(!flipper_format_rewind(flipper_format)) {
         if(!flipper_format_rewind(flipper_format)) {
             FURI_LOG_E(TAG, "Rewind error");
             FURI_LOG_E(TAG, "Rewind error");
+            ret = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         if(!flipper_format_read_uint32(flipper_format, "CRC", (uint32_t*)&instance->crc, 1)) {
         if(!flipper_format_read_uint32(flipper_format, "CRC", (uint32_t*)&instance->crc, 1)) {
             FURI_LOG_E(TAG, "Missing CRC");
             FURI_LOG_E(TAG, "Missing CRC");
+            ret = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
-        ret = true;
     } while(false);
     } while(false);
     return ret;
     return ret;
 }
 }

+ 5 - 6
lib/subghz/protocols/alutech_at_4n.h

@@ -49,9 +49,9 @@ uint8_t subghz_protocol_decoder_alutech_at_4n_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance
  * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_alutech_at_4n_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_alutech_at_4n_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -60,11 +60,10 @@ bool subghz_protocol_decoder_alutech_at_4n_serialize(
  * Deserialize data SubGhzProtocolDecoderAlutech_at_4n.
  * Deserialize data SubGhzProtocolDecoderAlutech_at_4n.
  * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance
  * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_alutech_at_4n_deserialize(
-    void* context,
-    FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_alutech_at_4n_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 17 - 26
lib/subghz/protocols/ansonic.c

@@ -136,28 +136,29 @@ static bool subghz_protocol_encoder_ansonic_get_upload(SubGhzProtocolEncoderAnso
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_ansonic_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_ansonic_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderAnsonic* instance = context;
     SubGhzProtocolEncoderAnsonic* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus res = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
+        res = subghz_block_generic_deserialize_check_count_bit(
+            &instance->generic,
+            flipper_format,
+            subghz_protocol_ansonic_const.min_count_bit_for_found);
+        if(res != SubGhzProtocolStatusOk) {
             FURI_LOG_E(TAG, "Deserialize error");
             FURI_LOG_E(TAG, "Deserialize error");
             break;
             break;
         }
         }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_ansonic_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_ansonic_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_ansonic_get_upload(instance)) {
+            res = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
     return res;
     return res;
@@ -301,7 +302,7 @@ uint8_t subghz_protocol_decoder_ansonic_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_ansonic_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_ansonic_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -310,22 +311,12 @@ bool subghz_protocol_decoder_ansonic_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_ansonic_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_ansonic_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderAnsonic* instance = context;
     SubGhzProtocolDecoderAnsonic* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_ansonic_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, subghz_protocol_ansonic_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_ansonic_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_ansonic_get_string(void* context, FuriString* output) {

+ 5 - 3
lib/subghz/protocols/ansonic.h

@@ -30,7 +30,8 @@ void subghz_protocol_encoder_ansonic_free(void* context);
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @return true On success
  * @return true On success
  */
  */
-bool subghz_protocol_encoder_ansonic_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_ansonic_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -86,7 +87,7 @@ uint8_t subghz_protocol_decoder_ansonic_get_hash_data(void* context);
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @return true On success
  * @return true On success
  */
  */
-bool subghz_protocol_decoder_ansonic_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_ansonic_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -97,7 +98,8 @@ bool subghz_protocol_decoder_ansonic_serialize(
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @return true On success
  * @return true On success
  */
  */
-bool subghz_protocol_decoder_ansonic_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_ansonic_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 4 - 4
lib/subghz/protocols/base.c

@@ -23,11 +23,11 @@ bool subghz_protocol_decoder_base_get_string(
     return status;
     return status;
 }
 }
 
 
-bool subghz_protocol_decoder_base_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_base_serialize(
     SubGhzProtocolDecoderBase* decoder_base,
     SubGhzProtocolDecoderBase* decoder_base,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
-    bool status = false;
+    SubGhzProtocolStatus status = SubGhzProtocolStatusError;
 
 
     if(decoder_base->protocol && decoder_base->protocol->decoder &&
     if(decoder_base->protocol && decoder_base->protocol->decoder &&
        decoder_base->protocol->decoder->serialize) {
        decoder_base->protocol->decoder->serialize) {
@@ -37,10 +37,10 @@ bool subghz_protocol_decoder_base_serialize(
     return status;
     return status;
 }
 }
 
 
-bool subghz_protocol_decoder_base_deserialize(
+SubGhzProtocolStatus subghz_protocol_decoder_base_deserialize(
     SubGhzProtocolDecoderBase* decoder_base,
     SubGhzProtocolDecoderBase* decoder_base,
     FlipperFormat* flipper_format) {
     FlipperFormat* flipper_format) {
-    bool status = false;
+    SubGhzProtocolStatus status = SubGhzProtocolStatusError;
 
 
     if(decoder_base->protocol && decoder_base->protocol->decoder &&
     if(decoder_base->protocol && decoder_base->protocol->decoder &&
        decoder_base->protocol->decoder->deserialize) {
        decoder_base->protocol->decoder->deserialize) {

+ 4 - 4
lib/subghz/protocols/base.h

@@ -49,9 +49,9 @@ bool subghz_protocol_decoder_base_get_string(
  * @param decoder_base Pointer to a SubGhzProtocolDecoderBase instance
  * @param decoder_base Pointer to a SubGhzProtocolDecoderBase instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return Status Error
  */
  */
-bool subghz_protocol_decoder_base_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_base_serialize(
     SubGhzProtocolDecoderBase* decoder_base,
     SubGhzProtocolDecoderBase* decoder_base,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -60,9 +60,9 @@ bool subghz_protocol_decoder_base_serialize(
  * Deserialize data SubGhzProtocolDecoderBase.
  * Deserialize data SubGhzProtocolDecoderBase.
  * @param decoder_base Pointer to a SubGhzProtocolDecoderBase instance
  * @param decoder_base Pointer to a SubGhzProtocolDecoderBase instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return Status Error
  */
  */
-bool subghz_protocol_decoder_base_deserialize(
+SubGhzProtocolStatus subghz_protocol_decoder_base_deserialize(
     SubGhzProtocolDecoderBase* decoder_base,
     SubGhzProtocolDecoderBase* decoder_base,
     FlipperFormat* flipper_format);
     FlipperFormat* flipper_format);
 
 

+ 18 - 27
lib/subghz/protocols/bett.c

@@ -155,31 +155,32 @@ static bool subghz_protocol_encoder_bett_get_upload(SubGhzProtocolEncoderBETT* i
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_bett_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_bett_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderBETT* instance = context;
     SubGhzProtocolEncoderBETT* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
+        ret = subghz_block_generic_deserialize_check_count_bit(
+            &instance->generic,
+            flipper_format,
+            subghz_protocol_bett_const.min_count_bit_for_found);
+        if(ret != SubGhzProtocolStatusOk) {
             FURI_LOG_E(TAG, "Deserialize error");
             FURI_LOG_E(TAG, "Deserialize error");
             break;
             break;
         }
         }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_bett_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_bett_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_bett_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_bett_stop(void* context) {
 void subghz_protocol_encoder_bett_stop(void* context) {
@@ -295,7 +296,7 @@ uint8_t subghz_protocol_decoder_bett_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_bett_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_bett_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -304,22 +305,12 @@ bool subghz_protocol_decoder_bett_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_bett_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_bett_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderBETT* instance = context;
     SubGhzProtocolDecoderBETT* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_bett_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, subghz_protocol_bett_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_bett_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_bett_get_string(void* context, FuriString* output) {

+ 8 - 6
lib/subghz/protocols/bett.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_bett_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderBETT instance
  * @param context Pointer to a SubGhzProtocolEncoderBETT instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_bett_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_bett_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -84,9 +85,9 @@ uint8_t subghz_protocol_decoder_bett_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderBETT instance
  * @param context Pointer to a SubGhzProtocolDecoderBETT instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_bett_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_bett_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -95,9 +96,10 @@ bool subghz_protocol_decoder_bett_serialize(
  * Deserialize data SubGhzProtocolDecoderBETT.
  * Deserialize data SubGhzProtocolDecoderBETT.
  * @param context Pointer to a SubGhzProtocolDecoderBETT instance
  * @param context Pointer to a SubGhzProtocolDecoderBETT instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_bett_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_bett_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 38 - 10
lib/subghz/protocols/bin_raw.c

@@ -219,20 +219,23 @@ static bool subghz_protocol_encoder_bin_raw_get_upload(SubGhzProtocolEncoderBinR
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderBinRAW* instance = context;
     SubGhzProtocolEncoderBinRAW* instance = context;
 
 
-    bool res = false;
+    SubGhzProtocolStatus res = SubGhzProtocolStatusError;
     uint32_t temp_data = 0;
     uint32_t temp_data = 0;
 
 
     do {
     do {
         if(!flipper_format_rewind(flipper_format)) {
         if(!flipper_format_rewind(flipper_format)) {
             FURI_LOG_E(TAG, "Rewind error");
             FURI_LOG_E(TAG, "Rewind error");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         if(!flipper_format_read_uint32(flipper_format, "Bit", (uint32_t*)&temp_data, 1)) {
         if(!flipper_format_read_uint32(flipper_format, "Bit", (uint32_t*)&temp_data, 1)) {
             FURI_LOG_E(TAG, "Missing Bit");
             FURI_LOG_E(TAG, "Missing Bit");
+            res = SubGhzProtocolStatusErrorParserBitCount;
             break;
             break;
         }
         }
 
 
@@ -240,6 +243,7 @@ bool subghz_protocol_encoder_bin_raw_deserialize(void* context, FlipperFormat* f
 
 
         if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) {
         if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) {
             FURI_LOG_E(TAG, "Missing TE");
             FURI_LOG_E(TAG, "Missing TE");
+            res = SubGhzProtocolStatusErrorParserTe;
             break;
             break;
         }
         }
 
 
@@ -251,11 +255,13 @@ bool subghz_protocol_encoder_bin_raw_deserialize(void* context, FlipperFormat* f
         while(flipper_format_read_uint32(flipper_format, "Bit_RAW", (uint32_t*)&temp_data, 1)) {
         while(flipper_format_read_uint32(flipper_format, "Bit_RAW", (uint32_t*)&temp_data, 1)) {
             if(ind >= BIN_RAW_MAX_MARKUP_COUNT) {
             if(ind >= BIN_RAW_MAX_MARKUP_COUNT) {
                 FURI_LOG_E(TAG, "Markup overflow");
                 FURI_LOG_E(TAG, "Markup overflow");
+                res = SubGhzProtocolStatusErrorParserOthers;
                 break;
                 break;
             }
             }
             byte_count += subghz_protocol_bin_raw_get_full_byte(temp_data);
             byte_count += subghz_protocol_bin_raw_get_full_byte(temp_data);
             if(byte_count > BIN_RAW_BUF_DATA_SIZE) {
             if(byte_count > BIN_RAW_BUF_DATA_SIZE) {
                 FURI_LOG_E(TAG, "Receive buffer overflow");
                 FURI_LOG_E(TAG, "Receive buffer overflow");
+                res = SubGhzProtocolStatusErrorParserOthers;
                 break;
                 break;
             }
             }
 
 
@@ -270,6 +276,7 @@ bool subghz_protocol_encoder_bin_raw_deserialize(void* context, FlipperFormat* f
                    subghz_protocol_bin_raw_get_full_byte(temp_data))) {
                    subghz_protocol_bin_raw_get_full_byte(temp_data))) {
                 instance->data_markup[ind].bit_count = 0;
                 instance->data_markup[ind].bit_count = 0;
                 FURI_LOG_E(TAG, "Missing Data_RAW");
                 FURI_LOG_E(TAG, "Missing Data_RAW");
+                res = SubGhzProtocolStatusErrorParserOthers;
                 break;
                 break;
             }
             }
             ind++;
             ind++;
@@ -297,16 +304,20 @@ bool subghz_protocol_encoder_bin_raw_deserialize(void* context, FlipperFormat* f
 #endif
 #endif
         if(!flipper_format_rewind(flipper_format)) {
         if(!flipper_format_rewind(flipper_format)) {
             FURI_LOG_E(TAG, "Rewind error");
             FURI_LOG_E(TAG, "Rewind error");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_bin_raw_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_bin_raw_get_upload(instance)) {
+            break;
+            res = SubGhzProtocolStatusErrorEncoderGetUpload;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
 
 
-        res = true;
+        res = SubGhzProtocolStatusOk;
     } while(0);
     } while(0);
 
 
     return res;
     return res;
@@ -957,14 +968,14 @@ uint8_t subghz_protocol_decoder_bin_raw_get_hash_data(void* context) {
         subghz_protocol_bin_raw_get_full_byte(instance->data_markup[0].bit_count));
         subghz_protocol_bin_raw_get_full_byte(instance->data_markup[0].bit_count));
 }
 }
 
 
-bool subghz_protocol_decoder_bin_raw_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_bin_raw_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderBinRAW* instance = context;
     SubGhzProtocolDecoderBinRAW* instance = context;
 
 
-    bool res = false;
+    SubGhzProtocolStatus res = SubGhzProtocolStatusError;
     FuriString* temp_str;
     FuriString* temp_str;
     temp_str = furi_string_alloc();
     temp_str = furi_string_alloc();
     do {
     do {
@@ -972,11 +983,13 @@ bool subghz_protocol_decoder_bin_raw_serialize(
         if(!flipper_format_write_header_cstr(
         if(!flipper_format_write_header_cstr(
                flipper_format, SUBGHZ_KEY_FILE_TYPE, SUBGHZ_KEY_FILE_VERSION)) {
                flipper_format, SUBGHZ_KEY_FILE_TYPE, SUBGHZ_KEY_FILE_VERSION)) {
             FURI_LOG_E(TAG, "Unable to add header");
             FURI_LOG_E(TAG, "Unable to add header");
+            res = SubGhzProtocolStatusErrorParserHeader;
             break;
             break;
         }
         }
 
 
         if(!flipper_format_write_uint32(flipper_format, "Frequency", &preset->frequency, 1)) {
         if(!flipper_format_write_uint32(flipper_format, "Frequency", &preset->frequency, 1)) {
             FURI_LOG_E(TAG, "Unable to add Frequency");
             FURI_LOG_E(TAG, "Unable to add Frequency");
+            res = SubGhzProtocolStatusErrorParserFrequency;
             break;
             break;
         }
         }
 
 
@@ -984,34 +997,40 @@ bool subghz_protocol_decoder_bin_raw_serialize(
         if(!flipper_format_write_string_cstr(
         if(!flipper_format_write_string_cstr(
                flipper_format, "Preset", furi_string_get_cstr(temp_str))) {
                flipper_format, "Preset", furi_string_get_cstr(temp_str))) {
             FURI_LOG_E(TAG, "Unable to add Preset");
             FURI_LOG_E(TAG, "Unable to add Preset");
+            res = SubGhzProtocolStatusErrorParserPreset;
             break;
             break;
         }
         }
         if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) {
         if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) {
             if(!flipper_format_write_string_cstr(
             if(!flipper_format_write_string_cstr(
                    flipper_format, "Custom_preset_module", "CC1101")) {
                    flipper_format, "Custom_preset_module", "CC1101")) {
                 FURI_LOG_E(TAG, "Unable to add Custom_preset_module");
                 FURI_LOG_E(TAG, "Unable to add Custom_preset_module");
+                res = SubGhzProtocolStatusErrorParserCustomPreset;
                 break;
                 break;
             }
             }
             if(!flipper_format_write_hex(
             if(!flipper_format_write_hex(
                    flipper_format, "Custom_preset_data", preset->data, preset->data_size)) {
                    flipper_format, "Custom_preset_data", preset->data, preset->data_size)) {
                 FURI_LOG_E(TAG, "Unable to add Custom_preset_data");
                 FURI_LOG_E(TAG, "Unable to add Custom_preset_data");
+                res = SubGhzProtocolStatusErrorParserCustomPreset;
                 break;
                 break;
             }
             }
         }
         }
         if(!flipper_format_write_string_cstr(
         if(!flipper_format_write_string_cstr(
                flipper_format, "Protocol", instance->generic.protocol_name)) {
                flipper_format, "Protocol", instance->generic.protocol_name)) {
             FURI_LOG_E(TAG, "Unable to add Protocol");
             FURI_LOG_E(TAG, "Unable to add Protocol");
+            res = SubGhzProtocolStatusErrorParserProtocolName;
             break;
             break;
         }
         }
 
 
         uint32_t temp = instance->generic.data_count_bit;
         uint32_t temp = instance->generic.data_count_bit;
         if(!flipper_format_write_uint32(flipper_format, "Bit", &temp, 1)) {
         if(!flipper_format_write_uint32(flipper_format, "Bit", &temp, 1)) {
             FURI_LOG_E(TAG, "Unable to add Bit");
             FURI_LOG_E(TAG, "Unable to add Bit");
+            res = SubGhzProtocolStatusErrorParserBitCount;
             break;
             break;
         }
         }
 
 
         if(!flipper_format_write_uint32(flipper_format, "TE", &instance->te, 1)) {
         if(!flipper_format_write_uint32(flipper_format, "TE", &instance->te, 1)) {
             FURI_LOG_E(TAG, "Unable to add TE");
             FURI_LOG_E(TAG, "Unable to add TE");
+            res = SubGhzProtocolStatusErrorParserTe;
             break;
             break;
         }
         }
 
 
@@ -1020,6 +1039,7 @@ bool subghz_protocol_decoder_bin_raw_serialize(
             temp = instance->data_markup[i].bit_count;
             temp = instance->data_markup[i].bit_count;
             if(!flipper_format_write_uint32(flipper_format, "Bit_RAW", &temp, 1)) {
             if(!flipper_format_write_uint32(flipper_format, "Bit_RAW", &temp, 1)) {
                 FURI_LOG_E(TAG, "Bit_RAW");
                 FURI_LOG_E(TAG, "Bit_RAW");
+                res = SubGhzProtocolStatusErrorParserOthers;
                 break;
                 break;
             }
             }
             if(!flipper_format_write_hex(
             if(!flipper_format_write_hex(
@@ -1028,31 +1048,35 @@ bool subghz_protocol_decoder_bin_raw_serialize(
                    instance->data + instance->data_markup[i].byte_bias,
                    instance->data + instance->data_markup[i].byte_bias,
                    subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count))) {
                    subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count))) {
                 FURI_LOG_E(TAG, "Unable to add Data_RAW");
                 FURI_LOG_E(TAG, "Unable to add Data_RAW");
+                res = SubGhzProtocolStatusErrorParserOthers;
                 break;
                 break;
             }
             }
             i++;
             i++;
         }
         }
 
 
-        res = true;
+        res = SubGhzProtocolStatusOk;
     } while(false);
     } while(false);
     furi_string_free(temp_str);
     furi_string_free(temp_str);
     return res;
     return res;
 }
 }
 
 
-bool subghz_protocol_decoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderBinRAW* instance = context;
     SubGhzProtocolDecoderBinRAW* instance = context;
 
 
-    bool res = false;
+    SubGhzProtocolStatus res = SubGhzProtocolStatusError;
     uint32_t temp_data = 0;
     uint32_t temp_data = 0;
 
 
     do {
     do {
         if(!flipper_format_rewind(flipper_format)) {
         if(!flipper_format_rewind(flipper_format)) {
             FURI_LOG_E(TAG, "Rewind error");
             FURI_LOG_E(TAG, "Rewind error");
+            res = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         if(!flipper_format_read_uint32(flipper_format, "Bit", (uint32_t*)&temp_data, 1)) {
         if(!flipper_format_read_uint32(flipper_format, "Bit", (uint32_t*)&temp_data, 1)) {
             FURI_LOG_E(TAG, "Missing Bit");
             FURI_LOG_E(TAG, "Missing Bit");
+            res = SubGhzProtocolStatusErrorParserBitCount;
             break;
             break;
         }
         }
 
 
@@ -1060,6 +1084,7 @@ bool subghz_protocol_decoder_bin_raw_deserialize(void* context, FlipperFormat* f
 
 
         if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) {
         if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) {
             FURI_LOG_E(TAG, "Missing TE");
             FURI_LOG_E(TAG, "Missing TE");
+            res = SubGhzProtocolStatusErrorParserTe;
             break;
             break;
         }
         }
 
 
@@ -1071,11 +1096,13 @@ bool subghz_protocol_decoder_bin_raw_deserialize(void* context, FlipperFormat* f
         while(flipper_format_read_uint32(flipper_format, "Bit_RAW", (uint32_t*)&temp_data, 1)) {
         while(flipper_format_read_uint32(flipper_format, "Bit_RAW", (uint32_t*)&temp_data, 1)) {
             if(ind >= BIN_RAW_MAX_MARKUP_COUNT) {
             if(ind >= BIN_RAW_MAX_MARKUP_COUNT) {
                 FURI_LOG_E(TAG, "Markup overflow");
                 FURI_LOG_E(TAG, "Markup overflow");
+                res = SubGhzProtocolStatusErrorParserOthers;
                 break;
                 break;
             }
             }
             byte_count += subghz_protocol_bin_raw_get_full_byte(temp_data);
             byte_count += subghz_protocol_bin_raw_get_full_byte(temp_data);
             if(byte_count > BIN_RAW_BUF_DATA_SIZE) {
             if(byte_count > BIN_RAW_BUF_DATA_SIZE) {
                 FURI_LOG_E(TAG, "Receive buffer overflow");
                 FURI_LOG_E(TAG, "Receive buffer overflow");
+                res = SubGhzProtocolStatusErrorParserOthers;
                 break;
                 break;
             }
             }
 
 
@@ -1090,12 +1117,13 @@ bool subghz_protocol_decoder_bin_raw_deserialize(void* context, FlipperFormat* f
                    subghz_protocol_bin_raw_get_full_byte(temp_data))) {
                    subghz_protocol_bin_raw_get_full_byte(temp_data))) {
                 instance->data_markup[ind].bit_count = 0;
                 instance->data_markup[ind].bit_count = 0;
                 FURI_LOG_E(TAG, "Missing Data_RAW");
                 FURI_LOG_E(TAG, "Missing Data_RAW");
+                res = SubGhzProtocolStatusErrorParserOthers;
                 break;
                 break;
             }
             }
             ind++;
             ind++;
         }
         }
 
 
-        res = true;
+        res = SubGhzProtocolStatusOk;
     } while(0);
     } while(0);
 
 
     return res;
     return res;

+ 8 - 6
lib/subghz/protocols/bin_raw.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_bin_raw_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderBinRAW instance
  * @param context Pointer to a SubGhzProtocolEncoderBinRAW instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -88,9 +89,9 @@ void subghz_protocol_decoder_bin_raw_data_input_rssi(
  * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance
  * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_bin_raw_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_bin_raw_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -99,9 +100,10 @@ bool subghz_protocol_decoder_bin_raw_serialize(
  * Deserialize data SubGhzProtocolDecoderBinRAW.
  * Deserialize data SubGhzProtocolDecoderBinRAW.
  * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance
  * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 47 - 22
lib/subghz/protocols/came.c

@@ -13,6 +13,7 @@
  */
  */
 
 
 #define TAG "SubGhzProtocolCAME"
 #define TAG "SubGhzProtocolCAME"
+#define CAME_12_COUNT_BIT 12
 #define CAME_24_COUNT_BIT 24
 #define CAME_24_COUNT_BIT 24
 #define PRASTEL_COUNT_BIT 25
 #define PRASTEL_COUNT_BIT 25
 #define PRASTEL_NAME "Prastel"
 #define PRASTEL_NAME "Prastel"
@@ -108,6 +109,7 @@ void subghz_protocol_encoder_came_free(void* context) {
  */
  */
 static bool subghz_protocol_encoder_came_get_upload(SubGhzProtocolEncoderCame* instance) {
 static bool subghz_protocol_encoder_came_get_upload(SubGhzProtocolEncoderCame* instance) {
     furi_assert(instance);
     furi_assert(instance);
+    uint32_t header_te = 0;
     size_t index = 0;
     size_t index = 0;
     size_t size_upload = (instance->generic.data_count_bit * 2) + 2;
     size_t size_upload = (instance->generic.data_count_bit * 2) + 2;
     if(size_upload > instance->encoder.size_upload) {
     if(size_upload > instance->encoder.size_upload) {
@@ -117,13 +119,28 @@ static bool subghz_protocol_encoder_came_get_upload(SubGhzProtocolEncoderCame* i
         instance->encoder.size_upload = size_upload;
         instance->encoder.size_upload = size_upload;
     }
     }
     //Send header
     //Send header
-    instance->encoder.upload[index++] = level_duration_make(
-        false,
-        (((instance->generic.data_count_bit == CAME_24_COUNT_BIT) ||
-          (instance->generic.data_count_bit ==
-           subghz_protocol_came_const.min_count_bit_for_found)) ?
-             (uint32_t)subghz_protocol_came_const.te_short * 76 :
-             (uint32_t)subghz_protocol_came_const.te_short * 39));
+
+    switch(instance->generic.data_count_bit) {
+    case CAME_24_COUNT_BIT:
+        // CAME 24 Bit = 24320 us
+        header_te = 76;
+        break;
+    case CAME_12_COUNT_BIT:
+    case AIRFORCE_COUNT_BIT:
+        // CAME 12 Bit Original only! and Airforce protocol = 15040 us
+        header_te = 47;
+        break;
+    case PRASTEL_COUNT_BIT:
+        // PRASTEL = 11520 us
+        header_te = 36;
+        break;
+    default:
+        // Some wrong detected protocols, 5120 us
+        header_te = 16;
+        break;
+    }
+    instance->encoder.upload[index++] =
+        level_duration_make(false, (uint32_t)subghz_protocol_came_const.te_short * header_te);
     //Send start bit
     //Send start bit
     instance->encoder.upload[index++] =
     instance->encoder.upload[index++] =
         level_duration_make(true, (uint32_t)subghz_protocol_came_const.te_short);
         level_duration_make(true, (uint32_t)subghz_protocol_came_const.te_short);
@@ -146,30 +163,33 @@ static bool subghz_protocol_encoder_came_get_upload(SubGhzProtocolEncoderCame* i
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_came_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_came_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderCame* instance = context;
     SubGhzProtocolEncoderCame* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
+        ret = subghz_block_generic_deserialize(&instance->generic, flipper_format);
+        if(ret != SubGhzProtocolStatusOk) {
             break;
             break;
         }
         }
         if((instance->generic.data_count_bit > PRASTEL_COUNT_BIT)) {
         if((instance->generic.data_count_bit > PRASTEL_COUNT_BIT)) {
             FURI_LOG_E(TAG, "Wrong number of bits in key");
             FURI_LOG_E(TAG, "Wrong number of bits in key");
+            ret = SubGhzProtocolStatusErrorValueBitCount;
             break;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_came_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_came_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_came_stop(void* context) {
 void subghz_protocol_encoder_came_stop(void* context) {
@@ -244,8 +264,11 @@ void subghz_protocol_decoder_came_feed(void* context, bool level, uint32_t durat
         if(!level) { //save interval
         if(!level) { //save interval
             if(duration >= (subghz_protocol_came_const.te_short * 4)) {
             if(duration >= (subghz_protocol_came_const.te_short * 4)) {
                 instance->decoder.parser_step = CameDecoderStepFoundStartBit;
                 instance->decoder.parser_step = CameDecoderStepFoundStartBit;
-                if(instance->decoder.decode_count_bit >=
-                   subghz_protocol_came_const.min_count_bit_for_found) {
+                if((instance->decoder.decode_count_bit ==
+                    subghz_protocol_came_const.min_count_bit_for_found) ||
+                   (instance->decoder.decode_count_bit == AIRFORCE_COUNT_BIT) ||
+                   (instance->decoder.decode_count_bit == PRASTEL_COUNT_BIT) ||
+                   (instance->decoder.decode_count_bit == CAME_24_COUNT_BIT)) {
                     instance->generic.serial = 0x0;
                     instance->generic.serial = 0x0;
                     instance->generic.btn = 0x0;
                     instance->generic.btn = 0x0;
 
 
@@ -294,7 +317,7 @@ uint8_t subghz_protocol_decoder_came_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_came_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_came_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -303,19 +326,21 @@ bool subghz_protocol_decoder_came_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_came_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_came_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderCame* instance = context;
     SubGhzProtocolDecoderCame* instance = context;
-    bool ret = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
+        ret = subghz_block_generic_deserialize(&instance->generic, flipper_format);
+        if(ret != SubGhzProtocolStatusOk) {
             break;
             break;
         }
         }
         if((instance->generic.data_count_bit > PRASTEL_COUNT_BIT)) {
         if((instance->generic.data_count_bit > PRASTEL_COUNT_BIT)) {
             FURI_LOG_E(TAG, "Wrong number of bits in key");
             FURI_LOG_E(TAG, "Wrong number of bits in key");
+            ret = SubGhzProtocolStatusErrorValueBitCount;
             break;
             break;
         }
         }
-        ret = true;
     } while(false);
     } while(false);
     return ret;
     return ret;
 }
 }

+ 8 - 6
lib/subghz/protocols/came.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_came_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderCame instance
  * @param context Pointer to a SubGhzProtocolEncoderCame instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_came_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_came_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -84,9 +85,9 @@ uint8_t subghz_protocol_decoder_came_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderCame instance
  * @param context Pointer to a SubGhzProtocolDecoderCame instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_came_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_came_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -95,9 +96,10 @@ bool subghz_protocol_decoder_came_serialize(
  * Deserialize data SubGhzProtocolDecoderCame.
  * Deserialize data SubGhzProtocolDecoderCame.
  * @param context Pointer to a SubGhzProtocolDecoderCame instance
  * @param context Pointer to a SubGhzProtocolDecoderCame instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_came_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_came_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 7 - 15
lib/subghz/protocols/came_atomo.c

@@ -298,7 +298,7 @@ uint8_t subghz_protocol_decoder_came_atomo_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_came_atomo_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_came_atomo_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -307,22 +307,14 @@ bool subghz_protocol_decoder_came_atomo_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_came_atomo_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_came_atomo_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderCameAtomo* instance = context;
     SubGhzProtocolDecoderCameAtomo* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_came_atomo_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        subghz_protocol_came_atomo_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_came_atomo_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_came_atomo_get_string(void* context, FuriString* output) {

+ 5 - 4
lib/subghz/protocols/came_atomo.h

@@ -49,9 +49,9 @@ uint8_t subghz_protocol_decoder_came_atomo_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderCameAtomo instance
  * @param context Pointer to a SubGhzProtocolDecoderCameAtomo instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_came_atomo_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_came_atomo_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -60,9 +60,10 @@ bool subghz_protocol_decoder_came_atomo_serialize(
  * Deserialize data SubGhzProtocolDecoderCameAtomo.
  * Deserialize data SubGhzProtocolDecoderCameAtomo.
  * @param context Pointer to a SubGhzProtocolDecoderCameAtomo instance
  * @param context Pointer to a SubGhzProtocolDecoderCameAtomo instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_came_atomo_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_came_atomo_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 15 - 26
lib/subghz/protocols/came_twee.c

@@ -241,18 +241,17 @@ static void subghz_protocol_came_twee_remote_controller(SubGhzBlockGeneric* inst
     instance->cnt = data >> 6;
     instance->cnt = data >> 6;
 }
 }
 
 
-bool subghz_protocol_encoder_came_twee_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_came_twee_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderCameTwee* instance = context;
     SubGhzProtocolEncoderCameTwee* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus res = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_came_twee_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        res = subghz_block_generic_deserialize_check_count_bit(
+            &instance->generic,
+            flipper_format,
+            subghz_protocol_came_twee_const.min_count_bit_for_found);
+        if(res != SubGhzProtocolStatusOk) {
             break;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
@@ -262,8 +261,6 @@ bool subghz_protocol_encoder_came_twee_deserialize(void* context, FlipperFormat*
         subghz_protocol_came_twee_remote_controller(&instance->generic);
         subghz_protocol_came_twee_remote_controller(&instance->generic);
         subghz_protocol_encoder_came_twee_get_upload(instance);
         subghz_protocol_encoder_came_twee_get_upload(instance);
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
     return res;
     return res;
@@ -419,7 +416,7 @@ uint8_t subghz_protocol_decoder_came_twee_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_came_twee_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_came_twee_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -428,22 +425,14 @@ bool subghz_protocol_decoder_came_twee_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_came_twee_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_came_twee_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderCameTwee* instance = context;
     SubGhzProtocolDecoderCameTwee* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_came_twee_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        subghz_protocol_came_twee_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_came_twee_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_came_twee_get_string(void* context, FuriString* output) {

+ 8 - 6
lib/subghz/protocols/came_twee.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_came_twee_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderCameTwee instance
  * @param context Pointer to a SubGhzProtocolEncoderCameTwee instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_came_twee_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_came_twee_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -84,9 +85,9 @@ uint8_t subghz_protocol_decoder_came_twee_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderCameTwee instance
  * @param context Pointer to a SubGhzProtocolDecoderCameTwee instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_came_twee_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_came_twee_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -95,9 +96,10 @@ bool subghz_protocol_decoder_came_twee_serialize(
  * Deserialize data SubGhzProtocolDecoderCameTwee.
  * Deserialize data SubGhzProtocolDecoderCameTwee.
  * @param context Pointer to a SubGhzProtocolDecoderCameTwee instance
  * @param context Pointer to a SubGhzProtocolDecoderCameTwee instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_came_twee_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_came_twee_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 18 - 12
lib/subghz/protocols/chamberlain_code.c

@@ -207,31 +207,35 @@ static bool
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_chamb_code_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_chamb_code_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderChamb_Code* instance = context;
     SubGhzProtocolEncoderChamb_Code* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
+        ret = subghz_block_generic_deserialize(&instance->generic, flipper_format);
+        if(ret != SubGhzProtocolStatusOk) {
             break;
             break;
         }
         }
         if(instance->generic.data_count_bit >
         if(instance->generic.data_count_bit >
            subghz_protocol_chamb_code_const.min_count_bit_for_found) {
            subghz_protocol_chamb_code_const.min_count_bit_for_found) {
             FURI_LOG_E(TAG, "Wrong number of bits in key");
             FURI_LOG_E(TAG, "Wrong number of bits in key");
+            ret = SubGhzProtocolStatusErrorValueBitCount;
             break;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_chamb_code_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_chamb_code_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
 
 
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_chamb_code_stop(void* context) {
 void subghz_protocol_encoder_chamb_code_stop(void* context) {
@@ -425,7 +429,7 @@ uint8_t subghz_protocol_decoder_chamb_code_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_chamb_code_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_chamb_code_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -434,20 +438,22 @@ bool subghz_protocol_decoder_chamb_code_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_chamb_code_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_chamb_code_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderChamb_Code* instance = context;
     SubGhzProtocolDecoderChamb_Code* instance = context;
-    bool ret = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
+        ret = subghz_block_generic_deserialize(&instance->generic, flipper_format);
+        if(ret != SubGhzProtocolStatusOk) {
             break;
             break;
         }
         }
         if(instance->generic.data_count_bit >
         if(instance->generic.data_count_bit >
            subghz_protocol_chamb_code_const.min_count_bit_for_found) {
            subghz_protocol_chamb_code_const.min_count_bit_for_found) {
             FURI_LOG_E(TAG, "Wrong number of bits in key");
             FURI_LOG_E(TAG, "Wrong number of bits in key");
+            ret = SubGhzProtocolStatusErrorValueBitCount;
             break;
             break;
         }
         }
-        ret = true;
     } while(false);
     } while(false);
     return ret;
     return ret;
 }
 }

+ 8 - 6
lib/subghz/protocols/chamberlain_code.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_chamb_code_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderChamb_Code instance
  * @param context Pointer to a SubGhzProtocolEncoderChamb_Code instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_chamb_code_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_chamb_code_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -84,9 +85,9 @@ uint8_t subghz_protocol_decoder_chamb_code_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderChamb_Code instance
  * @param context Pointer to a SubGhzProtocolDecoderChamb_Code instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_chamb_code_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_chamb_code_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -95,9 +96,10 @@ bool subghz_protocol_decoder_chamb_code_serialize(
  * Deserialize data SubGhzProtocolDecoderChamb_Code.
  * Deserialize data SubGhzProtocolDecoderChamb_Code.
  * @param context Pointer to a SubGhzProtocolDecoderChamb_Code instance
  * @param context Pointer to a SubGhzProtocolDecoderChamb_Code instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_chamb_code_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_chamb_code_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 18 - 27
lib/subghz/protocols/clemsa.c

@@ -155,31 +155,32 @@ static bool subghz_protocol_encoder_clemsa_get_upload(SubGhzProtocolEncoderClems
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_clemsa_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_clemsa_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderClemsa* instance = context;
     SubGhzProtocolEncoderClemsa* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_clemsa_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        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;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_clemsa_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_clemsa_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
 
 
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_clemsa_stop(void* context) {
 void subghz_protocol_encoder_clemsa_stop(void* context) {
@@ -316,7 +317,7 @@ uint8_t subghz_protocol_decoder_clemsa_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_clemsa_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_clemsa_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -325,22 +326,12 @@ bool subghz_protocol_decoder_clemsa_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_clemsa_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_clemsa_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderClemsa* instance = context;
     SubGhzProtocolDecoderClemsa* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_clemsa_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, subghz_protocol_clemsa_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_clemsa_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_clemsa_get_string(void* context, FuriString* output) {

+ 8 - 6
lib/subghz/protocols/clemsa.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_clemsa_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderClemsa instance
  * @param context Pointer to a SubGhzProtocolEncoderClemsa instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_clemsa_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_clemsa_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -84,9 +85,9 @@ uint8_t subghz_protocol_decoder_clemsa_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderClemsa instance
  * @param context Pointer to a SubGhzProtocolDecoderClemsa instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_clemsa_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_clemsa_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -95,9 +96,10 @@ bool subghz_protocol_decoder_clemsa_serialize(
  * Deserialize data SubGhzProtocolDecoderClemsa.
  * Deserialize data SubGhzProtocolDecoderClemsa.
  * @param context Pointer to a SubGhzProtocolDecoderClemsa instance
  * @param context Pointer to a SubGhzProtocolDecoderClemsa instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_clemsa_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_clemsa_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 20 - 28
lib/subghz/protocols/doitrand.c

@@ -136,31 +136,31 @@ static bool subghz_protocol_encoder_doitrand_get_upload(SubGhzProtocolEncoderDoi
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_doitrand_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_doitrand_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderDoitrand* instance = context;
     SubGhzProtocolEncoderDoitrand* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_doitrand_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        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;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_doitrand_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_doitrand_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_doitrand_stop(void* context) {
 void subghz_protocol_encoder_doitrand_stop(void* context) {
@@ -310,7 +310,7 @@ uint8_t subghz_protocol_decoder_doitrand_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_doitrand_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_doitrand_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -319,22 +319,14 @@ bool subghz_protocol_decoder_doitrand_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_doitrand_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_doitrand_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderDoitrand* instance = context;
     SubGhzProtocolDecoderDoitrand* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_doitrand_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        subghz_protocol_doitrand_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_doitrand_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_doitrand_get_string(void* context, FuriString* output) {

+ 8 - 6
lib/subghz/protocols/doitrand.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_doitrand_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderDoitrand instance
  * @param context Pointer to a SubGhzProtocolEncoderDoitrand instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_doitrand_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_doitrand_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -84,9 +85,9 @@ uint8_t subghz_protocol_decoder_doitrand_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderDoitrand instance
  * @param context Pointer to a SubGhzProtocolDecoderDoitrand instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_doitrand_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_doitrand_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -95,9 +96,10 @@ bool subghz_protocol_decoder_doitrand_serialize(
  * Deserialize data SubGhzProtocolDecoderDoitrand.
  * Deserialize data SubGhzProtocolDecoderDoitrand.
  * @param context Pointer to a SubGhzProtocolDecoderDoitrand instance
  * @param context Pointer to a SubGhzProtocolDecoderDoitrand instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_doitrand_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_doitrand_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 18 - 28
lib/subghz/protocols/dooya.c

@@ -146,31 +146,31 @@ static bool subghz_protocol_encoder_dooya_get_upload(SubGhzProtocolEncoderDooya*
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_dooya_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_dooya_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderDooya* instance = context;
     SubGhzProtocolEncoderDooya* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_dooya_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        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;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_dooya_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_dooya_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_dooya_stop(void* context) {
 void subghz_protocol_encoder_dooya_stop(void* context) {
@@ -354,7 +354,7 @@ uint8_t subghz_protocol_decoder_dooya_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_dooya_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_dooya_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -363,22 +363,12 @@ bool subghz_protocol_decoder_dooya_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_dooya_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_dooya_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderDooya* instance = context;
     SubGhzProtocolDecoderDooya* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_dooya_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, subghz_protocol_dooya_const.min_count_bit_for_found);
 }
 }
 
 
 /**
 /**

+ 8 - 6
lib/subghz/protocols/dooya.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_dooya_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderDooya instance
  * @param context Pointer to a SubGhzProtocolEncoderDooya instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_dooya_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_dooya_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -84,9 +85,9 @@ uint8_t subghz_protocol_decoder_dooya_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderDooya instance
  * @param context Pointer to a SubGhzProtocolDecoderDooya instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_dooya_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_dooya_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -95,9 +96,10 @@ bool subghz_protocol_decoder_dooya_serialize(
  * Deserialize data SubGhzProtocolDecoderDooya.
  * Deserialize data SubGhzProtocolDecoderDooya.
  * @param context Pointer to a SubGhzProtocolDecoderDooya instance
  * @param context Pointer to a SubGhzProtocolDecoderDooya instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_dooya_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_dooya_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 7 - 15
lib/subghz/protocols/faac_slh.c

@@ -180,7 +180,7 @@ uint8_t subghz_protocol_decoder_faac_slh_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_faac_slh_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_faac_slh_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -189,22 +189,14 @@ bool subghz_protocol_decoder_faac_slh_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderFaacSLH* instance = context;
     SubGhzProtocolDecoderFaacSLH* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_faac_slh_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        subghz_protocol_faac_slh_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* output) {

+ 5 - 4
lib/subghz/protocols/faac_slh.h

@@ -50,9 +50,9 @@ uint8_t subghz_protocol_decoder_faac_slh_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderFaacSLH instance
  * @param context Pointer to a SubGhzProtocolDecoderFaacSLH instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_faac_slh_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_faac_slh_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -61,9 +61,10 @@ bool subghz_protocol_decoder_faac_slh_serialize(
  * Deserialize data SubGhzProtocolDecoderFaacSLH.
  * Deserialize data SubGhzProtocolDecoderFaacSLH.
  * @param context Pointer to a SubGhzProtocolDecoderFaacSLH instance
  * @param context Pointer to a SubGhzProtocolDecoderFaacSLH instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 18 - 28
lib/subghz/protocols/gate_tx.c

@@ -129,31 +129,31 @@ static bool subghz_protocol_encoder_gate_tx_get_upload(SubGhzProtocolEncoderGate
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_gate_tx_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_gate_tx_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderGateTx* instance = context;
     SubGhzProtocolEncoderGateTx* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_gate_tx_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        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;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_gate_tx_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_gate_tx_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_gate_tx_stop(void* context) {
 void subghz_protocol_encoder_gate_tx_stop(void* context) {
@@ -290,7 +290,7 @@ uint8_t subghz_protocol_decoder_gate_tx_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_gate_tx_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_gate_tx_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -299,22 +299,12 @@ bool subghz_protocol_decoder_gate_tx_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_gate_tx_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_gate_tx_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderGateTx* instance = context;
     SubGhzProtocolDecoderGateTx* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_gate_tx_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, subghz_protocol_gate_tx_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_gate_tx_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_gate_tx_get_string(void* context, FuriString* output) {

+ 8 - 6
lib/subghz/protocols/gate_tx.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_gate_tx_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderGateTx instance
  * @param context Pointer to a SubGhzProtocolEncoderGateTx instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_gate_tx_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_gate_tx_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -84,9 +85,9 @@ uint8_t subghz_protocol_decoder_gate_tx_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderGateTx instance
  * @param context Pointer to a SubGhzProtocolDecoderGateTx instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_gate_tx_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_gate_tx_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -95,9 +96,10 @@ bool subghz_protocol_decoder_gate_tx_serialize(
  * Deserialize data SubGhzProtocolDecoderGateTx.
  * Deserialize data SubGhzProtocolDecoderGateTx.
  * @param context Pointer to a SubGhzProtocolDecoderGateTx instance
  * @param context Pointer to a SubGhzProtocolDecoderGateTx instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_gate_tx_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_gate_tx_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 18 - 28
lib/subghz/protocols/holtek.c

@@ -142,31 +142,31 @@ static bool subghz_protocol_encoder_holtek_get_upload(SubGhzProtocolEncoderHolte
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_holtek_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_holtek_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderHoltek* instance = context;
     SubGhzProtocolEncoderHoltek* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_holtek_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        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;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_holtek_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_holtek_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_holtek_stop(void* context) {
 void subghz_protocol_encoder_holtek_stop(void* context) {
@@ -322,7 +322,7 @@ uint8_t subghz_protocol_decoder_holtek_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_holtek_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_holtek_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -331,22 +331,12 @@ bool subghz_protocol_decoder_holtek_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_holtek_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_holtek_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderHoltek* instance = context;
     SubGhzProtocolDecoderHoltek* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_holtek_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, subghz_protocol_holtek_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_holtek_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_holtek_get_string(void* context, FuriString* output) {

+ 8 - 6
lib/subghz/protocols/holtek.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_holtek_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderHoltek instance
  * @param context Pointer to a SubGhzProtocolEncoderHoltek instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_holtek_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_holtek_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -84,9 +85,9 @@ uint8_t subghz_protocol_decoder_holtek_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderHoltek instance
  * @param context Pointer to a SubGhzProtocolDecoderHoltek instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_holtek_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_holtek_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -95,9 +96,10 @@ bool subghz_protocol_decoder_holtek_serialize(
  * Deserialize data SubGhzProtocolDecoderHoltek.
  * Deserialize data SubGhzProtocolDecoderHoltek.
  * @param context Pointer to a SubGhzProtocolDecoderHoltek instance
  * @param context Pointer to a SubGhzProtocolDecoderHoltek instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_holtek_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_holtek_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 32 - 27
lib/subghz/protocols/holtek_ht12x.c

@@ -147,39 +147,41 @@ static bool
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_holtek_th12x_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_holtek_th12x_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderHoltek_HT12X* instance = context;
     SubGhzProtocolEncoderHoltek_HT12X* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
+        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;
             break;
         }
         }
         if(!flipper_format_rewind(flipper_format)) {
         if(!flipper_format_rewind(flipper_format)) {
             FURI_LOG_E(TAG, "Rewind error");
             FURI_LOG_E(TAG, "Rewind error");
+            ret = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) {
         if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) {
             FURI_LOG_E(TAG, "Missing TE");
             FURI_LOG_E(TAG, "Missing TE");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_holtek_th12x_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+            ret = SubGhzProtocolStatusErrorParserTe;
             break;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_holtek_th12x_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_holtek_th12x_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_holtek_th12x_stop(void* context) {
 void subghz_protocol_encoder_holtek_th12x_stop(void* context) {
@@ -327,42 +329,45 @@ uint8_t subghz_protocol_decoder_holtek_th12x_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_holtek_th12x_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_holtek_th12x_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderHoltek_HT12X* instance = context;
     SubGhzProtocolDecoderHoltek_HT12X* instance = context;
-    bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
-    if(res && !flipper_format_write_uint32(flipper_format, "TE", &instance->te, 1)) {
+    SubGhzProtocolStatus ret =
+        subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
+    if((ret == SubGhzProtocolStatusOk) &&
+       !flipper_format_write_uint32(flipper_format, "TE", &instance->te, 1)) {
         FURI_LOG_E(TAG, "Unable to add TE");
         FURI_LOG_E(TAG, "Unable to add TE");
-        res = false;
+        ret = SubGhzProtocolStatusErrorParserTe;
     }
     }
-    return res;
+    return ret;
 }
 }
 
 
-bool subghz_protocol_decoder_holtek_th12x_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_holtek_th12x_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderHoltek_HT12X* instance = context;
     SubGhzProtocolDecoderHoltek_HT12X* instance = context;
-    bool ret = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_holtek_th12x_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        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;
             break;
         }
         }
         if(!flipper_format_rewind(flipper_format)) {
         if(!flipper_format_rewind(flipper_format)) {
             FURI_LOG_E(TAG, "Rewind error");
             FURI_LOG_E(TAG, "Rewind error");
+            ret = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) {
         if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) {
             FURI_LOG_E(TAG, "Missing TE");
             FURI_LOG_E(TAG, "Missing TE");
+            ret = SubGhzProtocolStatusErrorParserTe;
             break;
             break;
         }
         }
-        ret = true;
     } while(false);
     } while(false);
     return ret;
     return ret;
 }
 }

+ 8 - 6
lib/subghz/protocols/holtek_ht12x.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_holtek_th12x_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderHoltek_HT12X instance
  * @param context Pointer to a SubGhzProtocolEncoderHoltek_HT12X instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_holtek_th12x_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_holtek_th12x_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -84,9 +85,9 @@ uint8_t subghz_protocol_decoder_holtek_th12x_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderHoltek_HT12X instance
  * @param context Pointer to a SubGhzProtocolDecoderHoltek_HT12X instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_holtek_th12x_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_holtek_th12x_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -95,9 +96,10 @@ bool subghz_protocol_decoder_holtek_th12x_serialize(
  * Deserialize data SubGhzProtocolDecoderHoltek_HT12X.
  * Deserialize data SubGhzProtocolDecoderHoltek_HT12X.
  * @param context Pointer to a SubGhzProtocolDecoderHoltek_HT12X instance
  * @param context Pointer to a SubGhzProtocolDecoderHoltek_HT12X instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_holtek_th12x_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_holtek_th12x_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 18 - 28
lib/subghz/protocols/honeywell_wdb.c

@@ -142,33 +142,32 @@ static bool subghz_protocol_encoder_honeywell_wdb_get_upload(
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_honeywell_wdb_deserialize(
+SubGhzProtocolStatus subghz_protocol_encoder_honeywell_wdb_deserialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format) {
     FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderHoneywell_WDB* instance = context;
     SubGhzProtocolEncoderHoneywell_WDB* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_honeywell_wdb_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        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;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_honeywell_wdb_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_honeywell_wdb_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_honeywell_wdb_stop(void* context) {
 void subghz_protocol_encoder_honeywell_wdb_stop(void* context) {
@@ -345,7 +344,7 @@ uint8_t subghz_protocol_decoder_honeywell_wdb_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_honeywell_wdb_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_honeywell_wdb_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -354,24 +353,15 @@ bool subghz_protocol_decoder_honeywell_wdb_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_honeywell_wdb_deserialize(
+SubGhzProtocolStatus subghz_protocol_decoder_honeywell_wdb_deserialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format) {
     FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderHoneywell_WDB* instance = context;
     SubGhzProtocolDecoderHoneywell_WDB* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_honeywell_wdb_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        subghz_protocol_honeywell_wdb_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, FuriString* output) {

+ 8 - 10
lib/subghz/protocols/honeywell_wdb.h

@@ -28,11 +28,10 @@ void subghz_protocol_encoder_honeywell_wdb_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderHoneywell_WDB instance
  * @param context Pointer to a SubGhzProtocolEncoderHoneywell_WDB instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_honeywell_wdb_deserialize(
-    void* context,
-    FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_honeywell_wdb_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -86,9 +85,9 @@ uint8_t subghz_protocol_decoder_honeywell_wdb_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance
  * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_honeywell_wdb_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_honeywell_wdb_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -97,11 +96,10 @@ bool subghz_protocol_decoder_honeywell_wdb_serialize(
  * Deserialize data SubGhzProtocolDecoderHoneywell_WDB.
  * Deserialize data SubGhzProtocolDecoderHoneywell_WDB.
  * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance
  * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_honeywell_wdb_deserialize(
-    void* context,
-    FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_honeywell_wdb_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 18 - 28
lib/subghz/protocols/hormann.c

@@ -140,31 +140,31 @@ static bool subghz_protocol_encoder_hormann_get_upload(SubGhzProtocolEncoderHorm
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_hormann_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_hormann_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderHormann* instance = context;
     SubGhzProtocolEncoderHormann* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_hormann_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        ret = subghz_block_generic_deserialize_check_count_bit(
+            &instance->generic,
+            flipper_format,
+            subghz_protocol_hormann_const.min_count_bit_for_found);
+        if(ret != SubGhzProtocolStatusOk) {
             break;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_hormann_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_hormann_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_hormann_stop(void* context) {
 void subghz_protocol_encoder_hormann_stop(void* context) {
@@ -295,7 +295,7 @@ uint8_t subghz_protocol_decoder_hormann_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_hormann_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_hormann_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -304,22 +304,12 @@ bool subghz_protocol_decoder_hormann_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_hormann_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_hormann_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderHormann* instance = context;
     SubGhzProtocolDecoderHormann* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_hormann_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, subghz_protocol_hormann_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_hormann_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_hormann_get_string(void* context, FuriString* output) {

+ 8 - 6
lib/subghz/protocols/hormann.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_hormann_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderHormann instance
  * @param context Pointer to a SubGhzProtocolEncoderHormann instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_hormann_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_hormann_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -84,9 +85,9 @@ uint8_t subghz_protocol_decoder_hormann_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderHormann instance
  * @param context Pointer to a SubGhzProtocolDecoderHormann instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_hormann_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_hormann_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -95,9 +96,10 @@ bool subghz_protocol_decoder_hormann_serialize(
  * Deserialize data SubGhzProtocolDecoderHormann.
  * Deserialize data SubGhzProtocolDecoderHormann.
  * @param context Pointer to a SubGhzProtocolDecoderHormann instance
  * @param context Pointer to a SubGhzProtocolDecoderHormann instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_hormann_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_hormann_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 5 - 14
lib/subghz/protocols/ido.c

@@ -179,7 +179,7 @@ uint8_t subghz_protocol_decoder_ido_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_ido_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_ido_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -188,21 +188,12 @@ bool subghz_protocol_decoder_ido_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_ido_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_ido_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderIDo* instance = context;
     SubGhzProtocolDecoderIDo* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit != subghz_protocol_ido_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, subghz_protocol_ido_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_ido_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_ido_get_string(void* context, FuriString* output) {

+ 5 - 4
lib/subghz/protocols/ido.h

@@ -50,9 +50,9 @@ uint8_t subghz_protocol_decoder_ido_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderIDo instance
  * @param context Pointer to a SubGhzProtocolDecoderIDo instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_ido_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_ido_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -61,9 +61,10 @@ bool subghz_protocol_decoder_ido_serialize(
  * Deserialize data SubGhzProtocolDecoderIDo.
  * Deserialize data SubGhzProtocolDecoderIDo.
  * @param context Pointer to a SubGhzProtocolDecoderIDo instance
  * @param context Pointer to a SubGhzProtocolDecoderIDo instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_ido_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_ido_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 16 - 13
lib/subghz/protocols/intertechno_v3.c

@@ -158,34 +158,36 @@ static bool subghz_protocol_encoder_intertechno_v3_get_upload(
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_intertechno_v3_deserialize(
+SubGhzProtocolStatus subghz_protocol_encoder_intertechno_v3_deserialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format) {
     FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderIntertechno_V3* instance = context;
     SubGhzProtocolEncoderIntertechno_V3* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
+        ret = subghz_block_generic_deserialize(&instance->generic, flipper_format);
+        if(ret != SubGhzProtocolStatusOk) {
             break;
             break;
         }
         }
         if((instance->generic.data_count_bit !=
         if((instance->generic.data_count_bit !=
             subghz_protocol_intertechno_v3_const.min_count_bit_for_found) &&
             subghz_protocol_intertechno_v3_const.min_count_bit_for_found) &&
            (instance->generic.data_count_bit != INTERTECHNO_V3_DIMMING_COUNT_BIT)) {
            (instance->generic.data_count_bit != INTERTECHNO_V3_DIMMING_COUNT_BIT)) {
             FURI_LOG_E(TAG, "Wrong number of bits in key");
             FURI_LOG_E(TAG, "Wrong number of bits in key");
+            ret = SubGhzProtocolStatusErrorValueBitCount;
             break;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_intertechno_v3_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_intertechno_v3_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_intertechno_v3_stop(void* context) {
 void subghz_protocol_encoder_intertechno_v3_stop(void* context) {
@@ -404,7 +406,7 @@ uint8_t subghz_protocol_decoder_intertechno_v3_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_intertechno_v3_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_intertechno_v3_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -413,23 +415,24 @@ bool subghz_protocol_decoder_intertechno_v3_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_intertechno_v3_deserialize(
+SubGhzProtocolStatus subghz_protocol_decoder_intertechno_v3_deserialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format) {
     FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderIntertechno_V3* instance = context;
     SubGhzProtocolDecoderIntertechno_V3* instance = context;
-    bool ret = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
+        ret = subghz_block_generic_deserialize(&instance->generic, flipper_format);
+        if(ret != SubGhzProtocolStatusOk) {
             break;
             break;
         }
         }
         if((instance->generic.data_count_bit !=
         if((instance->generic.data_count_bit !=
             subghz_protocol_intertechno_v3_const.min_count_bit_for_found) &&
             subghz_protocol_intertechno_v3_const.min_count_bit_for_found) &&
            (instance->generic.data_count_bit != INTERTECHNO_V3_DIMMING_COUNT_BIT)) {
            (instance->generic.data_count_bit != INTERTECHNO_V3_DIMMING_COUNT_BIT)) {
             FURI_LOG_E(TAG, "Wrong number of bits in key");
             FURI_LOG_E(TAG, "Wrong number of bits in key");
+            ret = SubGhzProtocolStatusErrorValueBitCount;
             break;
             break;
         }
         }
-        ret = true;
     } while(false);
     } while(false);
     return ret;
     return ret;
 }
 }

+ 6 - 6
lib/subghz/protocols/intertechno_v3.h

@@ -28,9 +28,9 @@ void subghz_protocol_encoder_intertechno_v3_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderIntertechno_V3 instance
  * @param context Pointer to a SubGhzProtocolEncoderIntertechno_V3 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return Starus error
  */
  */
-bool subghz_protocol_encoder_intertechno_v3_deserialize(
+SubGhzProtocolStatus subghz_protocol_encoder_intertechno_v3_deserialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format);
     FlipperFormat* flipper_format);
 
 
@@ -86,9 +86,9 @@ uint8_t subghz_protocol_decoder_intertechno_v3_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance
  * @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return Starus error
  */
  */
-bool subghz_protocol_decoder_intertechno_v3_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_intertechno_v3_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -97,9 +97,9 @@ bool subghz_protocol_decoder_intertechno_v3_serialize(
  * Deserialize data SubGhzProtocolDecoderIntertechno_V3.
  * Deserialize data SubGhzProtocolDecoderIntertechno_V3.
  * @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance
  * @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return Starus error
  */
  */
-bool subghz_protocol_decoder_intertechno_v3_deserialize(
+SubGhzProtocolStatus subghz_protocol_decoder_intertechno_v3_deserialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format);
     FlipperFormat* flipper_format);
 
 

+ 27 - 35
lib/subghz/protocols/keeloq.c

@@ -254,18 +254,17 @@ static bool
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderKeeloq* instance = context;
     SubGhzProtocolEncoderKeeloq* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_keeloq_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        ret = subghz_block_generic_deserialize_check_count_bit(
+            &instance->generic,
+            flipper_format,
+            subghz_protocol_keeloq_const.min_count_bit_for_found);
+        if(ret != SubGhzProtocolStatusOk) {
             break;
             break;
         }
         }
         subghz_protocol_keeloq_check_remote_controller(
         subghz_protocol_keeloq_check_remote_controller(
@@ -273,6 +272,7 @@ bool subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* fl
 
 
         if(strcmp(instance->manufacture_name, "DoorHan") != 0) {
         if(strcmp(instance->manufacture_name, "DoorHan") != 0) {
             FURI_LOG_E(TAG, "Wrong manufacturer name");
             FURI_LOG_E(TAG, "Wrong manufacturer name");
+            ret = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
 
 
@@ -280,10 +280,13 @@ bool subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* fl
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_keeloq_get_upload(instance, instance->generic.btn)) break;
-
+        if(!subghz_protocol_encoder_keeloq_get_upload(instance, instance->generic.btn)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         if(!flipper_format_rewind(flipper_format)) {
         if(!flipper_format_rewind(flipper_format)) {
             FURI_LOG_E(TAG, "Rewind error");
             FURI_LOG_E(TAG, "Rewind error");
+            ret = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         uint8_t key_data[sizeof(uint64_t)] = {0};
         uint8_t key_data[sizeof(uint64_t)] = {0};
@@ -292,15 +295,14 @@ bool subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* fl
         }
         }
         if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) {
         if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) {
             FURI_LOG_E(TAG, "Unable to add Key");
             FURI_LOG_E(TAG, "Unable to add Key");
+            ret = SubGhzProtocolStatusErrorParserKey;
             break;
             break;
         }
         }
 
 
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_keeloq_stop(void* context) {
 void subghz_protocol_encoder_keeloq_stop(void* context) {
@@ -669,7 +671,7 @@ uint8_t subghz_protocol_decoder_keeloq_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_keeloq_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_keeloq_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -678,34 +680,24 @@ bool subghz_protocol_decoder_keeloq_serialize(
     subghz_protocol_keeloq_check_remote_controller(
     subghz_protocol_keeloq_check_remote_controller(
         &instance->generic, instance->keystore, &instance->manufacture_name);
         &instance->generic, instance->keystore, &instance->manufacture_name);
 
 
-    bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
+    SubGhzProtocolStatus res =
+        subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 
 
-    if(res && !flipper_format_write_string_cstr(
-                  flipper_format, "Manufacture", instance->manufacture_name)) {
+    if((res == SubGhzProtocolStatusOk) &&
+       !flipper_format_write_string_cstr(
+           flipper_format, "Manufacture", instance->manufacture_name)) {
         FURI_LOG_E(TAG, "Unable to add manufacture name");
         FURI_LOG_E(TAG, "Unable to add manufacture name");
-        res = false;
+        res = SubGhzProtocolStatusErrorParserOthers;
     }
     }
     return res;
     return res;
 }
 }
 
 
-bool subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderKeeloq* instance = context;
     SubGhzProtocolDecoderKeeloq* instance = context;
-    bool res = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_keeloq_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        res = true;
-    } while(false);
-
-    return res;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, subghz_protocol_keeloq_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output) {

+ 8 - 6
lib/subghz/protocols/keeloq.h

@@ -48,9 +48,10 @@ bool subghz_protocol_keeloq_create_data(
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderKeeloq instance
  * @param context Pointer to a SubGhzProtocolEncoderKeeloq instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -104,9 +105,9 @@ uint8_t subghz_protocol_decoder_keeloq_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderKeeloq instance
  * @param context Pointer to a SubGhzProtocolDecoderKeeloq instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return SubGhzProtocolStatus
  */
  */
-bool subghz_protocol_decoder_keeloq_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_keeloq_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -115,9 +116,10 @@ bool subghz_protocol_decoder_keeloq_serialize(
  * Deserialize data SubGhzProtocolDecoderKeeloq.
  * Deserialize data SubGhzProtocolDecoderKeeloq.
  * @param context Pointer to a SubGhzProtocolDecoderKeeloq instance
  * @param context Pointer to a SubGhzProtocolDecoderKeeloq instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return SubGhzProtocolStatus
  */
  */
-bool subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 5 - 14
lib/subghz/protocols/kia.c

@@ -230,7 +230,7 @@ uint8_t subghz_protocol_decoder_kia_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_kia_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_kia_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -239,21 +239,12 @@ bool subghz_protocol_decoder_kia_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_kia_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_kia_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderKIA* instance = context;
     SubGhzProtocolDecoderKIA* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit != subghz_protocol_kia_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, subghz_protocol_kia_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_kia_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_kia_get_string(void* context, FuriString* output) {

+ 5 - 4
lib/subghz/protocols/kia.h

@@ -50,9 +50,9 @@ uint8_t subghz_protocol_decoder_kia_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderKIA instance
  * @param context Pointer to a SubGhzProtocolDecoderKIA instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_kia_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_kia_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -61,9 +61,10 @@ bool subghz_protocol_decoder_kia_serialize(
  * Deserialize data SubGhzProtocolDecoderKIA.
  * Deserialize data SubGhzProtocolDecoderKIA.
  * @param context Pointer to a SubGhzProtocolDecoderKIA instance
  * @param context Pointer to a SubGhzProtocolDecoderKIA instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_kia_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_kia_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 16 - 16
lib/subghz/protocols/kinggates_stylo_4k.c

@@ -260,56 +260,56 @@ uint8_t subghz_protocol_decoder_kinggates_stylo_4k_get_hash_data(void* context)
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_kinggates_stylo_4k_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_kinggates_stylo_4k_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderKingGates_stylo_4k* instance = context;
     SubGhzProtocolDecoderKingGates_stylo_4k* instance = context;
-    bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
+    SubGhzProtocolStatus ret =
+        subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 
 
     uint8_t key_data[sizeof(uint64_t)] = {0};
     uint8_t key_data[sizeof(uint64_t)] = {0};
     for(size_t i = 0; i < sizeof(uint64_t); i++) {
     for(size_t i = 0; i < sizeof(uint64_t); i++) {
         key_data[sizeof(uint64_t) - i - 1] = (instance->data >> (i * 8)) & 0xFF;
         key_data[sizeof(uint64_t) - i - 1] = (instance->data >> (i * 8)) & 0xFF;
     }
     }
 
 
-    if(res && !flipper_format_write_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
+    if((ret == SubGhzProtocolStatusOk) &&
+       !flipper_format_write_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
         FURI_LOG_E(TAG, "Unable to add Data");
         FURI_LOG_E(TAG, "Unable to add Data");
-        res = false;
+        ret = SubGhzProtocolStatusErrorParserOthers;
     }
     }
-    return res;
-
-    return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
+    return ret;
 }
 }
 
 
-bool subghz_protocol_decoder_kinggates_stylo_4k_deserialize(
+SubGhzProtocolStatus subghz_protocol_decoder_kinggates_stylo_4k_deserialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format) {
     FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderKingGates_stylo_4k* instance = context;
     SubGhzProtocolDecoderKingGates_stylo_4k* instance = context;
-    bool ret = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_kinggates_stylo_4k_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        ret = subghz_block_generic_deserialize_check_count_bit(
+            &instance->generic,
+            flipper_format,
+            subghz_protocol_kinggates_stylo_4k_const.min_count_bit_for_found);
+        if(ret != SubGhzProtocolStatusOk) {
             break;
             break;
         }
         }
         if(!flipper_format_rewind(flipper_format)) {
         if(!flipper_format_rewind(flipper_format)) {
             FURI_LOG_E(TAG, "Rewind error");
             FURI_LOG_E(TAG, "Rewind error");
+            ret = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         uint8_t key_data[sizeof(uint64_t)] = {0};
         uint8_t key_data[sizeof(uint64_t)] = {0};
         if(!flipper_format_read_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
         if(!flipper_format_read_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
             FURI_LOG_E(TAG, "Missing Data");
             FURI_LOG_E(TAG, "Missing Data");
+            ret = SubGhzProtocolStatusErrorParserOthers;
             break;
             break;
         }
         }
         for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
         for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
             instance->data = instance->data << 8 | key_data[i];
             instance->data = instance->data << 8 | key_data[i];
         }
         }
-        ret = true;
     } while(false);
     } while(false);
     return ret;
     return ret;
 }
 }

+ 4 - 4
lib/subghz/protocols/kinggates_stylo_4k.h

@@ -49,9 +49,9 @@ uint8_t subghz_protocol_decoder_kinggates_stylo_4k_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderKingGates_stylo_4k instance
  * @param context Pointer to a SubGhzProtocolDecoderKingGates_stylo_4k instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_kinggates_stylo_4k_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_kinggates_stylo_4k_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -60,9 +60,9 @@ bool subghz_protocol_decoder_kinggates_stylo_4k_serialize(
  * Deserialize data SubGhzProtocolDecoderKingGates_stylo_4k.
  * Deserialize data SubGhzProtocolDecoderKingGates_stylo_4k.
  * @param context Pointer to a SubGhzProtocolDecoderKingGates_stylo_4k instance
  * @param context Pointer to a SubGhzProtocolDecoderKingGates_stylo_4k instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_kinggates_stylo_4k_deserialize(
+SubGhzProtocolStatus subghz_protocol_decoder_kinggates_stylo_4k_deserialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format);
     FlipperFormat* flipper_format);
 
 

+ 18 - 28
lib/subghz/protocols/linear.c

@@ -147,31 +147,31 @@ static bool subghz_protocol_encoder_linear_get_upload(SubGhzProtocolEncoderLinea
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_linear_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_linear_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderLinear* instance = context;
     SubGhzProtocolEncoderLinear* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_linear_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        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;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_linear_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_linear_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_linear_stop(void* context) {
 void subghz_protocol_encoder_linear_stop(void* context) {
@@ -300,7 +300,7 @@ uint8_t subghz_protocol_decoder_linear_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_linear_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_linear_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -309,22 +309,12 @@ bool subghz_protocol_decoder_linear_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_linear_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_linear_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderLinear* instance = context;
     SubGhzProtocolDecoderLinear* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_linear_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic, flipper_format, subghz_protocol_linear_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_linear_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_linear_get_string(void* context, FuriString* output) {

+ 8 - 6
lib/subghz/protocols/linear.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_linear_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderLinear instance
  * @param context Pointer to a SubGhzProtocolEncoderLinear instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_linear_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_linear_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -84,9 +85,9 @@ uint8_t subghz_protocol_decoder_linear_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderLinear instance
  * @param context Pointer to a SubGhzProtocolDecoderLinear instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_linear_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_linear_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -95,9 +96,10 @@ bool subghz_protocol_decoder_linear_serialize(
  * Deserialize data SubGhzProtocolDecoderLinear.
  * Deserialize data SubGhzProtocolDecoderLinear.
  * @param context Pointer to a SubGhzProtocolDecoderLinear instance
  * @param context Pointer to a SubGhzProtocolDecoderLinear instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_linear_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_linear_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 18 - 28
lib/subghz/protocols/linear_delta3.c

@@ -150,33 +150,32 @@ static bool
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_linear_delta3_deserialize(
+SubGhzProtocolStatus subghz_protocol_encoder_linear_delta3_deserialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format) {
     FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderLinearDelta3* instance = context;
     SubGhzProtocolEncoderLinearDelta3* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_linear_delta3_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        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;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_linear_delta3_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_linear_delta3_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_linear_delta3_stop(void* context) {
 void subghz_protocol_encoder_linear_delta3_stop(void* context) {
@@ -312,7 +311,7 @@ uint8_t subghz_protocol_decoder_linear_delta3_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8));
         &instance->decoder, (instance->decoder.decode_count_bit / 8));
 }
 }
 
 
-bool subghz_protocol_decoder_linear_delta3_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_linear_delta3_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -321,24 +320,15 @@ bool subghz_protocol_decoder_linear_delta3_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_linear_delta3_deserialize(
+SubGhzProtocolStatus subghz_protocol_decoder_linear_delta3_deserialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format) {
     FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderLinearDelta3* instance = context;
     SubGhzProtocolDecoderLinearDelta3* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_linear_delta3_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        subghz_protocol_linear_delta3_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_linear_delta3_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_linear_delta3_get_string(void* context, FuriString* output) {

+ 8 - 10
lib/subghz/protocols/linear_delta3.h

@@ -28,11 +28,10 @@ void subghz_protocol_encoder_linear_delta3_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderLinearDelta3 instance
  * @param context Pointer to a SubGhzProtocolEncoderLinearDelta3 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_linear_delta3_deserialize(
-    void* context,
-    FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_linear_delta3_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -86,9 +85,9 @@ uint8_t subghz_protocol_decoder_linear_delta3_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderLinearDelta3 instance
  * @param context Pointer to a SubGhzProtocolDecoderLinearDelta3 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_linear_delta3_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_linear_delta3_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -97,11 +96,10 @@ bool subghz_protocol_decoder_linear_delta3_serialize(
  * Deserialize data SubGhzProtocolDecoderLinearDelta3.
  * Deserialize data SubGhzProtocolDecoderLinearDelta3.
  * @param context Pointer to a SubGhzProtocolDecoderLinearDelta3 instance
  * @param context Pointer to a SubGhzProtocolDecoderLinearDelta3 instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_linear_delta3_deserialize(
-    void* context,
-    FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_linear_delta3_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 20 - 28
lib/subghz/protocols/magellan.c

@@ -150,31 +150,31 @@ static bool subghz_protocol_encoder_magellan_get_upload(SubGhzProtocolEncoderMag
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_magellan_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_magellan_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderMagellan* instance = context;
     SubGhzProtocolEncoderMagellan* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_magellan_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        ret = subghz_block_generic_deserialize_check_count_bit(
+            &instance->generic,
+            flipper_format,
+            subghz_protocol_magellan_const.min_count_bit_for_found);
+        if(ret != SubGhzProtocolStatusOk) {
             break;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_magellan_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_magellan_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_magellan_stop(void* context) {
 void subghz_protocol_encoder_magellan_stop(void* context) {
@@ -397,7 +397,7 @@ uint8_t subghz_protocol_decoder_magellan_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_magellan_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_magellan_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -406,22 +406,14 @@ bool subghz_protocol_decoder_magellan_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_magellan_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_magellan_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderMagellan* instance = context;
     SubGhzProtocolDecoderMagellan* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_magellan_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        subghz_protocol_magellan_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_magellan_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_magellan_get_string(void* context, FuriString* output) {

+ 8 - 6
lib/subghz/protocols/magellan.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_magellan_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderMagellan instance
  * @param context Pointer to a SubGhzProtocolEncoderMagellan instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_magellan_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_magellan_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -84,9 +85,9 @@ uint8_t subghz_protocol_decoder_magellan_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderMagellan instance
  * @param context Pointer to a SubGhzProtocolDecoderMagellan instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_magellan_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_magellan_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -95,9 +96,10 @@ bool subghz_protocol_decoder_magellan_serialize(
  * Deserialize data SubGhzProtocolDecoderMagellan.
  * Deserialize data SubGhzProtocolDecoderMagellan.
  * @param context Pointer to a SubGhzProtocolDecoderMagellan instance
  * @param context Pointer to a SubGhzProtocolDecoderMagellan instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_magellan_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_magellan_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 16 - 27
lib/subghz/protocols/marantec.c

@@ -188,18 +188,17 @@ static void subghz_protocol_marantec_remote_controller(SubGhzBlockGeneric* insta
     instance->serial = ((instance->data >> 12) & 0xFFFFFF00) | ((instance->data >> 8) & 0xFF);
     instance->serial = ((instance->data >> 12) & 0xFFFFFF00) | ((instance->data >> 8) & 0xFF);
 }
 }
 
 
-bool subghz_protocol_encoder_marantec_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_marantec_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderMarantec* instance = context;
     SubGhzProtocolEncoderMarantec* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_marantec_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        ret = subghz_block_generic_deserialize_check_count_bit(
+            &instance->generic,
+            flipper_format,
+            subghz_protocol_marantec_const.min_count_bit_for_found);
+        if(ret != SubGhzProtocolStatusOk) {
             break;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
@@ -209,11 +208,9 @@ bool subghz_protocol_encoder_marantec_deserialize(void* context, FlipperFormat*
         subghz_protocol_marantec_remote_controller(&instance->generic);
         subghz_protocol_marantec_remote_controller(&instance->generic);
         subghz_protocol_encoder_marantec_get_upload(instance);
         subghz_protocol_encoder_marantec_get_upload(instance);
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_marantec_stop(void* context) {
 void subghz_protocol_encoder_marantec_stop(void* context) {
@@ -346,7 +343,7 @@ uint8_t subghz_protocol_decoder_marantec_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_marantec_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_marantec_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -355,22 +352,14 @@ bool subghz_protocol_decoder_marantec_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_marantec_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_marantec_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderMarantec* instance = context;
     SubGhzProtocolDecoderMarantec* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_marantec_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        subghz_protocol_marantec_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* output) {

+ 8 - 6
lib/subghz/protocols/marantec.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_marantec_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderMarantec instance
  * @param context Pointer to a SubGhzProtocolEncoderMarantec instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_marantec_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_marantec_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -84,9 +85,9 @@ uint8_t subghz_protocol_decoder_marantec_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderMarantec instance
  * @param context Pointer to a SubGhzProtocolDecoderMarantec instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_marantec_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_marantec_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -95,9 +96,10 @@ bool subghz_protocol_decoder_marantec_serialize(
  * Deserialize data SubGhzProtocolDecoderMarantec.
  * Deserialize data SubGhzProtocolDecoderMarantec.
  * @param context Pointer to a SubGhzProtocolDecoderMarantec instance
  * @param context Pointer to a SubGhzProtocolDecoderMarantec instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_marantec_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_marantec_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 20 - 28
lib/subghz/protocols/megacode.c

@@ -175,31 +175,31 @@ static bool subghz_protocol_encoder_megacode_get_upload(SubGhzProtocolEncoderMeg
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_megacode_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_megacode_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderMegaCode* instance = context;
     SubGhzProtocolEncoderMegaCode* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_megacode_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        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;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_megacode_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_megacode_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_megacode_stop(void* context) {
 void subghz_protocol_encoder_megacode_stop(void* context) {
@@ -381,7 +381,7 @@ uint8_t subghz_protocol_decoder_megacode_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_megacode_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_megacode_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -390,22 +390,14 @@ bool subghz_protocol_decoder_megacode_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_megacode_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_megacode_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderMegaCode* instance = context;
     SubGhzProtocolDecoderMegaCode* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_megacode_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        subghz_protocol_megacode_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_megacode_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_megacode_get_string(void* context, FuriString* output) {

+ 8 - 6
lib/subghz/protocols/megacode.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_megacode_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderMegaCode instance
  * @param context Pointer to a SubGhzProtocolEncoderMegaCode instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_megacode_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_megacode_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -84,9 +85,9 @@ uint8_t subghz_protocol_decoder_megacode_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance
  * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_megacode_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_megacode_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -95,9 +96,10 @@ bool subghz_protocol_decoder_megacode_serialize(
  * Deserialize data SubGhzProtocolDecoderMegaCode.
  * Deserialize data SubGhzProtocolDecoderMegaCode.
  * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance
  * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_megacode_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_megacode_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 20 - 28
lib/subghz/protocols/nero_radio.c

@@ -154,31 +154,31 @@ static bool
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_nero_radio_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_nero_radio_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderNeroRadio* instance = context;
     SubGhzProtocolEncoderNeroRadio* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_nero_radio_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        ret = subghz_block_generic_deserialize_check_count_bit(
+            &instance->generic,
+            flipper_format,
+            subghz_protocol_nero_radio_const.min_count_bit_for_found);
+        if(ret != SubGhzProtocolStatusOk) {
             break;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_nero_radio_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_nero_radio_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_nero_radio_stop(void* context) {
 void subghz_protocol_encoder_nero_radio_stop(void* context) {
@@ -343,7 +343,7 @@ uint8_t subghz_protocol_decoder_nero_radio_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_nero_radio_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_nero_radio_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -352,22 +352,14 @@ bool subghz_protocol_decoder_nero_radio_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_nero_radio_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_nero_radio_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderNeroRadio* instance = context;
     SubGhzProtocolDecoderNeroRadio* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_nero_radio_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        subghz_protocol_nero_radio_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_nero_radio_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_nero_radio_get_string(void* context, FuriString* output) {

+ 8 - 6
lib/subghz/protocols/nero_radio.h

@@ -28,9 +28,10 @@ void subghz_protocol_encoder_nero_radio_free(void* context);
  * Deserialize and generating an upload to send.
  * Deserialize and generating an upload to send.
  * @param context Pointer to a SubGhzProtocolEncoderNeroRadio instance
  * @param context Pointer to a SubGhzProtocolEncoderNeroRadio instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_encoder_nero_radio_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_encoder_nero_radio_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Forced transmission stop.
  * Forced transmission stop.
@@ -84,9 +85,9 @@ uint8_t subghz_protocol_decoder_nero_radio_get_hash_data(void* context);
  * @param context Pointer to a SubGhzProtocolDecoderNeroRadio instance
  * @param context Pointer to a SubGhzProtocolDecoderNeroRadio instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
  * @param preset The modulation on which the signal was received, SubGhzRadioPreset
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_nero_radio_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_nero_radio_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset);
     SubGhzRadioPreset* preset);
@@ -95,9 +96,10 @@ bool subghz_protocol_decoder_nero_radio_serialize(
  * Deserialize data SubGhzProtocolDecoderNeroRadio.
  * Deserialize data SubGhzProtocolDecoderNeroRadio.
  * @param context Pointer to a SubGhzProtocolDecoderNeroRadio instance
  * @param context Pointer to a SubGhzProtocolDecoderNeroRadio instance
  * @param flipper_format Pointer to a FlipperFormat instance
  * @param flipper_format Pointer to a FlipperFormat instance
- * @return true On success
+ * @return status
  */
  */
-bool subghz_protocol_decoder_nero_radio_deserialize(void* context, FlipperFormat* flipper_format);
+SubGhzProtocolStatus
+    subghz_protocol_decoder_nero_radio_deserialize(void* context, FlipperFormat* flipper_format);
 
 
 /**
 /**
  * Getting a textual representation of the received data.
  * Getting a textual representation of the received data.

+ 20 - 28
lib/subghz/protocols/nero_sketch.c

@@ -148,31 +148,31 @@ static bool
     return true;
     return true;
 }
 }
 
 
-bool subghz_protocol_encoder_nero_sketch_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_encoder_nero_sketch_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolEncoderNeroSketch* instance = context;
     SubGhzProtocolEncoderNeroSketch* instance = context;
-    bool res = false;
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
     do {
     do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            FURI_LOG_E(TAG, "Deserialize error");
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_nero_sketch_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
+        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;
             break;
         }
         }
         //optional parameter parameter
         //optional parameter parameter
         flipper_format_read_uint32(
         flipper_format_read_uint32(
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
             flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
 
 
-        if(!subghz_protocol_encoder_nero_sketch_get_upload(instance)) break;
+        if(!subghz_protocol_encoder_nero_sketch_get_upload(instance)) {
+            ret = SubGhzProtocolStatusErrorEncoderGetUpload;
+            break;
+        }
         instance->encoder.is_running = true;
         instance->encoder.is_running = true;
-
-        res = true;
     } while(false);
     } while(false);
 
 
-    return res;
+    return ret;
 }
 }
 
 
 void subghz_protocol_encoder_nero_sketch_stop(void* context) {
 void subghz_protocol_encoder_nero_sketch_stop(void* context) {
@@ -328,7 +328,7 @@ uint8_t subghz_protocol_decoder_nero_sketch_get_hash_data(void* context) {
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
         &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
 }
 }
 
 
-bool subghz_protocol_decoder_nero_sketch_serialize(
+SubGhzProtocolStatus subghz_protocol_decoder_nero_sketch_serialize(
     void* context,
     void* context,
     FlipperFormat* flipper_format,
     FlipperFormat* flipper_format,
     SubGhzRadioPreset* preset) {
     SubGhzRadioPreset* preset) {
@@ -337,22 +337,14 @@ bool subghz_protocol_decoder_nero_sketch_serialize(
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
     return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
 }
 }
 
 
-bool subghz_protocol_decoder_nero_sketch_deserialize(void* context, FlipperFormat* flipper_format) {
+SubGhzProtocolStatus
+    subghz_protocol_decoder_nero_sketch_deserialize(void* context, FlipperFormat* flipper_format) {
     furi_assert(context);
     furi_assert(context);
     SubGhzProtocolDecoderNeroSketch* instance = context;
     SubGhzProtocolDecoderNeroSketch* instance = context;
-    bool ret = false;
-    do {
-        if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
-            break;
-        }
-        if(instance->generic.data_count_bit !=
-           subghz_protocol_nero_sketch_const.min_count_bit_for_found) {
-            FURI_LOG_E(TAG, "Wrong number of bits in key");
-            break;
-        }
-        ret = true;
-    } while(false);
-    return ret;
+    return subghz_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        subghz_protocol_nero_sketch_const.min_count_bit_for_found);
 }
 }
 
 
 void subghz_protocol_decoder_nero_sketch_get_string(void* context, FuriString* output) {
 void subghz_protocol_decoder_nero_sketch_get_string(void* context, FuriString* output) {

Some files were not shown because too many files changed in this diff