ソースを参照

SubGhz: Nice FlooR S improvements, cli stack overflow fix, code documentation, new key data formatting (#559)

Skorpionm 4 年 前
コミット
88be176fcf

+ 1 - 1
applications/applications.c

@@ -51,7 +51,7 @@ void ibutton_cli_init();
 
 const FlipperApplication FLIPPER_SERVICES[] = {
 #ifdef SRV_CLI
-    {.app = cli_task, .name = "cli_task", .stack_size = 2048, .icon = A_Plugins_14},
+    {.app = cli_task, .name = "cli_task", .stack_size = 4096, .icon = A_Plugins_14},
 #endif
 
 #ifdef SRV_EXAMPLE_BLINK

+ 1 - 0
applications/subghz/subghz_cli.c

@@ -256,6 +256,7 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) {
 
     SubGhzProtocol* protocol = subghz_protocol_alloc();
     subghz_protocol_load_keeloq_file(protocol, "/assets/subghz/keeloq_mfcodes");
+    subghz_protocol_load_nice_flor_s_file(protocol, "/assets/subghz/nice_floor_s_rx");
     subghz_protocol_enable_dump(protocol, NULL, NULL);
 
     frequency = api_hal_subghz_set_frequency_and_path(frequency);

+ 2 - 0
applications/subghz/views/subghz_capture.c

@@ -161,6 +161,8 @@ SubghzCapture* subghz_capture_alloc() {
     subghz_worker_set_context(subghz_capture->worker, subghz_capture->protocol);
 
     subghz_protocol_load_keeloq_file(subghz_capture->protocol, "/assets/subghz/keeloq_mfcodes");
+    subghz_protocol_load_nice_flor_s_file(
+        subghz_capture->protocol, "/assets/subghz/nice_floor_s_rx");
     subghz_protocol_enable_dump(
         subghz_capture->protocol, subghz_capture_text_callback, subghz_capture);
 

+ 4 - 0
lib/fl_subghz/protocols/subghz_protocol.c

@@ -89,6 +89,10 @@ static void subghz_protocol_load_keeloq_file_process_line(SubGhzProtocol* instan
     }
 }
 
+void subghz_protocol_load_nice_flor_s_file(SubGhzProtocol* instance, const char* file_name) {
+    subghz_protocol_nice_flor_s_name_file(instance->nice_flor_s, file_name);
+}
+
 void subghz_protocol_load_keeloq_file(SubGhzProtocol* instance, const char* file_name) {
     File manufacture_keys_file;
     FS_Api* fs_api = furi_record_open("sdcard");

+ 40 - 2
lib/fl_subghz/protocols/subghz_protocol.h

@@ -6,14 +6,52 @@ typedef void (*SubGhzProtocolTextCallback)(string_t text, void* context);
 
 typedef struct SubGhzProtocol SubGhzProtocol;
 
+/** Allocate SubGhzProtocol
+ * 
+ * @return SubGhzProtocol* 
+ */
 SubGhzProtocol* subghz_protocol_alloc();
 
+/** Free SubGhzProtocol
+ * 
+ * @param instance 
+ */
 void subghz_protocol_free(SubGhzProtocol* instance);
 
-void subghz_protocol_enable_dump(SubGhzProtocol* instance, SubGhzProtocolTextCallback callback, void* context);
-
+/** Outputting data from all parsers
+ * 
+ * @param instance - SubGhzProtocol instance
+ * @param callback - SubGhzProtocolTextCallback callback
+ * @param context
+ */
+void subghz_protocol_enable_dump(
+    SubGhzProtocol* instance,
+    SubGhzProtocolTextCallback callback,
+    void* context);
+
+/** File name rainbow table Nice Flor-S
+ * 
+ * @param instance - SubGhzProtocol instance
+ * @param file_name - "path/file_name"
+ */
+void subghz_protocol_load_nice_flor_s_file(SubGhzProtocol* instance, const char* file_name);
+
+/** File upload manufacture keys
+ * 
+ * @param instance - SubGhzProtocol instance
+ * @param file_name - "path/file_name"
+ */
 void subghz_protocol_load_keeloq_file(SubGhzProtocol* instance, const char* file_name);
 
+/** Restarting all parsers
+ * 
+ * @param instance - SubGhzProtocol instance
+ */
 void subghz_protocol_reset(SubGhzProtocol* instance);
 
+/** Loading data into all parsers
+ * 
+ * @param instance - SubGhzProtocol instance
+ * @param data - LevelPair data
+ */
 void subghz_protocol_parse(SubGhzProtocol* instance, LevelPair data);

+ 7 - 0
lib/fl_subghz/protocols/subghz_protocol_came.c

@@ -28,6 +28,11 @@ void subghz_protocol_came_free(SubGhzProtocolCame* instance) {
     free(instance);
 }
 
+/** Send bit 
+ * 
+ * @param instance - SubGhzProtocolCame instance
+ * @param bit - bit
+ */
 void subghz_protocol_came_send_bit(SubGhzProtocolCame* instance, uint8_t bit) {
     if (bit) {
         //send bit 1
@@ -88,6 +93,8 @@ void subghz_protocol_came_parse(SubGhzProtocolCame* instance, LevelPair data) {
                 if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
 
                     //ToDo out data display
+                    instance->common.serial = 0x0;
+                    instance->common.btn = 0x0;
                     if (instance->common.callback)
                         instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
                 }

+ 20 - 0
lib/fl_subghz/protocols/subghz_protocol_came.h

@@ -4,10 +4,30 @@
 
 typedef struct SubGhzProtocolCame SubGhzProtocolCame;
 
+/** Allocate SubGhzProtocolCame
+ * 
+ * @return SubGhzProtocolCame* 
+ */
 SubGhzProtocolCame* subghz_protocol_came_alloc();
 
+/** Free SubGhzProtocolCame
+ * 
+ * @param instance 
+ */
 void subghz_protocol_came_free(SubGhzProtocolCame* instance);
 
+/** Sends the key on the air
+ * 
+ * @param instance - SubGhzProtocolCame instance
+ * @param key - key send
+ * @param bit - count bit key
+ * @param repeat - repeat send key
+ */
 void subghz_protocol_came_send_key(SubGhzProtocolCame* instance, uint64_t key, uint8_t bit, uint8_t repeat);
 
+/** Parse accepted duration
+ * 
+ * @param instance - SubGhzProtocolCame instance
+ * @param data - LevelPair data
+ */
 void subghz_protocol_came_parse(SubGhzProtocolCame* instance, LevelPair data);

+ 14 - 8
lib/fl_subghz/protocols/subghz_protocol_common.c

@@ -6,11 +6,11 @@ void subghz_protocol_common_add_bit(SubGhzProtocolCommon *common, uint8_t bit){
     common->code_count_bit++;
 }
 
-uint8_t subghz_protocol_common_check_interval (SubGhzProtocolCommon *common, uint32_t interval, uint16_t interval_check) {
-    if ((interval_check >= (interval - common->te_delta))&&(interval_check <= (interval + common->te_delta))){
-        return 1;
+bool subghz_protocol_common_check_interval (SubGhzProtocolCommon *common, uint32_t duration, uint16_t duration_check) {
+    if ((duration_check >= (duration - common->te_delta))&&(duration_check <= (duration + common->te_delta))){
+        return true;
     } else {
-        return 0;
+        return false;
     }
 }
 
@@ -44,26 +44,32 @@ void subghz_protocol_common_to_str(SubGhzProtocolCommon* instance, string_t outp
                 output,
                 "Protocol %s, %d Bit\r\n"
                 " KEY:0x%lX%08lX\r\n"
-                " YEK:0x%lX%08lX\r\n",
+                " YEK:0x%lX%08lX\r\n"
+                " SN:0x%05lX BTN:%02X\r\n",
                 instance->name,
                 instance->code_count_bit,
                 code_found_hi,
                 code_found_lo,
                 code_found_reverse_hi,
-                code_found_reverse_lo
+                code_found_reverse_lo,
+                instance->serial,
+                instance->btn
             );
         } else {
             string_cat_printf(
                 output,
                 "Protocol %s, %d Bit\r\n"
                 " KEY:0x%lX%lX\r\n"
-                " YEK:0x%lX%lX\r\n",
+                " YEK:0x%lX%lX\r\n"
+                " SN:0x%05lX BTN:%02X\r\n",
                 instance->name,
                 instance->code_count_bit,
                 code_found_hi,
                 code_found_lo,
                 code_found_reverse_hi,
-                code_found_reverse_lo
+                code_found_reverse_lo,
+                instance->serial,
+                instance->btn
             );
         }
     }

+ 34 - 1
lib/fl_subghz/protocols/subghz_protocol_common.h

@@ -32,6 +32,8 @@ struct SubGhzProtocolCommon {
     uint16_t    te_last;
     uint8_t     header_count;
     uint16_t    cnt;
+    uint32_t    serial;
+    uint8_t     btn;
 
     /* Standard Callback for on rx complete event */
     SubGhzProtocolCommonCallback callback;
@@ -41,13 +43,44 @@ struct SubGhzProtocolCommon {
     SubGhzProtocolCommonToStr to_string;
 };
 
+
+/** Add data bit to code_found
+ * 
+ * @param common - SubGhzProtocolCommon common
+ * @param bit - add bit
+ */
 void subghz_protocol_common_add_bit(SubGhzProtocolCommon *common, uint8_t bit);
 
-uint8_t subghz_protocol_common_check_interval(SubGhzProtocolCommon *common, uint32_t interval, uint16_t interval_check);
+/** Checking that the duration is included in the interval
+ * 
+ * @param common - SubGhzProtocolCommon common
+ * @param duration duration reference
+ * @param duration_check duration checked
+ * @return true on success
+ */
+bool subghz_protocol_common_check_interval(SubGhzProtocolCommon *common, uint32_t duration, uint16_t duration_check);
 
+/** Bit-by-bit data mirroring
+ * 
+ * @param key - data to mirror
+ * @param count_bit number of data bits
+ * @return mirrored data
+ */
 uint64_t subghz_protocol_common_reverse_key(uint64_t key, uint8_t count_bit);
 
+
+/** Callback protocol
+ * 
+ * @param instance - SubGhzProtocolCommon* instance
+ * @param callback
+ * @param context
+ */
 void subghz_protocol_common_set_callback(SubGhzProtocolCommon* instance, SubGhzProtocolCommonCallback callback, void* context);
 
+/** outputting information from the parser
+ * 
+ * @param instance - SubGhzProtocolCommon* instance
+ * @param output   - output string
+ */
 void subghz_protocol_common_to_str(SubGhzProtocolCommon* instance, string_t output);
 

+ 40 - 41
lib/fl_subghz/protocols/subghz_protocol_keeloq.c

@@ -41,9 +41,9 @@ struct SubGhzProtocolKeeloq {
 };
 
 /** Simple Learning Encrypt
- * @param data - serial number (28bit)
+ * @param data - 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter
  * @param key - manufacture (64bit)
- * @return ?
+ * @return keelog encrypt data
  */
 inline uint32_t subghz_protocol_keeloq_encrypt(const uint32_t data, const uint64_t key) {
     uint32_t x = data, r;
@@ -53,9 +53,9 @@ inline uint32_t subghz_protocol_keeloq_encrypt(const uint32_t data, const uint64
 }
 
 /** Simple Learning Decrypt
- * @param data - serial number (28bit)
+ * @param data - keelog encrypt data
  * @param key - manufacture (64bit)
- * @return ?
+ * @return 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter
  */
 inline uint32_t subghz_protocol_keeloq_decrypt(const uint32_t data, const uint64_t key) {
     uint32_t x = data, r;
@@ -67,7 +67,7 @@ inline uint32_t subghz_protocol_keeloq_decrypt(const uint32_t data, const uint64
 /** Normal Learning
  * @param data - serial number (28bit)
  * @param key - manufacture (64bit)
- * @return ?
+ * @return manufacture for this serial number (64bit)
  */
 inline uint64_t subghz_protocol_keeloq_normal_learning(uint32_t data, const uint64_t key){
     uint32_t k1,k2;
@@ -116,6 +116,13 @@ void subghz_protocol_keeloq_add_manafacture_key(SubGhzProtocolKeeloq* instance,
     manufacture_code->type = type;
 }
 
+/** Checking the accepted code against the database manafacture key
+ * 
+ * @param instance SubGhzProtocolKeeloq instance
+ * @param fix fix part of the parcel
+ * @param hop hop encrypted part of the parcel
+ * @return true on successful search
+ */
 uint8_t subghz_protocol_keeloq_check_remote_controller_selector(SubGhzProtocolKeeloq* instance, uint32_t fix , uint32_t hop) {
     uint16_t end_serial = (uint16_t)(fix&0x3FF);
     uint8_t btn = (uint8_t)(fix>>28);
@@ -200,6 +207,10 @@ uint8_t subghz_protocol_keeloq_check_remote_controller_selector(SubGhzProtocolKe
     return 0;
 }
 
+/** Analysis of received data
+ * 
+ * @param instance SubGhzProtocolKeeloq instance
+ */
 void subghz_protocol_keeloq_check_remote_controller(SubGhzProtocolKeeloq* instance) {
     uint64_t key = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit);
     uint32_t key_fix = key >> 32;
@@ -211,9 +222,16 @@ void subghz_protocol_keeloq_check_remote_controller(SubGhzProtocolKeeloq* instan
     } else {
         subghz_protocol_keeloq_check_remote_controller_selector(instance, key_fix, key_hop);
     }
+    instance ->common.serial= key_fix&0x0FFFFF;
+    instance->common.btn = key_fix >> 28;
     if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
 }
 
+/** Send bit 
+ * 
+ * @param instance - SubGhzProtocolKeeloq instance
+ * @param bit - bit
+ */
 void subghz_protocol_keeloq_send_bit(SubGhzProtocolKeeloq* instance, uint8_t bit) {
     if (bit) {
         // send bit 1
@@ -297,8 +315,6 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, LevelPair data
                     //ToDo out data display
                     subghz_protocol_keeloq_check_remote_controller(instance);
 
-                    //Print_Code(&KEELOQ);
-                    //Reverse_Code(KEELOQ.Code);
                     instance->common.code_found = 0;
                     instance->common.code_count_bit = 0;
                     instance->common.header_count = 0;
@@ -329,7 +345,6 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, LevelPair data
 }
 
 void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t output) {
-    //snprintf(BufTX, sizeof(BufTX),"Protocol %s: %d Bit | KEY:0x%llX HEX  \n\r", common->Name_Protocol, common->Count_BIT, common->Code);
     uint32_t code_found_hi = instance->common.code_found >> 32;
     uint32_t code_found_lo = instance->common.code_found & 0x00000000ffffffff;
 
@@ -337,42 +352,26 @@ void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t outp
 
     uint32_t code_found_reverse_hi = code_found_reverse>>32;
     uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff;
-
-    if (code_found_hi>0) {
-        string_cat_printf(
-            output,
-            "Protocol %s, %d Bit\r\n"
-            " KEY:0x%lX%08lX\r\n"
-            " YEK:0x%lX%08lX\r\n",
-            instance->common.name,
-            instance->common.code_count_bit,
-            code_found_hi,
-            code_found_lo,
-            code_found_reverse_hi,
-            code_found_reverse_lo
-        );
-    } else {
-        string_cat_printf(
-            output,
-            "Protocol %s, %d Bit\r\n"
-            " KEY:0x%lX%lX\r\n"
-            " YEK:0x%lX%lX\r\n",
-            instance->common.name,
-            instance->common.code_count_bit,
-            code_found_hi,
-            code_found_lo,
-            code_found_reverse_hi,
-            code_found_reverse_lo
-        );
-    }
     string_cat_printf(
         output,
-        " MF:%s FIX:%lX\r\n"
-        " HOP:%lX CNT:%04X BTN:%02lX\r\n",
-        instance->manufacture_name,
+        "Protocol %s, %d Bit\r\n"
+        "KEY:0x%lX%lX\r\n"
+        "FIX:%lX MF:%s \r\n"
+        "HOP:%lX \r\n"
+        //"CNT:%04X BTN:%02lX\r\n",
+        "SN:%05lX CNT:%04X BTN:%02lX\r\n",
+        //"YEK:0x%lX%lX\r\n",
+        instance->common.name,
+        instance->common.code_count_bit,
+        code_found_hi,
+        code_found_lo,
+        //code_found_reverse_hi,
+        //code_found_reverse_lo
         code_found_reverse_hi,
+        instance->manufacture_name,
         code_found_reverse_lo,
-        instance->common.cnt, //need manufacture code
-        code_found_reverse_hi >> 28
+        instance->common.serial,
+        instance->common.cnt, 
+        instance->common.btn
     );
 }

+ 32 - 0
lib/fl_subghz/protocols/subghz_protocol_keeloq.h

@@ -4,14 +4,46 @@
 
 typedef struct SubGhzProtocolKeeloq SubGhzProtocolKeeloq;
 
+/** Allocate SubGhzProtocolKeeloq
+ * 
+ * @return SubGhzProtocolKeeloq* 
+ */
 SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc();
 
+/** Free SubGhzProtocolKeeloq
+ * 
+ * @param instance 
+ */
 void subghz_protocol_keeloq_free(SubGhzProtocolKeeloq* instance);
 
+/** Loading of manufacture keys
+ * 
+ * @param instance - SubGhzProtocolKeeloq instance
+ * @param name - key name
+ * @param key - manufacture (64bit)
+ * @param type - type manufacture key 
+ */
 void subghz_protocol_keeloq_add_manafacture_key(SubGhzProtocolKeeloq* instance, const char* name, uint64_t key, uint16_t type);
 
+/** Sends the key on the air
+ * 
+ * @param instance - SubGhzProtocolKeeloq instance
+ * @param key - key send
+ * @param bit - count bit key
+ * @param repeat - repeat send key
+ */
 void subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, uint64_t key, uint8_t bit, uint8_t repeat);
 
+/** Parse accepted duration
+ * 
+ * @param instance - SubGhzProtocolKeeloq instance
+ * @param data - LevelPair data
+ */
 void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, LevelPair data);
 
+/** Outputting information from the parser
+ * 
+ * @param instance - SubGhzProtocolKeeloq* instance
+ * @param output   - output string
+ */
 void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t output);

+ 6 - 0
lib/fl_subghz/protocols/subghz_protocol_nice_flo.c

@@ -27,6 +27,11 @@ void subghz_protocol_nice_flo_free(SubGhzProtocolNiceFlo* instance) {
     free(instance);
 }
 
+/** Send bit 
+ * 
+ * @param instance - SubGhzProtocolNiceFlo instance
+ * @param bit - bit
+ */
 void subghz_protocol_nice_flo_send_bit(SubGhzProtocolNiceFlo* instance, uint8_t bit) {
     if (bit) {
         //send bit 1
@@ -87,6 +92,7 @@ void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, LevelPair d
                 if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
 
                     //ToDo out data display
+                    //instance->common.serial = 0x12345;
                     if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
                 }
                 break;

+ 20 - 2
lib/fl_subghz/protocols/subghz_protocol_nice_flo.h

@@ -4,12 +4,30 @@
 
 typedef struct SubGhzProtocolNiceFlo SubGhzProtocolNiceFlo;
 
+/** Allocate SubGhzProtocolNiceFlo
+ * 
+ * @return SubGhzProtocolNiceFlo* 
+ */
 SubGhzProtocolNiceFlo* subghz_protocol_nice_flo_alloc();
 
+/** Free SubGhzProtocolNiceFlo
+ * 
+ * @param instance 
+ */
 void subghz_protocol_nice_flo_free(SubGhzProtocolNiceFlo* instance);
 
-void subghz_protocol_nice_flo_set_callback(SubGhzProtocolNiceFlo* instance, SubGhzProtocolCommonCallback callback, void* context);
-
+/** Sends the key on the air
+ * 
+ * @param instance - SubGhzProtocolNiceFlo instance
+ * @param key - key send
+ * @param bit - count bit key
+ * @param repeat - repeat send key
+ */
 void subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, uint64_t key, uint8_t bit, uint8_t repeat);
 
+/** Parse accepted duration
+ * 
+ * @param instance - SubGhzProtocolNiceFlo instance
+ * @param data - LevelPair data
+ */
 void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, LevelPair data);

+ 126 - 26
lib/fl_subghz/protocols/subghz_protocol_nice_flor_s.c

@@ -1,4 +1,7 @@
 #include "subghz_protocol_nice_flor_s.h"
+
+#include <furi.h>
+#include "file-worker.h"
 /*
  * https://phreakerclub.com/1615
  * https://phreakerclub.com/forum/showthread.php?t=2360
@@ -7,16 +10,18 @@
 
 struct SubGhzProtocolNiceFlorS {
     SubGhzProtocolCommon common;
+    const char* rainbow_table_file_name;
 };
 
 SubGhzProtocolNiceFlorS* subghz_protocol_nice_flor_s_alloc() {
     SubGhzProtocolNiceFlorS* instance = furi_alloc(sizeof(SubGhzProtocolNiceFlorS));
 
-    instance->common.name = "Nice FloR S";
+    instance->common.name = "Nice FloR-S";
     instance->common.code_min_count_bit_for_found = 52;
     instance->common.te_shot = 500;
     instance->common.te_long = 1000;
     instance->common.te_delta = 300;
+    instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nice_flor_s_to_str;
 
     return instance;
 }
@@ -26,8 +31,18 @@ void subghz_protocol_nice_flor_s_free(SubGhzProtocolNiceFlorS* instance) {
     free(instance);
 }
 
+void subghz_protocol_nice_flor_s_name_file(SubGhzProtocolNiceFlorS* instance, const char* name) {
+    instance->rainbow_table_file_name = name;
+    printf("Loading Nice FloR S rainbow table %s\r\n", name);
+}
+
+/** Send bit 
+ * 
+ * @param instance - SubGhzProtocolNiceFlorS instance
+ * @param bit - bit
+ */
 void subghz_protocol_nice_flor_s_send_bit(SubGhzProtocolNiceFlorS* instance, uint8_t bit) {
-    if (bit) {
+    if(bit) {
         //send bit 1
         SUBGHZ_TX_PIN_HIGTH();
         delay_us(instance->common.te_long);
@@ -42,33 +57,98 @@ void subghz_protocol_nice_flor_s_send_bit(SubGhzProtocolNiceFlorS* instance, uin
     }
 }
 
-void subghz_protocol_nice_flor_s_send_key(SubGhzProtocolNiceFlorS* instance, uint64_t key, uint8_t bit, uint8_t repeat) {
-    while (repeat--) {
+void subghz_protocol_nice_flor_s_send_key(
+    SubGhzProtocolNiceFlorS* instance,
+    uint64_t key,
+    uint8_t bit,
+    uint8_t repeat) {
+    while(repeat--) {
         //Send header
         SUBGHZ_TX_PIN_LOW();
         delay_us(instance->common.te_shot * 34);
         //Send Start Bit
         SUBGHZ_TX_PIN_HIGTH();
-        delay_us(instance->common.te_shot*3);
+        delay_us(instance->common.te_shot * 3);
         SUBGHZ_TX_PIN_LOW();
-        delay_us(instance->common.te_shot*3);
+        delay_us(instance->common.te_shot * 3);
         //Send key data
-        for (uint8_t i = bit; i > 0; i--) {
+        for(uint8_t i = bit; i > 0; i--) {
             subghz_protocol_nice_flor_s_send_bit(instance, bit_read(key, i - 1));
         }
         //Send Stop Bit
         SUBGHZ_TX_PIN_HIGTH();
-        delay_us(instance->common.te_shot*3);
+        delay_us(instance->common.te_shot * 3);
         SUBGHZ_TX_PIN_LOW();
-        delay_us(instance->common.te_shot*3);
+        delay_us(instance->common.te_shot * 3);
+    }
+}
+
+/** Read bytes from rainbow table
+ * 
+ * @param instance - SubGhzProtocolNiceFlorS* instance
+ * @param address  - address byte
+ * @return byte data
+ */
+uint8_t subghz_nice_flor_s_get_byte_in_file(SubGhzProtocolNiceFlorS* instance, uint32_t address) {
+    if(!instance->rainbow_table_file_name) 
+        return 0;
+
+    uint8_t buffer = 0;
+    FileWorker* file_worker = file_worker_alloc(true);
+    if(file_worker_open(file_worker, instance->rainbow_table_file_name, FSAM_READ, FSOM_OPEN_EXISTING)) {
+        file_worker_seek(file_worker, address, true);
+        file_worker_read(file_worker, &buffer, 1);
+        // bool res = file_worker_read(file_worker, &buffer, 1);
+        // furi_assert(res== true);
     }
+    file_worker_close(file_worker);
+    file_worker_free(file_worker);
+
+    return buffer;
+}
+
+/** Decrypt protocol Nice Flor S
+ * 
+ * @param instance - SubGhzProtocolNiceFlorS* instance
+ */
+void subghz_nice_flor_s_decoder_decrypt(SubGhzProtocolNiceFlorS* instance) {
+    /*
+    * Packet format Nice Flor-s: START-P0-P1-P2-P3-P4-P5-P6-P7-STOP
+    * P0 (4-bit)    - button positional code - 1:0x1, 2:0x2, 3:0x4, 4:0x8;
+    * P1 (4-bit)    - batch repetition number, calculated by the formula:
+    * P1 = 0xF ^ P0 ^ n; where n changes from 1 to 15, then 0, and then in a circle
+    * key 1: {0xF,0xC,0xD,0xA,0xB,0x8,0x9,0x6,0x7,0x4,0x5,0x2,0x3,0x0,0x1,0xE};
+    * key 2: {0xC,0xF,0xE,0x9,0x8,0xB,0xA,0x5,0x4,0x7,0x6,0x1,0x0,0x3,0x2,0xD};
+    * key 3: {0xA,0x9,0x8,0xF,0xE,0xD,0xC,0x3,0x2,0x1,0x0,0x7,0x6,0x5,0x4,0xB};
+    * P2 (4-bit)    - part of the serial number, P2 = (K ^ S3) & 0xF;
+    * P3 (byte)     - the major part of the encrypted index
+    * P4 (byte)     - the low-order part of the encrypted index
+    * P5 (byte)     - part of the serial number, P5 = K ^ S2;
+    * P6 (byte)     - part of the serial number, P6 = K ^ S1;
+    * P7 (byte)     - part of the serial number, P7 = K ^ S0;
+    * K (byte)      - depends on P3 and P4, K = Fk(P3, P4);
+    * S3,S2,S1,S0   - serial number of the console 28 bit.
+    */
+
+    uint16_t p3p4 = (uint16_t)(instance->common.code_found >> 24);
+    instance->common.cnt = subghz_nice_flor_s_get_byte_in_file(instance,p3p4*2) << 8 | subghz_nice_flor_s_get_byte_in_file(instance,p3p4*2+1); //nice_flor_srainbow_table_for_search[p3p4]; тут надо считать поле с файла причем адрес надо у множить на 2
+    uint8_t k =(uint8_t)(p3p4 & 0x00FF) ^subghz_nice_flor_s_get_byte_in_file(instance,(0x20000 |(instance->common.cnt &0x00ff))); //nice_flor_srainbow_table_for_search[0x10000|subghz_protocol_nice_flor_s.cnt & 0x00ff];
+
+    uint8_t s3 = ((uint8_t)(instance->common.code_found >> 40) ^ k) & 0x0f;
+    uint8_t s2 = ((uint8_t)(instance->common.code_found >> 16) ^ k);
+    uint8_t s1 = ((uint8_t)(instance->common.code_found >> 8) ^ k);
+    uint8_t s0 = ((uint8_t)(instance->common.code_found) ^ k);
+    instance->common.serial = s3 << 24 | s2 << 16 | s1 << 8 | s0;
+
+    instance->common.btn = (instance->common.code_found >> 48) & 0x0f;
+    if(instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
 }
 
 void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelPair data) {
-    switch (instance->common.parser_step) {
+    switch(instance->common.parser_step) {
     case 0:
-        if ((data.level == ApiHalSubGhzCaptureLevelLow)
-                && (DURATION_DIFF(data.duration,instance->common.te_shot * 38)< instance->common.te_delta * 38)) {
+        if((data.level == ApiHalSubGhzCaptureLevelLow) 
+            && (DURATION_DIFF(data.duration, instance->common.te_shot * 38) < instance->common.te_delta * 38)) {
             //Found start header Nice Flor-S
             instance->common.parser_step = 1;
         } else {
@@ -76,8 +156,8 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelP
         }
         break;
     case 1:
-        if ((data.level == ApiHalSubGhzCaptureLevelHigh)
-                && (DURATION_DIFF(data.duration,instance->common.te_shot * 3)< instance->common.te_delta * 3)) {
+        if((data.level == ApiHalSubGhzCaptureLevelHigh) 
+            && (DURATION_DIFF(data.duration, instance->common.te_shot * 3) < instance->common.te_delta * 3)) {
             //Found next header Nice Flor-S
             instance->common.parser_step = 2;
         } else {
@@ -85,8 +165,8 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelP
         }
         break;
     case 2:
-        if ((data.level == ApiHalSubGhzCaptureLevelLow)
-                && (DURATION_DIFF(data.duration,instance->common.te_shot * 3)< instance->common.te_delta * 3)) {
+        if((data.level == ApiHalSubGhzCaptureLevelLow) 
+            && (DURATION_DIFF(data.duration, instance->common.te_shot * 3) < instance->common.te_delta * 3)) {
             //Found header Nice Flor-S
             instance->common.parser_step = 3;
             instance->common.code_found = 0;
@@ -96,14 +176,13 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelP
         }
         break;
     case 3:
-        if (data.level == ApiHalSubGhzCaptureLevelHigh) {
-            if(DURATION_DIFF(data.duration,instance->common.te_shot*3) < instance->common.te_delta){
+        if(data.level == ApiHalSubGhzCaptureLevelHigh) {
+            if(DURATION_DIFF(data.duration, instance->common.te_shot * 3) < instance->common.te_delta) {
                 //Found STOP bit
                 instance->common.parser_step = 0;
-                if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
-
+                if(instance->common.code_count_bit >=instance->common.code_min_count_bit_for_found) {
                     //ToDo out data display
-                    if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
+                    subghz_nice_flor_s_decoder_decrypt(instance);
                 }
                 break;
             } else {
@@ -114,13 +193,14 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelP
         }
         break;
     case 4:
-        if (data.level == ApiHalSubGhzCaptureLevelLow) {
-            if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot) < instance->common.te_delta)
-                    && (DURATION_DIFF(data.duration,instance->common.te_long)< instance->common.te_delta)) {
+        if(data.level == ApiHalSubGhzCaptureLevelLow) {
+            if((DURATION_DIFF(instance->common.te_last, instance->common.te_shot) < instance->common.te_delta) 
+                &&(DURATION_DIFF(data.duration, instance->common.te_long) < instance->common.te_delta)) {
                 subghz_protocol_common_add_bit(&instance->common, 0);
                 instance->common.parser_step = 3;
-            } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta)
-                    && (DURATION_DIFF(data.duration,instance->common.te_shot)< instance->common.te_delta)) {
+            } else if(
+                (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta) 
+                    &&(DURATION_DIFF(data.duration, instance->common.te_shot) < instance->common.te_delta)) {
                 subghz_protocol_common_add_bit(&instance->common, 1);
                 instance->common.parser_step = 3;
             } else
@@ -131,3 +211,23 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelP
         break;
     }
 }
+
+void subghz_protocol_nice_flor_s_to_str(SubGhzProtocolNiceFlorS* instance, string_t output) {
+    uint32_t code_found_hi = instance->common.code_found >> 32;
+    uint32_t code_found_lo = instance->common.code_found & 0x00000000ffffffff;
+
+    string_cat_printf(
+        output,
+        "Protocol %s, %d Bit\r\n"
+        " KEY:0x%lX%08lX\r\n"
+        " SN:%05lX\r\n"
+        " CNT:%04X BTN:%02lX\r\n",
+        instance->common.name,
+        instance->common.code_count_bit,
+        code_found_hi,
+        code_found_lo,
+        instance->common.serial,
+        instance->common.cnt,
+        instance->common.btn
+    );
+}

+ 33 - 1
lib/fl_subghz/protocols/subghz_protocol_nice_flor_s.h

@@ -4,12 +4,44 @@
 
 typedef struct SubGhzProtocolNiceFlorS SubGhzProtocolNiceFlorS;
 
+/** Allocate SubGhzProtocolNiceFlorS
+ * 
+ * @return SubGhzProtocolNiceFlorS* 
+ */
 SubGhzProtocolNiceFlorS* subghz_protocol_nice_flor_s_alloc();
 
+/** Free SubGhzProtocolNiceFlorS
+ * 
+ * @param instance 
+ */
 void subghz_protocol_nice_flor_s_free(SubGhzProtocolNiceFlorS* instance);
 
-void subghz_protocol_nice_flor_s_set_callback(SubGhzProtocolNiceFlorS* instance, SubGhzProtocolCommonCallback callback, void* context);
+/** File name rainbow table Nice Flor-S
+ * 
+ * @param instance - SubGhzProtocolNiceFlorS instance
+ * @param file_name - "path/file_name"
+ */
+void subghz_protocol_nice_flor_s_name_file(SubGhzProtocolNiceFlorS* instance, const char* name);
 
+/** Sends the key on the air
+ * 
+ * @param instance - SubGhzProtocolNiceFlorS instance
+ * @param key - key send
+ * @param bit - count bit key
+ * @param repeat - repeat send key
+ */
 void subghz_protocol_nice_flor_s_send_key(SubGhzProtocolNiceFlorS* instance, uint64_t key, uint8_t bit, uint8_t repeat);
 
+/** Parse accepted duration
+ * 
+ * @param instance - SubGhzProtocolNiceFlorS instance
+ * @param data - LevelPair data
+ */
 void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelPair data);
+
+/** Outputting information from the parser
+ * 
+ * @param instance - SubGhzProtocolNiceFlorS* instance
+ * @param output   - output string
+ */
+void subghz_protocol_nice_flor_s_to_str(SubGhzProtocolNiceFlorS* instance, string_t output);

+ 7 - 0
lib/fl_subghz/protocols/subghz_protocol_princeton.c

@@ -27,6 +27,11 @@ void subghz_protocol_princeton_free(SubGhzProtocolPrinceton* instance) {
     free(instance);
 }
 
+/** Send bit 
+ * 
+ * @param instance - SubGhzProtocolPrinceton instance
+ * @param bit - bit
+ */
 void subghz_protocol_princeton_send_bit(SubGhzProtocolPrinceton* instance, uint8_t bit) {
     if (bit) {
         //send bit 1
@@ -83,6 +88,8 @@ void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, LevelPai
                 instance->common.parser_step = 1;
                 if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
                     //ToDo out data display
+                    instance->common.serial = instance->common.code_found >> 4;
+                    instance->common.btn = (uint8_t)instance->common.code_found & 0x00000F;
                     if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
                 }
                 instance->common.code_found = 0;

+ 26 - 1
lib/fl_subghz/protocols/subghz_protocol_princeton.h

@@ -4,12 +4,37 @@
 
 typedef struct SubGhzProtocolPrinceton SubGhzProtocolPrinceton;
 
+/** Allocate SubGhzProtocolPrinceton
+ * 
+ * @return SubGhzProtocolPrinceton* 
+ */
 SubGhzProtocolPrinceton* subghz_protocol_princeton_alloc();
 
+/** Free SubGhzProtocolPrinceton
+ * 
+ * @param instance 
+ */
 void subghz_protocol_princeton_free(SubGhzProtocolPrinceton* instance);
 
+/** Sends the key on the air
+ * 
+ * @param instance - SubGhzProtocolPrinceton instance
+ * @param key - key send
+ * @param bit - count bit key
+ * @param repeat - repeat send key
+ */
 void subghz_protocol_princeton_send_key(SubGhzProtocolPrinceton* instance, uint64_t key, uint8_t bit, uint8_t repeat);
 
+/** Parse accepted duration
+ * 
+ * @param instance - SubGhzProtocolPrinceton instance
+ * @param data - LevelPair data
+ */
 void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, LevelPair data);
 
-void subghz_protocol_princeton_to_str(SubGhzProtocolPrinceton* instance, string_t output);
+/** Outputting information from the parser
+ * 
+ * @param instance - SubGhzProtocolPrinceton* instance
+ * @param output   - output string
+ */
+//void subghz_protocol_princeton_to_str(SubGhzProtocolPrinceton* instance, string_t output);

+ 11 - 0
lib/fl_subghz/subghz_worker.c

@@ -15,6 +15,12 @@ struct SubGhzWorker {
     void* context;
 };
 
+/** Rx callback timer
+ * 
+ * @param level received signal level
+ * @param duration received signal duration
+ * @param context 
+ */
 void subghz_worker_rx_callback(
     ApiHalSubGhzCaptureLevel level,
     uint32_t duration,
@@ -34,6 +40,11 @@ void subghz_worker_rx_callback(
     portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
 }
 
+/** Worker callback thread
+ * 
+ * @param context 
+ * @return exit code 
+ */
 static int32_t subghz_worker_thread_callback(void* context) {
     SubGhzWorker* instance = context;
 

+ 31 - 0
lib/fl_subghz/subghz_worker.h

@@ -10,16 +10,47 @@ typedef void (*SubGhzWorkerPairCallback)(void* context, LevelPair pair);
 
 void subghz_worker_rx_callback(ApiHalSubGhzCaptureLevel level, uint32_t duration, void* context);
 
+/** Allocate SubGhzWorker
+ * 
+ * @return SubGhzWorker* 
+ */
 SubGhzWorker* subghz_worker_alloc();
 
+/** Free SubGhzWorker
+ * 
+ * @param instance SubGhzWorker instance
+ */
 void subghz_worker_free(SubGhzWorker* instance);
 
+/** Overrun callback SubGhzWorker
+ * 
+ * @param instance SubGhzWorker instance
+ * @param callback SubGhzWorkerOverrunCallback callback
+ */
 void subghz_worker_set_overrun_callback(SubGhzWorker* instance, SubGhzWorkerOverrunCallback callback);
 
+/** Pair callback SubGhzWorker
+ * 
+ * @param instance SubGhzWorker instance
+ * @param callback SubGhzWorkerOverrunCallback callback
+ */
 void subghz_worker_set_pair_callback(SubGhzWorker* instance, SubGhzWorkerPairCallback callback);
 
+/** Context callback SubGhzWorker
+ * 
+ * @param instance SubGhzWorker instance
+ * @param context 
+ */
 void subghz_worker_set_context(SubGhzWorker* instance, void* context);
 
+/** Start SubGhzWorker
+ * 
+ * @param instance SubGhzWorker instance
+ */
 void subghz_worker_start(SubGhzWorker* instance);
 
+/** Stop SubGhzWorker
+ * 
+ * @param instance SubGhzWorker instance
+ */
 void subghz_worker_stop(SubGhzWorker* instance);