diff --git a/applications/applications.c b/applications/applications.c index 6d506a0c..62b934b9 100644 --- a/applications/applications.c +++ b/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 diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index 173e1b42..5cf95e2d 100644 --- a/applications/subghz/subghz_cli.c +++ b/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); diff --git a/applications/subghz/views/subghz_capture.c b/applications/subghz/views/subghz_capture.c index 075468a5..91fab068 100644 --- a/applications/subghz/views/subghz_capture.c +++ b/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); diff --git a/lib/fl_subghz/protocols/subghz_protocol.c b/lib/fl_subghz/protocols/subghz_protocol.c index 39172307..0d62e753 100644 --- a/lib/fl_subghz/protocols/subghz_protocol.c +++ b/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"); diff --git a/lib/fl_subghz/protocols/subghz_protocol.h b/lib/fl_subghz/protocols/subghz_protocol.h index c39c0cfe..8cd3172f 100644 --- a/lib/fl_subghz/protocols/subghz_protocol.h +++ b/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); diff --git a/lib/fl_subghz/protocols/subghz_protocol_came.c b/lib/fl_subghz/protocols/subghz_protocol_came.c index 8a016b8a..4854a2a1 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_came.c +++ b/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); } diff --git a/lib/fl_subghz/protocols/subghz_protocol_came.h b/lib/fl_subghz/protocols/subghz_protocol_came.h index 78557513..51783e4e 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_came.h +++ b/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); diff --git a/lib/fl_subghz/protocols/subghz_protocol_common.c b/lib/fl_subghz/protocols/subghz_protocol_common.c index b3fd7e29..a973e5d3 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_common.c +++ b/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 ); } } diff --git a/lib/fl_subghz/protocols/subghz_protocol_common.h b/lib/fl_subghz/protocols/subghz_protocol_common.h index d8e029d6..e1d608d3 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_common.h +++ b/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); diff --git a/lib/fl_subghz/protocols/subghz_protocol_keeloq.c b/lib/fl_subghz/protocols/subghz_protocol_keeloq.c index 4ac01e75..cfc0478f 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_keeloq.c +++ b/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 ); } \ No newline at end of file diff --git a/lib/fl_subghz/protocols/subghz_protocol_keeloq.h b/lib/fl_subghz/protocols/subghz_protocol_keeloq.h index 363835cf..9a429d39 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_keeloq.h +++ b/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); diff --git a/lib/fl_subghz/protocols/subghz_protocol_nice_flo.c b/lib/fl_subghz/protocols/subghz_protocol_nice_flo.c index d8ba71e9..59bf121f 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_nice_flo.c +++ b/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; diff --git a/lib/fl_subghz/protocols/subghz_protocol_nice_flo.h b/lib/fl_subghz/protocols/subghz_protocol_nice_flo.h index d9938ef7..d19de3d9 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_nice_flo.h +++ b/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); diff --git a/lib/fl_subghz/protocols/subghz_protocol_nice_flor_s.c b/lib/fl_subghz/protocols/subghz_protocol_nice_flor_s.c index 306aa6c5..726dd3f0 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_nice_flor_s.c +++ b/lib/fl_subghz/protocols/subghz_protocol_nice_flor_s.c @@ -1,4 +1,7 @@ #include "subghz_protocol_nice_flor_s.h" + +#include +#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 + ); +} \ No newline at end of file diff --git a/lib/fl_subghz/protocols/subghz_protocol_nice_flor_s.h b/lib/fl_subghz/protocols/subghz_protocol_nice_flor_s.h index 34f8fd11..b0e2951a 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_nice_flor_s.h +++ b/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); diff --git a/lib/fl_subghz/protocols/subghz_protocol_princeton.c b/lib/fl_subghz/protocols/subghz_protocol_princeton.c index 66b92ab9..a83197f4 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_princeton.c +++ b/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; diff --git a/lib/fl_subghz/protocols/subghz_protocol_princeton.h b/lib/fl_subghz/protocols/subghz_protocol_princeton.h index 89f3b341..291a2567 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_princeton.h +++ b/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); diff --git a/lib/fl_subghz/subghz_worker.c b/lib/fl_subghz/subghz_worker.c index afc1f21e..a1574a3e 100644 --- a/lib/fl_subghz/subghz_worker.c +++ b/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; diff --git a/lib/fl_subghz/subghz_worker.h b/lib/fl_subghz/subghz_worker.h index d9b6d0ca..58316341 100644 --- a/lib/fl_subghz/subghz_worker.h +++ b/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);