diff --git a/applications/applications.c b/applications/applications.c index cd7e9f4e1b3..9aa3795dfce 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -39,6 +39,7 @@ extern int32_t music_player_app(void* p); // On system start hooks declaration extern void bt_cli_init(); +extern void crypto_cli_init(); extern void ibutton_cli_init(); extern void irda_cli_init(); extern void lfrfid_cli_init(); @@ -171,6 +172,9 @@ const size_t FLIPPER_APPS_COUNT = sizeof(FLIPPER_APPS) / sizeof(FlipperApplicati // On system start hooks const FlipperOnStartHook FLIPPER_ON_SYSTEM_START[] = { +#ifdef SRV_CLI + crypto_cli_init, +#endif irda_cli_init, #ifdef APP_NFC nfc_cli_init, diff --git a/applications/bt/bt_debug_app/bt_debug_app.c b/applications/bt/bt_debug_app/bt_debug_app.c index 1511e84f125..9033310726d 100755 --- a/applications/bt/bt_debug_app/bt_debug_app.c +++ b/applications/bt/bt_debug_app/bt_debug_app.c @@ -1,4 +1,5 @@ #include "bt_debug_app.h" +#include enum BtDebugSubmenuIndex { BtDebugSubmenuIndexCarrierTest, @@ -25,6 +26,10 @@ uint32_t bt_debug_start_view(void* context) { BtDebugApp* bt_debug_app_alloc() { BtDebugApp* app = furi_alloc(sizeof(BtDebugApp)); + + // Load settings + bt_settings_load(&app->settings); + // Gui app->gui = furi_record_open("gui"); @@ -88,7 +93,15 @@ void bt_debug_app_free(BtDebugApp* app) { int32_t bt_debug_app(void* p) { BtDebugApp* app = bt_debug_app_alloc(); + // Stop advertising + furi_hal_bt_stop_advertising(); + view_dispatcher_run(app->view_dispatcher); + + // Restart advertising + if(app->settings.enabled) { + furi_hal_bt_start_advertising(); + } bt_debug_app_free(app); return 0; } diff --git a/applications/bt/bt_service/bt.c b/applications/bt/bt_service/bt.c index 09094d17de5..d50cdf0e9ba 100755 --- a/applications/bt/bt_service/bt.c +++ b/applications/bt/bt_service/bt.c @@ -3,13 +3,6 @@ #define BT_SERVICE_TAG "BT" -// static void bt_update_statusbar(void* arg) { -// furi_assert(arg); -// Bt* bt = arg; -// BtMessage m = {.type = BtMessageTypeUpdateStatusbar}; -// furi_check(osMessageQueuePut(bt->message_queue, &m, 0, osWaitForever) == osOK); -// } - static void bt_draw_statusbar_callback(Canvas* canvas, void* context) { canvas_draw_icon(canvas, 0, 0, &I_Bluetooth_5x8); } @@ -42,10 +35,6 @@ Bt* bt_alloc() { // Alloc queue bt->message_queue = osMessageQueueNew(8, sizeof(BtMessage), NULL); - // doesn't make sense if we waiting for transition on service start - // bt->update_status_timer = osTimerNew(bt_update_statusbar, osTimerPeriodic, bt, NULL); - // osTimerStart(bt->update_status_timer, 4000); - // Setup statusbar view port bt->statusbar_view_port = bt_statusbar_view_port_alloc(); // Gui @@ -67,25 +56,28 @@ int32_t bt_srv() { FURI_LOG_E(BT_SERVICE_TAG, "Core2 startup failed"); } else { view_port_enabled_set(bt->statusbar_view_port, true); - if(bt->bt_settings.enabled) { - bool bt_app_started = furi_hal_bt_start_app(); - if(!bt_app_started) { - FURI_LOG_E(BT_SERVICE_TAG, "BT App start failed"); - } else { - FURI_LOG_I(BT_SERVICE_TAG, "BT App started"); + if(furi_hal_bt_init_app()) { + FURI_LOG_I(BT_SERVICE_TAG, "BLE stack started"); + if(bt->bt_settings.enabled) { + furi_hal_bt_start_advertising(); + FURI_LOG_I(BT_SERVICE_TAG, "Start advertising"); } + } else { + FURI_LOG_E(BT_SERVICE_TAG, "BT App start failed"); } } + // Update statusbar + view_port_enabled_set(bt->statusbar_view_port, furi_hal_bt_is_active()); BtMessage message; while(1) { furi_check(osMessageQueueGet(bt->message_queue, &message, NULL, osWaitForever) == osOK); if(message.type == BtMessageTypeUpdateStatusbar) { // Update statusbar - view_port_enabled_set(bt->statusbar_view_port, furi_hal_bt_is_alive()); + view_port_enabled_set(bt->statusbar_view_port, furi_hal_bt_is_active()); } else if(message.type == BtMessageTypeUpdateBatteryLevel) { // Update battery level - if(furi_hal_bt_is_alive()) { + if(furi_hal_bt_is_active()) { battery_svc_update_level(message.data.battery_level); } } else if(message.type == BtMessageTypePinCodeShow) { diff --git a/applications/bt/bt_service/bt.h b/applications/bt/bt_service/bt.h index 0bde59b825a..ccf5e501cfd 100644 --- a/applications/bt/bt_service/bt.h +++ b/applications/bt/bt_service/bt.h @@ -9,6 +9,8 @@ extern "C" { typedef struct Bt Bt; +void bt_update_statusbar(Bt* bt); + void bt_update_battery_level(Bt* bt, uint8_t battery_level); bool bt_pin_code_show(Bt* bt, uint32_t pin_code); diff --git a/applications/bt/bt_service/bt_api.c b/applications/bt/bt_service/bt_api.c index a12ac2684d7..db7098711b5 100755 --- a/applications/bt/bt_service/bt_api.c +++ b/applications/bt/bt_service/bt_api.c @@ -1,6 +1,12 @@ #include "bt.h" #include "bt_i.h" +void bt_update_statusbar(Bt* bt) { + furi_assert(bt); + BtMessage message = {.type = BtMessageTypeUpdateStatusbar}; + furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); +} + void bt_update_battery_level(Bt* bt, uint8_t battery_level) { furi_assert(bt); BtMessage message = { diff --git a/applications/bt/bt_service/bt_i.h b/applications/bt/bt_service/bt_i.h index fbc0f378bb2..fa78811ac0c 100644 --- a/applications/bt/bt_service/bt_i.h +++ b/applications/bt/bt_service/bt_i.h @@ -32,7 +32,6 @@ typedef struct { struct Bt { BtSettings bt_settings; osMessageQueueId_t message_queue; - osTimerId_t update_status_timer; Gui* gui; ViewPort* statusbar_view_port; DialogsApp* dialogs; diff --git a/applications/bt/bt_settings_app/bt_settings_app.c b/applications/bt/bt_settings_app/bt_settings_app.c index 6eaf37610d0..f3e6093706b 100755 --- a/applications/bt/bt_settings_app/bt_settings_app.c +++ b/applications/bt/bt_settings_app/bt_settings_app.c @@ -31,12 +31,11 @@ BtSettingsApp* bt_settings_app_alloc() { view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - app->submenu = submenu_alloc(); + app->var_item_list = variable_item_list_alloc(); view_dispatcher_add_view( - app->view_dispatcher, BtSettingsAppViewSubmenu, submenu_get_view(app->submenu)); - app->dialog_ex = dialog_ex_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, BtSettingsAppViewDialogEx, dialog_ex_get_view(app->dialog_ex)); + app->view_dispatcher, + BtSettingsAppViewVarItemList, + variable_item_list_get_view(app->var_item_list)); scene_manager_next_scene(app->scene_manager, BtSettingsAppSceneStart); return app; @@ -44,12 +43,9 @@ BtSettingsApp* bt_settings_app_alloc() { void bt_settings_app_free(BtSettingsApp* app) { furi_assert(app); - // Submenu - view_dispatcher_remove_view(app->view_dispatcher, BtSettingsAppViewSubmenu); - submenu_free(app->submenu); - // Dialog - view_dispatcher_remove_view(app->view_dispatcher, BtSettingsAppViewDialogEx); - dialog_ex_free(app->dialog_ex); + // Variable item list + view_dispatcher_remove_view(app->view_dispatcher, BtSettingsAppViewVarItemList); + variable_item_list_free(app->var_item_list); // View dispatcher view_dispatcher_free(app->view_dispatcher); scene_manager_free(app->scene_manager); diff --git a/applications/bt/bt_settings_app/bt_settings_app.h b/applications/bt/bt_settings_app/bt_settings_app.h old mode 100644 new mode 100755 index cfbea1d0a44..0cb2b0be116 --- a/applications/bt/bt_settings_app/bt_settings_app.h +++ b/applications/bt/bt_settings_app/bt_settings_app.h @@ -6,8 +6,7 @@ #include #include -#include -#include +#include #include "../bt_settings.h" #include "scenes/bt_settings_scene.h" @@ -17,11 +16,7 @@ typedef struct { Gui* gui; SceneManager* scene_manager; ViewDispatcher* view_dispatcher; - Submenu* submenu; - DialogEx* dialog_ex; + VariableItemList* var_item_list; } BtSettingsApp; -typedef enum { - BtSettingsAppViewSubmenu, - BtSettingsAppViewDialogEx, -} BtSettingsAppView; +typedef enum { BtSettingsAppViewVarItemList } BtSettingsAppView; diff --git a/applications/bt/bt_settings_app/scenes/bt_settings_scene_config.h b/applications/bt/bt_settings_app/scenes/bt_settings_scene_config.h index e7d19b1a747..6aa23850251 100644 --- a/applications/bt/bt_settings_app/scenes/bt_settings_scene_config.h +++ b/applications/bt/bt_settings_app/scenes/bt_settings_scene_config.h @@ -1,2 +1 @@ ADD_SCENE(bt_settings, start, Start) -ADD_SCENE(bt_settings, disable_dialog, DisableDialog) diff --git a/applications/bt/bt_settings_app/scenes/bt_settings_scene_disable_dialog.c b/applications/bt/bt_settings_app/scenes/bt_settings_scene_disable_dialog.c deleted file mode 100755 index ac2d5f44e08..00000000000 --- a/applications/bt/bt_settings_app/scenes/bt_settings_scene_disable_dialog.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "../bt_settings_app.h" -#include -#include - -static void bt_setting_disable_dialog_callback(DialogExResult result, void* context) { - BtSettingsApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, result); -} - -void bt_settings_scene_disable_dialog_on_enter(void* context) { - BtSettingsApp* app = context; - DialogEx* dialog_ex = app->dialog_ex; - dialog_ex_set_text( - dialog_ex, "Reboot device\nto disable Bluetooth", 64, 32, AlignCenter, AlignCenter); - dialog_ex_set_left_button_text(dialog_ex, "Back"); - dialog_ex_set_right_button_text(dialog_ex, "Reboot"); - dialog_ex_set_result_callback(dialog_ex, bt_setting_disable_dialog_callback); - dialog_ex_set_context(dialog_ex, app); - - view_dispatcher_switch_to_view(app->view_dispatcher, BtSettingsAppViewDialogEx); -} - -bool bt_settings_scene_disable_dialog_on_event(void* context, SceneManagerEvent event) { - BtSettingsApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == DialogExResultLeft) { - scene_manager_previous_scene(app->scene_manager); - consumed = true; - } else if(event.event == DialogExResultRight) { - app->settings.enabled = false; - bt_settings_save(&app->settings); - furi_hal_boot_set_mode(FuriHalBootModeNormal); - furi_hal_power_reset(); - } - } - return consumed; -} - -void bt_settings_scene_disable_dialog_on_exit(void* context) { - BtSettingsApp* app = context; - dialog_ex_clean(app->dialog_ex); -} diff --git a/applications/bt/bt_settings_app/scenes/bt_settings_scene_start.c b/applications/bt/bt_settings_app/scenes/bt_settings_scene_start.c index faf1d3a1fa0..6e021148062 100755 --- a/applications/bt/bt_settings_app/scenes/bt_settings_scene_start.c +++ b/applications/bt/bt_settings_app/scenes/bt_settings_scene_start.c @@ -1,28 +1,45 @@ #include "../bt_settings_app.h" #include "furi-hal-bt.h" -enum BtSettingsAppStartSubmenuIndex { - BtSettingsAppStartSubmenuIndexEnable, +enum BtSetting { + BtSettingOff, + BtSettingOn, + BtSettingNum, }; -static void bt_settings_scene_start_submenu_callback(void* context, uint32_t index) { - BtSettingsApp* app = context; +const char* const bt_settings_text[BtSettingNum] = { + "Off", + "On", +}; + +static void bt_settings_scene_start_var_list_change_callback(VariableItem* item) { + BtSettingsApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + + variable_item_set_current_value_text(item, bt_settings_text[index]); view_dispatcher_send_custom_event(app->view_dispatcher, index); } void bt_settings_scene_start_on_enter(void* context) { BtSettingsApp* app = context; - Submenu* submenu = app->submenu; - - const char* submenu_label = app->settings.enabled ? "Disable" : "Enable"; - submenu_add_item( - submenu, - submenu_label, - BtSettingsAppStartSubmenuIndexEnable, - bt_settings_scene_start_submenu_callback, + VariableItemList* var_item_list = app->var_item_list; + + VariableItem* item; + item = variable_item_list_add( + var_item_list, + "Bluetooth", + BtSettingNum, + bt_settings_scene_start_var_list_change_callback, app); + if(app->settings.enabled) { + variable_item_set_current_value_index(item, BtSettingOn); + variable_item_set_current_value_text(item, bt_settings_text[BtSettingOn]); + } else { + variable_item_set_current_value_index(item, BtSettingOff); + variable_item_set_current_value_text(item, bt_settings_text[BtSettingOff]); + } - view_dispatcher_switch_to_view(app->view_dispatcher, BtSettingsAppViewSubmenu); + view_dispatcher_switch_to_view(app->view_dispatcher, BtSettingsAppViewVarItemList); } bool bt_settings_scene_start_on_event(void* context, SceneManagerEvent event) { @@ -30,27 +47,19 @@ bool bt_settings_scene_start_on_event(void* context, SceneManagerEvent event) { bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - if(event.event == BtSettingsAppStartSubmenuIndexEnable) { - if(!app->settings.enabled) { - app->settings.enabled = true; - furi_hal_bt_start_app(); - submenu_clean(app->submenu); - submenu_add_item( - app->submenu, - "Disable", - BtSettingsAppStartSubmenuIndexEnable, - bt_settings_scene_start_submenu_callback, - app); - } else { - scene_manager_next_scene(app->scene_manager, BtSettingsAppSceneDisableDialog); - } - consumed = true; + if(event.event == BtSettingOn) { + furi_hal_bt_start_advertising(); + app->settings.enabled = true; + } else if(event.event == BtSettingOff) { + app->settings.enabled = false; + furi_hal_bt_stop_advertising(); } + consumed = true; } return consumed; } void bt_settings_scene_start_on_exit(void* context) { BtSettingsApp* app = context; - submenu_clean(app->submenu); + variable_item_list_clean(app->var_item_list); } diff --git a/applications/cli/cli_commands.c b/applications/cli/cli_commands.c index 5d1afc1225a..f03c12e719a 100644 --- a/applications/cli/cli_commands.c +++ b/applications/cli/cli_commands.c @@ -7,6 +7,15 @@ #include #include +#define ENCLAVE_SIGNATURE_KEY_SLOT 1 +#define ENCLAVE_SIGNATURE_SIZE 16 +static const uint8_t enclave_signature_iv[16] = + {0x32, 0xe6, 0xa7, 0x85, 0x20, 0xae, 0x0b, 0xf0, 0x00, 0xb6, 0x30, 0x9b, 0xd5, 0x42, 0x9e, 0xa6}; +static const uint8_t enclave_signature_input[ENCLAVE_SIGNATURE_SIZE] = + {0xdc, 0x76, 0x15, 0x1e, 0x69, 0xe8, 0xdc, 0xd3, 0x4a, 0x71, 0x0b, 0x42, 0x71, 0xe0, 0xa9, 0x78}; +static const uint8_t enclave_signature_expected[ENCLAVE_SIGNATURE_SIZE] = + {0x1b, 0xb3, 0xcf, 0x16, 0xc, 0x27, 0xf7, 0xf2, 0xf0, 0x7e, 0x5f, 0xbe, 0xfe, 0x89, 0x52, 0xe1}; + /* * Device Info Command * This command is intended to be used by humans and machines @@ -43,6 +52,7 @@ void cli_command_device_info(Cli* cli, string_t args, void* context) { const Version* boot_version = furi_hal_version_get_boot_version(); if(boot_version) { printf("boot_version : %s\r\n", version_get_version(boot_version)); + printf("boot_target : %s\r\n", version_get_target(boot_version)); printf("boot_commit : %s\r\n", version_get_githash(boot_version)); printf("boot_branch : %s\r\n", version_get_gitbranch(boot_version)); printf("boot_build_date : %s\r\n", version_get_builddate(boot_version)); @@ -52,6 +62,7 @@ void cli_command_device_info(Cli* cli, string_t args, void* context) { const Version* firmware_version = furi_hal_version_get_firmware_version(); if(firmware_version) { printf("firmware_version : %s\r\n", version_get_version(firmware_version)); + printf("firmware_target : %s\r\n", version_get_target(firmware_version)); printf("firmware_commit : %s\r\n", version_get_githash(firmware_version)); printf("firmware_branch : %s\r\n", version_get_gitbranch(firmware_version)); printf("firmware_build_date : %s\r\n", version_get_builddate(firmware_version)); @@ -85,6 +96,18 @@ void cli_command_device_info(Cli* cli, string_t args, void* context) { printf("%02X", ble_mac[i]); } printf("\r\n"); + + // Signature verification + uint8_t buffer[ENCLAVE_SIGNATURE_SIZE]; + bool enclave_valid = false; + if(furi_hal_crypto_store_load_key(ENCLAVE_SIGNATURE_KEY_SLOT, enclave_signature_iv)) { + if(furi_hal_crypto_encrypt(enclave_signature_input, buffer, ENCLAVE_SIGNATURE_SIZE)) { + enclave_valid = + memcmp(buffer, enclave_signature_expected, ENCLAVE_SIGNATURE_SIZE) == 0; + } + furi_hal_crypto_store_unload_key(ENCLAVE_SIGNATURE_KEY_SLOT); + } + printf("enclave_valid : %s\r\n", enclave_valid ? "true" : "false"); } else { printf("radio_alive : false\r\n"); } @@ -363,17 +386,19 @@ void cli_command_ps(Cli* cli, string_t args, void* context) { const uint8_t threads_num_max = 32; osThreadId_t threads_id[threads_num_max]; uint8_t thread_num = osThreadEnumerate(threads_id, threads_num_max); - printf("%d threads in total:\r\n", thread_num); - printf("%-20s %-14s %-14s %s\r\n", "Name", "Stack start", "Stack alloc", "Stack watermark"); + printf( + "%-20s %-14s %-8s %-8s %s\r\n", "Name", "Stack start", "Heap", "Stack", "Stack min free"); for(uint8_t i = 0; i < thread_num; i++) { TaskControlBlock* tcb = (TaskControlBlock*)threads_id[i]; printf( - "%-20s 0x%-12lx %-14ld %ld\r\n", + "%-20s 0x%-12lx %-8d %-8ld %-8ld\r\n", osThreadGetName(threads_id[i]), (uint32_t)tcb->pxStack, - (uint32_t)(tcb->pxEndOfStack - tcb->pxStack + 1) * sizeof(uint32_t), - osThreadGetStackSpace(threads_id[i]) * sizeof(uint32_t)); + memmgr_heap_get_thread_memory(threads_id[i]), + (uint32_t)(tcb->pxEndOfStack - tcb->pxStack + 1) * sizeof(StackType_t), + osThreadGetStackSpace(threads_id[i])); } + printf("\r\nTotal: %d", thread_num); } void cli_command_free(Cli* cli, string_t args, void* context) { diff --git a/applications/crypto/crypto_cli.c b/applications/crypto/crypto_cli.c new file mode 100644 index 00000000000..cafd4aaae92 --- /dev/null +++ b/applications/crypto/crypto_cli.c @@ -0,0 +1,319 @@ +#include +#include + +#include +#include + +void crypto_cli_print_usage() { + printf("Usage:\r\n"); + printf("crypto \r\n"); + printf("Cmd list:\r\n"); + printf( + "\tencrypt \t - Using key from secure enclave and IV encrypt plain text with AES256CBC and encode to hex\r\n"); + printf( + "\tdecrypt \t - Using key from secure enclave and IV decrypt hex encoded encrypted with AES256CBC data to plain text\r\n"); + printf("\thas_key \t - Check if secure enclave has key in slot\r\n"); + printf( + "\tstore_key \t - Store key in secure enclave. !!! NON-REVERSABLE OPERATION - READ MANUAL FIRST !!!\r\n"); +}; + +void crypto_cli_encrypt(Cli* cli, string_t args) { + int key_slot = 0; + bool key_loaded = false; + uint8_t iv[16]; + + do { + if(!args_read_int_and_trim(args, &key_slot) || !(key_slot > 0 && key_slot <= 100)) { + printf("Incorrect or missing slot, expected int 1-100"); + break; + } + + if(!args_read_hex_bytes(args, iv, 16)) { + printf("Incorrect or missing IV, expected 16 bytes in hex"); + break; + } + + if(!furi_hal_crypto_store_load_key(key_slot, iv)) { + printf("Unable to load key from slot %d", key_slot); + break; + } + key_loaded = true; + + printf("Enter plain text and press Ctrl+C to complete encryption:\r\n"); + + string_t input; + string_init(input); + char c; + while(cli_read(cli, (uint8_t*)&c, 1) == 1) { + if(c == CliSymbolAsciiETX) { + printf("\r\n"); + break; + } else if(c >= 0x20 && c < 0x7F) { + putc(c, stdout); + fflush(stdout); + string_push_back(input, c); + } else if(c == CliSymbolAsciiCR) { + printf("\r\n"); + string_cat_str(input, "\r\n"); + } + } + + size_t size = string_size(input); + if(size > 0) { + // C-string null termination and block alignments + size++; + size_t remain = size % 16; + if(remain) { + size = size - remain + 16; + } + string_reserve(input, size); + uint8_t* output = furi_alloc(size); + if(!furi_hal_crypto_encrypt((const uint8_t*)string_get_cstr(input), output, size)) { + printf("Failed to encrypt input"); + } else { + printf("Hex-encoded encrypted data:\r\n"); + for(size_t i = 0; i < size; i++) { + if(i % 80 == 0) printf("\r\n"); + printf("%02x", output[i]); + } + printf("\r\n"); + } + free(output); + } else { + printf("No input"); + } + + string_clear(input); + } while(0); + + if(key_loaded) { + furi_hal_crypto_store_unload_key(key_slot); + } +} + +void crypto_cli_decrypt(Cli* cli, string_t args) { + int key_slot = 0; + bool key_loaded = false; + uint8_t iv[16]; + + do { + if(!args_read_int_and_trim(args, &key_slot) || !(key_slot > 0 && key_slot <= 100)) { + printf("Incorrect or missing slot, expected int 1-100"); + break; + } + + if(!args_read_hex_bytes(args, iv, 16)) { + printf("Incorrect or missing IV, expected 16 bytes in hex"); + break; + } + + if(!furi_hal_crypto_store_load_key(key_slot, iv)) { + printf("Unable to load key from slot %d", key_slot); + break; + } + key_loaded = true; + + printf("Enter Hex-encoded data and press Ctrl+C to complete decryption:\r\n"); + + string_t hex_input; + string_init(hex_input); + char c; + while(cli_read(cli, (uint8_t*)&c, 1) == 1) { + if(c == CliSymbolAsciiETX) { + printf("\r\n"); + break; + } else if(c >= 0x20 && c < 0x7F) { + putc(c, stdout); + fflush(stdout); + string_push_back(hex_input, c); + } else if(c == CliSymbolAsciiCR) { + printf("\r\n"); + } + } + + string_strim(hex_input); + size_t hex_size = string_size(hex_input); + if(hex_size > 0 && hex_size % 2 == 0) { + size_t size = hex_size / 2; + uint8_t* input = furi_alloc(size); + uint8_t* output = furi_alloc(size); + + if(args_read_hex_bytes(hex_input, input, size)) { + if(furi_hal_crypto_decrypt(input, output, size)) { + printf("Decrypted data:\r\n"); + printf("%s\r\n", output); + } else { + printf("Failed to decrypt\r\n"); + } + } else { + printf("Failed to parse input"); + } + + free(input); + free(output); + } else { + printf("Invalid or empty input"); + } + + string_clear(hex_input); + } while(0); + + if(key_loaded) { + furi_hal_crypto_store_unload_key(key_slot); + } +} + +void crypto_cli_has_key(Cli* cli, string_t args) { + int key_slot = 0; + uint8_t iv[16]; + + do { + if(!args_read_int_and_trim(args, &key_slot) || !(key_slot > 0 && key_slot <= 100)) { + printf("Incorrect or missing slot, expected int 1-100"); + break; + } + + if(!furi_hal_crypto_store_load_key(key_slot, iv)) { + printf("Unable to load key from slot %d", key_slot); + break; + } + + printf("Successfully loaded key from slot %d", key_slot); + + furi_hal_crypto_store_unload_key(key_slot); + } while(0); +} + +void crypto_cli_store_key(Cli* cli, string_t args) { + int key_slot = 0; + int key_size = 0; + string_t key_type; + string_init(key_type); + + uint8_t data[32 + 12] = {}; + FuriHalCryptoKey key; + key.data = data; + size_t data_size = 0; + + do { + if(!args_read_int_and_trim(args, &key_slot)) { + printf("Incorrect or missing key type, expected master, simple or encrypted"); + break; + } + if(!args_read_string_and_trim(args, key_type)) { + printf("Incorrect or missing key type, expected master, simple or encrypted"); + break; + } + + if(string_cmp_str(key_type, "master") == 0) { + if(key_slot != 0) { + printf("Master keyslot must be is 0"); + break; + } + key.type = FuriHalCryptoKeyTypeMaster; + } else if(string_cmp_str(key_type, "simple") == 0) { + if(key_slot < 1 || key_slot > 99) { + printf("Simple keyslot must be in range"); + break; + } + key.type = FuriHalCryptoKeyTypeSimple; + } else if(string_cmp_str(key_type, "encrypted") == 0) { + key.type = FuriHalCryptoKeyTypeEncrypted; + data_size += 12; + } else { + printf("Incorrect or missing key type, expected master, simple or encrypted"); + break; + } + + if(!args_read_int_and_trim(args, &key_size)) { + printf("Incorrect or missing key size, expected 128 or 256"); + break; + } + + if(key_size == 128) { + key.size = FuriHalCryptoKeySize128; + data_size += 16; + } else if(key_size == 256) { + key.size = FuriHalCryptoKeySize256; + data_size += 32; + } else { + printf("Incorrect or missing key size, expected 128 or 256"); + } + + if(!args_read_hex_bytes(args, data, data_size)) { + printf("Incorrect or missing key data, expected hex encoded key with or without IV."); + break; + } + + if(key_slot > 0) { + uint8_t iv[16]; + if(key_slot > 1) { + if(!furi_hal_crypto_store_load_key(key_slot - 1, iv)) { + printf( + "Slot %d before %d is empty, which is not allowed", + key_slot - 1, + key_slot); + break; + } + furi_hal_crypto_store_unload_key(key_slot - 1); + } + + if(furi_hal_crypto_store_load_key(key_slot, iv)) { + furi_hal_crypto_store_unload_key(key_slot); + printf("Key slot %d is already used", key_slot); + break; + } + } + + uint8_t slot; + if(furi_hal_crypto_store_add_key(&key, &slot)) { + printf("Success. Stored to slot: %d", slot); + } else { + printf("Failure"); + } + } while(0); + + string_clear(key_type); +} + +void crypto_cli(Cli* cli, string_t args, void* context) { + string_t cmd; + string_init(cmd); + + do { + if(!args_read_string_and_trim(args, cmd)) { + crypto_cli_print_usage(); + break; + } + + if(string_cmp_str(cmd, "encrypt") == 0) { + crypto_cli_encrypt(cli, args); + break; + } + + if(string_cmp_str(cmd, "decrypt") == 0) { + crypto_cli_decrypt(cli, args); + break; + } + + if(string_cmp_str(cmd, "has_key") == 0) { + crypto_cli_has_key(cli, args); + break; + } + + if(string_cmp_str(cmd, "store_key") == 0) { + crypto_cli_store_key(cli, args); + break; + } + + crypto_cli_print_usage(); + } while(false); + + string_clear(cmd); +} + +void crypto_cli_init() { + Cli* cli = furi_record_open("cli"); + cli_add_command(cli, "crypto", CliCommandFlagDefault, crypto_cli, NULL); + furi_record_close("cli"); +} diff --git a/applications/gui/canvas.c b/applications/gui/canvas.c index 023419893dc..404543398ba 100644 --- a/applications/gui/canvas.c +++ b/applications/gui/canvas.c @@ -116,7 +116,7 @@ void canvas_set_font(Canvas* canvas, Font font) { } else if(font == FontKeyboard) { u8g2_SetFont(&canvas->fb, u8g2_font_profont11_mf); } else { - furi_check(0); + furi_crash(NULL); } } @@ -150,7 +150,7 @@ void canvas_draw_str_aligned( x -= (u8g2_GetStrWidth(&canvas->fb, str) / 2); break; default: - furi_check(0); + furi_crash(NULL); break; } @@ -164,7 +164,7 @@ void canvas_draw_str_aligned( y += (u8g2_GetAscent(&canvas->fb) / 2); break; default: - furi_check(0); + furi_crash(NULL); break; } diff --git a/applications/gui/modules/widget.c b/applications/gui/modules/widget.c index 4b561260316..92ca9133a4d 100755 --- a/applications/gui/modules/widget.c +++ b/applications/gui/modules/widget.c @@ -118,7 +118,7 @@ static void widget_add_element(Widget* widget, WidgetElement* element) { }); } -void widget_add_string_multi_element( +void widget_add_string_multiline_element( Widget* widget, uint8_t x, uint8_t y, @@ -127,9 +127,9 @@ void widget_add_string_multi_element( Font font, const char* text) { furi_assert(widget); - WidgetElement* string_multi_element = - widget_element_string_multi_create(x, y, horizontal, vertical, font, text); - widget_add_element(widget, string_multi_element); + WidgetElement* string_multiline_element = + widget_element_string_multiline_create(x, y, horizontal, vertical, font, text); + widget_add_element(widget, string_multiline_element); } void widget_add_string_element( diff --git a/applications/gui/modules/widget.h b/applications/gui/modules/widget.h index 943e63c4b82..9a335bce687 100755 --- a/applications/gui/modules/widget.h +++ b/applications/gui/modules/widget.h @@ -34,7 +34,7 @@ View* widget_get_view(Widget* widget); * @param vertical - Align instance * @param font Font instance */ -void widget_add_string_multi_element( +void widget_add_string_multiline_element( Widget* widget, uint8_t x, uint8_t y, diff --git a/applications/gui/modules/widget_elements/widget_element_button.c b/applications/gui/modules/widget_elements/widget_element_button.c index 4b8517e0372..2fbfb892819 100644 --- a/applications/gui/modules/widget_elements/widget_element_button.c +++ b/applications/gui/modules/widget_elements/widget_element_button.c @@ -32,26 +32,15 @@ static bool gui_button_input(InputEvent* event, WidgetElement* element) { if(model->callback == NULL) return consumed; - if(event->key == InputKeyOk && event->type == InputTypePress && - model->button_type == GuiButtonTypeCenter) { - model->callback(GuiButtonTypeCenterPress, model->context); + if((model->button_type == GuiButtonTypeLeft) && (event->key == InputKeyLeft)) { + model->callback(model->button_type, event->type, model->context); consumed = true; - } else if( - event->key == InputKeyOk && event->type == InputTypeRelease && - model->button_type == GuiButtonTypeCenter) { - model->callback(GuiButtonTypeCenterRelease, model->context); + } else if((model->button_type == GuiButtonTypeRight) && (event->key == InputKeyRight)) { + model->callback(model->button_type, event->type, model->context); + consumed = true; + } else if((model->button_type == GuiButtonTypeCenter) && (event->key == InputKeyOk)) { + model->callback(model->button_type, event->type, model->context); consumed = true; - } else if(event->type == InputTypeShort) { - if((model->button_type == GuiButtonTypeLeft) && (event->key == InputKeyLeft)) { - model->callback(model->button_type, model->context); - consumed = true; - } else if((model->button_type == GuiButtonTypeRight) && (event->key == InputKeyRight)) { - model->callback(model->button_type, model->context); - consumed = true; - } else if((model->button_type == GuiButtonTypeCenter) && (event->key == InputKeyOk)) { - model->callback(model->button_type, model->context); - consumed = true; - } } return consumed; diff --git a/applications/gui/modules/widget_elements/widget_element_i.h b/applications/gui/modules/widget_elements/widget_element_i.h index d99e349f54d..2930eb1cf56 100755 --- a/applications/gui/modules/widget_elements/widget_element_i.h +++ b/applications/gui/modules/widget_elements/widget_element_i.h @@ -1,16 +1,15 @@ #pragma once #include #include +#include typedef enum { GuiButtonTypeLeft, GuiButtonTypeCenter, GuiButtonTypeRight, - GuiButtonTypeCenterPress, - GuiButtonTypeCenterRelease, } GuiButtonType; -typedef void (*ButtonCallback)(GuiButtonType result, void* context); +typedef void (*ButtonCallback)(GuiButtonType result, InputType type, void* context); typedef struct WidgetElement WidgetElement; typedef struct Widget Widget; @@ -31,7 +30,7 @@ struct WidgetElement { }; /* Create multi string element */ -WidgetElement* widget_element_string_multi_create( +WidgetElement* widget_element_string_multiline_create( uint8_t x, uint8_t y, Align horizontal, diff --git a/applications/gui/modules/widget_elements/widget_element_string_multi.c b/applications/gui/modules/widget_elements/widget_element_string_multiline.c similarity index 70% rename from applications/gui/modules/widget_elements/widget_element_string_multi.c rename to applications/gui/modules/widget_elements/widget_element_string_multiline.c index ad9c58f572f..f37eb3fcf06 100644 --- a/applications/gui/modules/widget_elements/widget_element_string_multi.c +++ b/applications/gui/modules/widget_elements/widget_element_string_multiline.c @@ -9,12 +9,12 @@ typedef struct { Align vertical; Font font; string_t text; -} GuiStringMultiModel; +} GuiStringMultiLineModel; -static void gui_string_multi_draw(Canvas* canvas, WidgetElement* element) { +static void gui_string_multiline_draw(Canvas* canvas, WidgetElement* element) { furi_assert(canvas); furi_assert(element); - GuiStringMultiModel* model = element->model; + GuiStringMultiLineModel* model = element->model; if(string_size(model->text)) { canvas_set_font(canvas, model->font); @@ -28,16 +28,16 @@ static void gui_string_multi_draw(Canvas* canvas, WidgetElement* element) { } } -static void gui_string_multi_free(WidgetElement* gui_string) { +static void gui_string_multiline_free(WidgetElement* gui_string) { furi_assert(gui_string); - GuiStringMultiModel* model = gui_string->model; + GuiStringMultiLineModel* model = gui_string->model; string_clear(model->text); free(gui_string->model); free(gui_string); } -WidgetElement* widget_element_string_multi_create( +WidgetElement* widget_element_string_multiline_create( uint8_t x, uint8_t y, Align horizontal, @@ -47,7 +47,7 @@ WidgetElement* widget_element_string_multi_create( furi_assert(text); // Allocate and init model - GuiStringMultiModel* model = furi_alloc(sizeof(GuiStringMultiModel)); + GuiStringMultiLineModel* model = furi_alloc(sizeof(GuiStringMultiLineModel)); model->x = x; model->y = y; model->horizontal = horizontal; @@ -59,8 +59,8 @@ WidgetElement* widget_element_string_multi_create( WidgetElement* gui_string = furi_alloc(sizeof(WidgetElement)); gui_string->parent = NULL; gui_string->input = NULL; - gui_string->draw = gui_string_multi_draw; - gui_string->free = gui_string_multi_free; + gui_string->draw = gui_string_multiline_draw; + gui_string->free = gui_string_multiline_free; gui_string->model = model; return gui_string; diff --git a/applications/menu/menu.c b/applications/menu/menu.c index ea7157d468e..544a88219b2 100644 --- a/applications/menu/menu.c +++ b/applications/menu/menu.c @@ -35,7 +35,7 @@ ValueMutex* menu_init() { ValueMutex* menu_mutex = furi_alloc(sizeof(ValueMutex)); if(menu_mutex == NULL || !init_mutex(menu_mutex, menu, sizeof(Menu))) { printf("[menu_task] cannot create menu mutex\r\n"); - furi_check(0); + furi_crash(NULL); } // OpenGui record diff --git a/applications/nfc/scenes/nfc_scene_delete.c b/applications/nfc/scenes/nfc_scene_delete.c index 9098759b7ab..5c6fe2545f2 100755 --- a/applications/nfc/scenes/nfc_scene_delete.c +++ b/applications/nfc/scenes/nfc_scene_delete.c @@ -1,9 +1,10 @@ #include "../nfc_i.h" -void nfc_scene_delete_widget_callback(GuiButtonType result, void* context) { +void nfc_scene_delete_widget_callback(GuiButtonType result, InputType type, void* context) { Nfc* nfc = (Nfc*)context; - - view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + } } void nfc_scene_delete_on_enter(void* context) { diff --git a/applications/nfc/scenes/nfc_scene_device_info.c b/applications/nfc/scenes/nfc_scene_device_info.c index 032834c581b..43082dcf016 100755 --- a/applications/nfc/scenes/nfc_scene_device_info.c +++ b/applications/nfc/scenes/nfc_scene_device_info.c @@ -7,9 +7,11 @@ enum { NfcSceneDeviceInfoData, }; -void nfc_scene_device_info_widget_callback(GuiButtonType result, void* context) { +void nfc_scene_device_info_widget_callback(GuiButtonType result, InputType type, void* context) { Nfc* nfc = context; - view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + } } void nfc_scene_device_info_dialog_callback(DialogExResult result, void* context) { @@ -22,9 +24,11 @@ void nfc_scene_device_info_text_box_callback(void* context) { view_dispatcher_send_custom_event(nfc->view_dispatcher, NFC_SCENE_DEVICE_INFO_BACK_EVENT); } -void nfc_scene_device_info_bank_card_callback(GuiButtonType result, void* context) { +void nfc_scene_device_info_bank_card_callback(GuiButtonType result, InputType type, void* context) { Nfc* nfc = context; - view_dispatcher_send_custom_event(nfc->view_dispatcher, NFC_SCENE_DEVICE_INFO_BACK_EVENT); + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, NFC_SCENE_DEVICE_INFO_BACK_EVENT); + } } void nfc_scene_device_info_on_enter(void* context) { diff --git a/applications/nfc/scenes/nfc_scene_read_emv_data_success.c b/applications/nfc/scenes/nfc_scene_read_emv_data_success.c index 927adb427e6..c0b61111ceb 100755 --- a/applications/nfc/scenes/nfc_scene_read_emv_data_success.c +++ b/applications/nfc/scenes/nfc_scene_read_emv_data_success.c @@ -1,10 +1,14 @@ #include "../nfc_i.h" #include "../helpers/nfc_emv_parser.h" -void nfc_scene_read_emv_data_success_widget_callback(GuiButtonType result, void* context) { +void nfc_scene_read_emv_data_success_widget_callback( + GuiButtonType result, + InputType type, + void* context) { Nfc* nfc = (Nfc*)context; - - view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + } } void nfc_scene_read_emv_data_success_on_enter(void* context) { diff --git a/applications/subghz/scenes/subghz_scene_receiver.c b/applications/subghz/scenes/subghz_scene_receiver.c index aa5eaabe24a..ffe510aab35 100644 --- a/applications/subghz/scenes/subghz_scene_receiver.c +++ b/applications/subghz/scenes/subghz_scene_receiver.c @@ -20,7 +20,7 @@ static void subghz_scene_receiver_update_statusbar(void* context) { } else if(subghz->txrx->preset == FuriHalSubGhzPreset2FSKAsync) { snprintf(preset_str, sizeof(preset_str), "FM"); } else { - furi_check(0); + furi_crash(NULL); } subghz_receiver_add_data_statusbar( subghz->subghz_receiver, frequency_str, preset_str, string_get_cstr(history_stat_str)); @@ -46,7 +46,7 @@ void subghz_scene_add_to_history_callback(SubGhzProtocolCommon* parser, void* co if(subghz_history_add_to_history( subghz->txrx->history, parser, subghz->txrx->frequency, subghz->txrx->preset)) { - subghz_protocol_reset(subghz->txrx->protocol); + subghz_parser_reset(subghz->txrx->parser); string_clean(str_buff); subghz_history_get_text_item_menu( subghz->txrx->history, str_buff, subghz_history_get_item(subghz->txrx->history) - 1); @@ -79,23 +79,18 @@ const void subghz_scene_receiver_on_enter(void* context) { string_clear(str_buff); subghz_scene_receiver_update_statusbar(subghz); subghz_receiver_set_callback(subghz->subghz_receiver, subghz_scene_receiver_callback, subghz); - subghz_protocol_enable_dump( - subghz->txrx->protocol, subghz_scene_add_to_history_callback, subghz); + subghz_parser_enable_dump(subghz->txrx->parser, subghz_scene_add_to_history_callback, subghz); subghz->state_notifications = NOTIFICATION_RX_STATE; if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz->txrx->worker); - //subghz_sleep(); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz_rx_end(subghz); }; - if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle) { - subghz_begin(subghz->txrx->preset); - subghz_rx(subghz->txrx->worker, subghz->txrx->frequency); - subghz->txrx->txrx_state = SubGhzTxRxStateRx; - } - if(subghz->txrx->idx_menu_chosen != 0) { - subghz_receiver_set_idx_menu(subghz->subghz_receiver, subghz->txrx->idx_menu_chosen); + if((subghz->txrx->txrx_state == SubGhzTxRxStateIdle) || + (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { + subghz_begin(subghz, subghz->txrx->preset); + subghz_rx(subghz, subghz->txrx->frequency); } + subghz_receiver_set_idx_menu(subghz->subghz_receiver, subghz->txrx->idx_menu_chosen); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewReceiver); } @@ -108,16 +103,15 @@ const bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event case SubghzReceverEventBack: // Stop CC1101 Rx if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz->txrx->worker); - subghz_sleep(); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz_rx_end(subghz); + subghz_sleep(subghz); }; subghz_history_clean(subghz->txrx->history); subghz->txrx->hopper_state = SubGhzHopperStateOFF; subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92]; subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; subghz->txrx->idx_menu_chosen = 0; - subghz_protocol_enable_dump(subghz->txrx->protocol, NULL, subghz); + subghz_parser_enable_dump(subghz->txrx->parser, NULL, subghz); scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneStart); return true; @@ -129,6 +123,7 @@ const bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event break; case SubghzReceverEventConfig: subghz->state_notifications = NOTIFICATION_IDLE_STATE; + subghz->txrx->idx_menu_chosen = subghz_receiver_get_idx_menu(subghz->subghz_receiver); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverConfig); return true; break; @@ -137,7 +132,7 @@ const bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event } } else if(event.type == SceneManagerEventTypeTick) { if(subghz->txrx->hopper_state != SubGhzHopperStateOFF) { - subghz_hopper_update(subghz->txrx); + subghz_hopper_update(subghz); subghz_scene_receiver_update_statusbar(subghz); } diff --git a/applications/subghz/scenes/subghz_scene_receiver_info.c b/applications/subghz/scenes/subghz_scene_receiver_info.c index 6d0d371e736..8f2663376ff 100644 --- a/applications/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/subghz/scenes/subghz_scene_receiver_info.c @@ -1,15 +1,31 @@ #include "../subghz_i.h" -void subghz_scene_receiver_info_callback(GuiButtonType result, void* context) { +typedef enum { + SubGhzSceneReceiverInfoCustomEventTxStart, + SubGhzSceneReceiverInfoCustomEventTxStop, + SubGhzSceneReceiverInfoCustomEventSave, +} SubGhzSceneReceiverInfoCustomEvent; + +void subghz_scene_receiver_info_callback(GuiButtonType result, InputType type, void* context) { furi_assert(context); SubGhz* subghz = context; - view_dispatcher_send_custom_event(subghz->view_dispatcher, result); + + if((result == GuiButtonTypeCenter) && (type == InputTypePress)) { + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubGhzSceneReceiverInfoCustomEventTxStart); + } else if((result == GuiButtonTypeCenter) && (type == InputTypeRelease)) { + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubGhzSceneReceiverInfoCustomEventTxStop); + } else if((result == GuiButtonTypeRight) && (type == InputTypeShort)) { + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubGhzSceneReceiverInfoCustomEventSave); + } } static bool subghz_scene_receiver_info_update_parser(void* context) { SubGhz* subghz = context; - subghz->txrx->protocol_result = subghz_protocol_get_by_name( - subghz->txrx->protocol, + subghz->txrx->protocol_result = subghz_parser_get_by_name( + subghz->txrx->parser, subghz_history_get_name(subghz->txrx->history, subghz->txrx->idx_menu_chosen)); if(subghz->txrx->protocol_result->to_load_protocol != NULL) { @@ -44,14 +60,14 @@ const void subghz_scene_receiver_info_on_enter(void* context) { } else if(subghz->txrx->preset == FuriHalSubGhzPreset2FSKAsync) { snprintf(buffer_str, sizeof(buffer_str), "FM"); } else { - furi_check(0); + furi_crash(NULL); } widget_add_string_element( subghz->widget, 113, 0, AlignLeft, AlignTop, FontSecondary, buffer_str); string_t text; string_init(text); subghz->txrx->protocol_result->to_string(subghz->txrx->protocol_result, text); - widget_add_string_multi_element( + widget_add_string_multiline_element( subghz->widget, 0, 0, AlignLeft, AlignTop, FontSecondary, string_get_cstr(text)); string_clear(text); @@ -83,52 +99,46 @@ const void subghz_scene_receiver_info_on_enter(void* context) { const bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeCenterPress) { + if(event.event == SubGhzSceneReceiverInfoCustomEventTxStart) { //CC1101 Stop RX -> Start TX subghz->state_notifications = NOTIFICATION_TX_STATE; if(subghz->txrx->hopper_state != SubGhzHopperStateOFF) { subghz->txrx->hopper_state = SubGhzHopperStatePause; } if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz->txrx->worker); - //subghz_sleep(); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz_rx_end(subghz); } if(!subghz_scene_receiver_info_update_parser(subghz)) { return false; } if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle) { subghz_tx_start(subghz); - subghz->txrx->txrx_state = SubGhzTxRxStateTx; } return true; - } else if(event.event == GuiButtonTypeCenterRelease) { + } else if(event.event == SubGhzSceneReceiverInfoCustomEventTxStop) { //CC1101 Stop Tx -> Start RX subghz->state_notifications = NOTIFICATION_IDLE_STATE; if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { subghz_tx_stop(subghz); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; } if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle) { - subghz_begin(subghz->txrx->preset); - subghz_rx(subghz->txrx->worker, subghz->txrx->frequency); - subghz->txrx->txrx_state = SubGhzTxRxStateRx; + subghz_begin(subghz, subghz->txrx->preset); + subghz_rx(subghz, subghz->txrx->frequency); } if(subghz->txrx->hopper_state == SubGhzHopperStatePause) { subghz->txrx->hopper_state = SubGhzHopperStateRunnig; } subghz->state_notifications = NOTIFICATION_RX_STATE; return true; - } else if(event.event == GuiButtonTypeRight) { + } else if(event.event == SubGhzSceneReceiverInfoCustomEventSave) { //CC1101 Stop RX -> Save subghz->state_notifications = NOTIFICATION_IDLE_STATE; if(subghz->txrx->hopper_state != SubGhzHopperStateOFF) { subghz->txrx->hopper_state = SubGhzHopperStateOFF; } if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz->txrx->worker); - subghz_sleep(); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz_rx_end(subghz); + subghz_sleep(subghz); } if(!subghz_scene_receiver_info_update_parser(subghz)) { return false; @@ -141,7 +151,7 @@ const bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent } } else if(event.type == SceneManagerEventTypeTick) { if(subghz->txrx->hopper_state != SubGhzHopperStateOFF) { - subghz_hopper_update(subghz->txrx); + subghz_hopper_update(subghz); } switch(subghz->state_notifications) { case NOTIFICATION_TX_STATE: diff --git a/applications/subghz/scenes/subghz_scene_set_type.c b/applications/subghz/scenes/subghz_scene_set_type.c index c506a5c7130..5993512bfca 100644 --- a/applications/subghz/scenes/subghz_scene_set_type.c +++ b/applications/subghz/scenes/subghz_scene_set_type.c @@ -15,8 +15,7 @@ enum SubmenuIndex { bool subghz_scene_set_type_submenu_to_find_protocol(void* context, const char* protocol_name) { SubGhz* subghz = context; - subghz->txrx->protocol_result = - subghz_protocol_get_by_name(subghz->txrx->protocol, protocol_name); + subghz->txrx->protocol_result = subghz_parser_get_by_name(subghz->txrx->parser, protocol_name); if(subghz->txrx->protocol_result == NULL) { string_set(subghz->error_str, "Protocol not found"); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); @@ -142,7 +141,7 @@ const bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event case SubmenuIndexGateTX: if(subghz_scene_set_type_submenu_to_find_protocol(subghz, "GateTX")) { subghz->txrx->protocol_result->code_last_count_bit = 24; - key = (key & 0x00F0FFFF) | 0xF << 16; //btn 0xF, 0xC, 0xA, 0x6 + key = (key & 0x00F0FF00) | 0xF << 16 | 0x40; //btn 0xF, 0xC, 0xA, 0x6 (?) subghz->txrx->protocol_result->code_last_found = subghz_protocol_common_reverse_key( key, subghz->txrx->protocol_result->code_last_count_bit); diff --git a/applications/subghz/scenes/subghz_scene_transmitter.c b/applications/subghz/scenes/subghz_scene_transmitter.c index 9628a094abb..8e743250b1d 100644 --- a/applications/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/subghz/scenes/subghz_scene_transmitter.c @@ -39,7 +39,7 @@ static void subghz_scene_transmitter_update_data_show(void* context) { } else if(subghz->txrx->preset == FuriHalSubGhzPreset2FSKAsync) { snprintf(preset_str, sizeof(preset_str), "FM"); } else { - furi_check(0); + furi_crash(NULL); } subghz_transmitter_add_data_to_show( @@ -70,21 +70,19 @@ const bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent ev if(event.event == SubghzTransmitterEventSendStart) { subghz->state_notifications = NOTIFICATION_TX_STATE; if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz->txrx->worker); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz_rx_end(subghz); } - if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle) { + if((subghz->txrx->txrx_state == SubGhzTxRxStateIdle) || + (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { subghz_tx_start(subghz); subghz_scene_transmitter_update_data_show(subghz); - subghz->txrx->txrx_state = SubGhzTxRxStateTx; } return true; } else if(event.event == SubghzTransmitterEventSendStop) { subghz->state_notifications = NOTIFICATION_IDLE_STATE; if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { subghz_tx_stop(subghz); - subghz_sleep(); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz_sleep(subghz); } return true; } else if(event.event == SubghzTransmitterEventBack) { diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c index 5b356ab17fe..02da799d9d4 100644 --- a/applications/subghz/subghz.c +++ b/applications/subghz/subghz.c @@ -7,6 +7,7 @@ const char* const subghz_frequencies_text[] = { "387.00", "433.08", "433.92", + "434.42", "434.78", "438.90", "464.00", @@ -26,6 +27,7 @@ const uint32_t subghz_frequencies[] = { 387000000, 433075000, /* LPD433 first */ 433920000, /* LPD433 mid */ + 434420000, 434775000, /* LPD433 last channels */ 438900000, 464000000, @@ -156,24 +158,24 @@ SubGhz* subghz_alloc() { subghz->txrx = furi_alloc(sizeof(SubGhzTxRx)); subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92]; subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz->txrx->txrx_state = SubGhzTxRxStateSleep; subghz->txrx->hopper_state = SubGhzHopperStateOFF; subghz->txrx->history = subghz_history_alloc(); subghz->txrx->worker = subghz_worker_alloc(); - subghz->txrx->protocol = subghz_protocol_alloc(); + subghz->txrx->parser = subghz_parser_alloc(); subghz_worker_set_overrun_callback( - subghz->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_protocol_reset); + subghz->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_parser_reset); subghz_worker_set_pair_callback( - subghz->txrx->worker, (SubGhzWorkerPairCallback)subghz_protocol_parse); - subghz_worker_set_context(subghz->txrx->worker, subghz->txrx->protocol); + subghz->txrx->worker, (SubGhzWorkerPairCallback)subghz_parser_parse); + subghz_worker_set_context(subghz->txrx->worker, subghz->txrx->parser); //Init Error_str string_init(subghz->error_str); - subghz_protocol_load_keeloq_file(subghz->txrx->protocol, "/ext/subghz/keeloq_mfcodes"); - subghz_protocol_load_nice_flor_s_file(subghz->txrx->protocol, "/ext/subghz/nice_floor_s_rx"); + subghz_parser_load_keeloq_file(subghz->txrx->parser, "/ext/subghz/keeloq_mfcodes"); + subghz_parser_load_nice_flor_s_file(subghz->txrx->parser, "/ext/subghz/nice_floor_s_rx"); - //subghz_protocol_enable_dump_text(subghz->protocol, subghz_text_callback, subghz); + //subghz_parser_enable_dump_text(subghz->protocol, subghz_text_callback, subghz); return subghz; } @@ -232,7 +234,7 @@ void subghz_free(SubGhz* subghz) { subghz->gui = NULL; //Worker & Protocol & History - subghz_protocol_free(subghz->txrx->protocol); + subghz_parser_free(subghz->txrx->parser); subghz_worker_free(subghz->txrx->worker); subghz_history_free(subghz->txrx->history); free(subghz->txrx); diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index e5da483ef1b..46149d4eb82 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include @@ -205,10 +205,10 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { instance->stream = xStreamBufferCreate(sizeof(LevelDuration) * 1024, sizeof(LevelDuration)); furi_check(instance->stream); - SubGhzProtocol* protocol = subghz_protocol_alloc(); - subghz_protocol_load_keeloq_file(protocol, "/ext/subghz/keeloq_mfcodes"); - subghz_protocol_load_nice_flor_s_file(protocol, "/ext/subghz/nice_floor_s_rx"); - subghz_protocol_enable_dump_text(protocol, subghz_cli_command_rx_text_callback, instance); + SubGhzParser* parser = subghz_parser_alloc(); + subghz_parser_load_keeloq_file(parser, "/ext/subghz/keeloq_mfcodes"); + subghz_parser_load_nice_flor_s_file(parser, "/ext/subghz/nice_floor_s_rx"); + subghz_parser_enable_dump_text(parser, subghz_cli_command_rx_text_callback, instance); // Configure radio furi_hal_subghz_reset(); @@ -228,11 +228,11 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { if(ret == sizeof(LevelDuration)) { if(level_duration_is_reset(level_duration)) { printf("."); - subghz_protocol_reset(protocol); + subghz_parser_reset(parser); } else { bool level = level_duration_get_level(level_duration); uint32_t duration = level_duration_get_duration(level_duration); - subghz_protocol_parse(protocol, level, duration); + subghz_parser_parse(parser, level, duration); } } } @@ -244,7 +244,7 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { printf("\r\nPackets recieved %u\r\n", instance->packet_count); // Cleanup - subghz_protocol_free(protocol); + subghz_parser_free(parser); vStreamBufferDelete(instance->stream); free(instance); } diff --git a/applications/subghz/subghz_history.h b/applications/subghz/subghz_history.h index 406c1ceefa8..59655188dc9 100644 --- a/applications/subghz/subghz_history.h +++ b/applications/subghz/subghz_history.h @@ -112,5 +112,3 @@ bool subghz_history_add_to_history( * @return SubGhzProtocolCommonLoad* */ SubGhzProtocolCommonLoad* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx); - -void subghz_hopper_update(void* context); diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c index cdac50c6dfc..9a52586a4ed 100644 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -10,19 +10,23 @@ #include "../notification/notification.h" #include "views/subghz_receiver.h" -void subghz_begin(FuriHalSubGhzPreset preset) { +void subghz_begin(SubGhz* subghz, FuriHalSubGhzPreset preset) { + furi_assert(subghz); furi_hal_subghz_reset(); furi_hal_subghz_idle(); furi_hal_subghz_load_preset(preset); hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + subghz->txrx->txrx_state = SubGhzTxRxStateIdle; } -uint32_t subghz_rx(void* context, uint32_t frequency) { - furi_assert(context); +uint32_t subghz_rx(SubGhz* subghz, uint32_t frequency) { + furi_assert(subghz); if(!furi_hal_subghz_is_frequency_valid(frequency)) { - furi_check(0); + furi_crash(NULL); } - SubGhzWorker* worker = context; + furi_assert( + subghz->txrx->txrx_state != SubGhzTxRxStateRx && + subghz->txrx->txrx_state != SubGhzTxRxStateSleep); furi_hal_subghz_idle(); uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency); @@ -30,45 +34,54 @@ uint32_t subghz_rx(void* context, uint32_t frequency) { furi_hal_subghz_flush_rx(); furi_hal_subghz_rx(); - furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, worker); - subghz_worker_start(worker); + furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, subghz->txrx->worker); + subghz_worker_start(subghz->txrx->worker); + subghz->txrx->txrx_state = SubGhzTxRxStateRx; return value; } -uint32_t subghz_tx(uint32_t frequency) { +uint32_t subghz_tx(SubGhz* subghz, uint32_t frequency) { + furi_assert(subghz); if(!furi_hal_subghz_is_frequency_valid(frequency)) { - furi_check(0); + furi_crash(NULL); } + furi_assert(subghz->txrx->txrx_state != SubGhzTxRxStateSleep); furi_hal_subghz_idle(); uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency); hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); hal_gpio_write(&gpio_cc1101_g0, true); furi_hal_subghz_tx(); + subghz->txrx->txrx_state = SubGhzTxRxStateTx; return value; } -void subghz_idle(void) { +void subghz_idle(SubGhz* subghz) { + furi_assert(subghz); + furi_assert(subghz->txrx->txrx_state != SubGhzTxRxStateSleep); furi_hal_subghz_idle(); + subghz->txrx->txrx_state = SubGhzTxRxStateIdle; } -void subghz_rx_end(void* context) { - furi_assert(context); - SubGhzWorker* worker = context; - - if(subghz_worker_is_running(worker)) { - subghz_worker_stop(worker); +void subghz_rx_end(SubGhz* subghz) { + furi_assert(subghz); + furi_assert(subghz->txrx->txrx_state == SubGhzTxRxStateRx); + if(subghz_worker_is_running(subghz->txrx->worker)) { + subghz_worker_stop(subghz->txrx->worker); furi_hal_subghz_stop_async_rx(); } furi_hal_subghz_idle(); + subghz->txrx->txrx_state = SubGhzTxRxStateIdle; } -void subghz_sleep(void) { +void subghz_sleep(SubGhz* subghz) { + furi_assert(subghz); furi_hal_subghz_sleep(); + subghz->txrx->txrx_state = SubGhzTxRxStateSleep; } -void subghz_frequency_preset_to_str(void* context, string_t output) { - furi_assert(context); - SubGhz* subghz = context; +static void subghz_frequency_preset_to_str(SubGhz* subghz, string_t output) { + furi_assert(subghz); + string_cat_printf( output, "Frequency: %d\n" @@ -77,9 +90,9 @@ void subghz_frequency_preset_to_str(void* context, string_t output) { (int)subghz->txrx->preset); } -void subghz_tx_start(void* context) { - furi_assert(context); - SubGhz* subghz = context; +void subghz_tx_start(SubGhz* subghz) { + furi_assert(subghz); + subghz->txrx->encoder = subghz_protocol_encoder_common_alloc(); subghz->txrx->encoder->repeat = 200; //max repeat with the button held down //get upload @@ -87,14 +100,14 @@ void subghz_tx_start(void* context) { if(subghz->txrx->protocol_result->get_upload_protocol( subghz->txrx->protocol_result, subghz->txrx->encoder)) { if(subghz->txrx->preset) { - subghz_begin(subghz->txrx->preset); + subghz_begin(subghz, subghz->txrx->preset); } else { - subghz_begin(FuriHalSubGhzPresetOok270Async); + subghz_begin(subghz, FuriHalSubGhzPresetOok270Async); } if(subghz->txrx->frequency) { - subghz_tx(subghz->txrx->frequency); + subghz_tx(subghz, subghz->txrx->frequency); } else { - subghz_tx(433920000); + subghz_tx(subghz, 433920000); } //Start TX @@ -104,15 +117,15 @@ void subghz_tx_start(void* context) { } } -void subghz_tx_stop(void* context) { - furi_assert(context); - SubGhz* subghz = context; +void subghz_tx_stop(SubGhz* subghz) { + furi_assert(subghz); + furi_assert(subghz->txrx->txrx_state == SubGhzTxRxStateTx); //Stop TX furi_hal_subghz_stop_async_tx(); subghz_protocol_encoder_common_free(subghz->txrx->encoder); - furi_hal_subghz_idle(); + subghz_idle(subghz); //if protocol dynamic then we save the last upload - if(subghz->txrx->protocol_result->type_protocol == TYPE_PROTOCOL_DYNAMIC) { + if(subghz->txrx->protocol_result->type_protocol == SubGhzProtocolCommonTypeDynamic) { subghz_save_protocol_to_file(subghz, subghz->text_store); } notification_message(subghz->notifications, &sequence_reset_red); @@ -164,7 +177,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) { // strlen("Protocol: ") = 10 string_right(temp_str, 10); subghz->txrx->protocol_result = - subghz_protocol_get_by_name(subghz->txrx->protocol, string_get_cstr(temp_str)); + subghz_parser_get_by_name(subghz->txrx->parser, string_get_cstr(temp_str)); if(subghz->txrx->protocol_result == NULL) { break; } @@ -186,10 +199,10 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) { return loaded; } -bool subghz_save_protocol_to_file(void* context, const char* dev_name) { - furi_assert(context); - SubGhz* subghz = context; +bool subghz_save_protocol_to_file(SubGhz* subghz, const char* dev_name) { + furi_assert(subghz); furi_assert(subghz->txrx->protocol_result); + FileWorker* file_worker = file_worker_alloc(false); string_t dev_file_name; string_init(dev_file_name); @@ -308,7 +321,7 @@ bool subghz_load_protocol_from_file(SubGhz* subghz) { // strlen("Protocol: ") = 10 string_right(temp_str, 10); subghz->txrx->protocol_result = - subghz_protocol_get_by_name(subghz->txrx->protocol, string_get_cstr(temp_str)); + subghz_parser_get_by_name(subghz->txrx->parser, string_get_cstr(temp_str)); if(subghz->txrx->protocol_result == NULL) { break; } @@ -342,11 +355,10 @@ uint32_t subghz_random_serial(void) { return (uint32_t)rand(); } -void subghz_hopper_update(void* context) { - furi_assert(context); - SubGhzTxRx* txrx = context; +void subghz_hopper_update(SubGhz* subghz) { + furi_assert(subghz); - switch(txrx->hopper_state) { + switch(subghz->txrx->hopper_state) { case SubGhzHopperStateOFF: return; break; @@ -354,8 +366,8 @@ void subghz_hopper_update(void* context) { return; break; case SubGhzHopperStateRSSITimeOut: - if(txrx->hopper_timeout != 0) { - txrx->hopper_timeout--; + if(subghz->txrx->hopper_timeout != 0) { + subghz->txrx->hopper_timeout--; return; } break; @@ -363,35 +375,33 @@ void subghz_hopper_update(void* context) { break; } float rssi = -127.0f; - if(txrx->hopper_state != SubGhzHopperStateRSSITimeOut) { + if(subghz->txrx->hopper_state != SubGhzHopperStateRSSITimeOut) { // See RSSI Calculation timings in CC1101 17.3 RSSI rssi = furi_hal_subghz_get_rssi(); // Stay if RSSI is high enough if(rssi > -90.0f) { - txrx->hopper_timeout = 10; - txrx->hopper_state = SubGhzHopperStateRSSITimeOut; + subghz->txrx->hopper_timeout = 10; + subghz->txrx->hopper_state = SubGhzHopperStateRSSITimeOut; return; } } else { - txrx->hopper_state = SubGhzHopperStateRunnig; + subghz->txrx->hopper_state = SubGhzHopperStateRunnig; } // Select next frequency - if(txrx->hopper_idx_frequency < subghz_hopper_frequencies_count - 1) { - txrx->hopper_idx_frequency++; + if(subghz->txrx->hopper_idx_frequency < subghz_hopper_frequencies_count - 1) { + subghz->txrx->hopper_idx_frequency++; } else { - txrx->hopper_idx_frequency = 0; + subghz->txrx->hopper_idx_frequency = 0; } - if(txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(txrx->worker); - txrx->txrx_state = SubGhzTxRxStateIdle; + if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { + subghz_rx_end(subghz); }; - if(txrx->txrx_state == SubGhzTxRxStateIdle) { - subghz_protocol_reset(txrx->protocol); - txrx->frequency = subghz_hopper_frequencies[txrx->hopper_idx_frequency]; - subghz_rx(txrx->worker, txrx->frequency); - txrx->txrx_state = SubGhzTxRxStateRx; + if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle) { + subghz_parser_reset(subghz->txrx->parser); + subghz->txrx->frequency = subghz_hopper_frequencies[subghz->txrx->hopper_idx_frequency]; + subghz_rx(subghz, subghz->txrx->frequency); } } diff --git a/applications/subghz/subghz_i.h b/applications/subghz/subghz_i.h index 9d088dc6f31..eecf98d3bff 100644 --- a/applications/subghz/subghz_i.h +++ b/applications/subghz/subghz_i.h @@ -22,7 +22,8 @@ #include #include -#include + +#include #include #include "subghz_history.h" @@ -47,6 +48,7 @@ typedef enum { SubGhzTxRxStateIdle, SubGhzTxRxStateRx, SubGhzTxRxStateTx, + SubGhzTxRxStateSleep, } SubGhzTxRxState; /** SubGhzHopperState state */ @@ -59,7 +61,7 @@ typedef enum { struct SubGhzTxRx { SubGhzWorker* worker; - SubGhzProtocol* protocol; + SubGhzParser* parser; SubGhzProtocolCommon* protocol_result; SubGhzProtocolCommonEncoder* encoder; uint32_t frequency; @@ -115,15 +117,14 @@ typedef enum { SubGhzViewTestPacket, } SubGhzView; -void subghz_begin(FuriHalSubGhzPreset preset); -uint32_t subghz_rx(void* context, uint32_t frequency); -uint32_t subghz_tx(uint32_t frequency); -void subghz_idle(void); -void subghz_rx_end(void* context); -void subghz_sleep(void); -void subghz_tx_start(void* context); -void subghz_tx_stop(void* context); +void subghz_begin(SubGhz* subghz, FuriHalSubGhzPreset preset); +uint32_t subghz_rx(SubGhz* subghz, uint32_t frequency); +void subghz_rx_end(SubGhz* subghz); +void subghz_sleep(SubGhz* subghz); +void subghz_tx_start(SubGhz* subghz); +void subghz_tx_stop(SubGhz* subghz); bool subghz_key_load(SubGhz* subghz, const char* file_path); -bool subghz_save_protocol_to_file(void* context, const char* dev_name); +bool subghz_save_protocol_to_file(SubGhz* subghz, const char* dev_name); bool subghz_load_protocol_from_file(SubGhz* subghz); uint32_t subghz_random_serial(void); +void subghz_hopper_update(SubGhz* subghz); diff --git a/applications/subghz/views/subghz_receiver.c b/applications/subghz/views/subghz_receiver.c index 4abf82253f4..26aec5e7120 100644 --- a/applications/subghz/views/subghz_receiver.c +++ b/applications/subghz/views/subghz_receiver.c @@ -29,9 +29,9 @@ struct SubGhzReceiverHistory { typedef struct SubGhzReceiverHistory SubGhzReceiverHistory; static const Icon* ReceiverItemIcons[] = { - [TYPE_PROTOCOL_UNKNOWN] = &I_Quest_7x8, - [TYPE_PROTOCOL_STATIC] = &I_Unlock_7x8, - [TYPE_PROTOCOL_DYNAMIC] = &I_Lock_7x8, + [SubGhzProtocolCommonTypeUnknown] = &I_Quest_7x8, + [SubGhzProtocolCommonTypeStatic] = &I_Unlock_7x8, + [SubGhzProtocolCommonTypeDynamic] = &I_Lock_7x8, }; struct SubghzReceiver { @@ -90,7 +90,13 @@ void subghz_receiver_add_item_to_menu( SubGhzReceiverMenuItemArray_push_raw(model->history->data); string_init_set_str(item_menu->item_str, name); item_menu->type = type; - model->history_item++; + if((model->idx == model->history_item - 1)) { + model->history_item++; + model->idx++; + } else { + model->history_item++; + } + return true; }); subghz_receiver_update_offset(subghz_receiver); diff --git a/applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c b/applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c index 55403b95b18..01bca32d6dc 100644 --- a/applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c +++ b/applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c @@ -129,10 +129,7 @@ static void run_encoder_decoder(const IrdaMessage input_messages[], uint32_t inp for(int i = 0; i < timings_len; ++i) { message_decoded = irda_decode(decoder_handler, level, timings[i]); if((i == timings_len - 2) && level && message_decoded) { - /* In case we end with space timing - message can be decoded at last mark. - * Exception - SIRC protocol, which has variable message length (12/15/20), - * and decoder recognizes protocol by silence time before next message - * or by timeout (irda_check_decoder_ready()). */ + /* In case we end with space timing - message can be decoded at last mark */ break; } else if(i < timings_len - 1) { mu_check(!message_decoded); @@ -225,17 +222,16 @@ MU_TEST(test_mix) { RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1); RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1); RUN_DECODER(test_decoder_sirc_input5, test_decoder_sirc_expected5); + RUN_DECODER(test_decoder_nec_input3, test_decoder_nec_expected3); RUN_DECODER(test_decoder_rc5_input5, test_decoder_rc5_expected5); RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1); RUN_DECODER(test_decoder_sirc_input3, test_decoder_sirc_expected3); } -MU_TEST(test_decoder_nec1) { +MU_TEST(test_decoder_nec) { RUN_DECODER(test_decoder_nec_input1, test_decoder_nec_expected1); -} - -MU_TEST(test_decoder_nec2) { RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2); + RUN_DECODER(test_decoder_nec_input3, test_decoder_nec_expected3); } MU_TEST(test_decoder_unexpected_end_in_sequence) { @@ -295,6 +291,8 @@ MU_TEST(test_encoder_rc6) { MU_TEST(test_encoder_decoder_all) { RUN_ENCODER_DECODER(test_nec); RUN_ENCODER_DECODER(test_necext); + RUN_ENCODER_DECODER(test_nec42); + RUN_ENCODER_DECODER(test_nec42ext); RUN_ENCODER_DECODER(test_samsung32); RUN_ENCODER_DECODER(test_rc6); RUN_ENCODER_DECODER(test_rc5); @@ -312,8 +310,7 @@ MU_TEST_SUITE(test_irda_decoder_encoder) { MU_RUN_TEST(test_decoder_rc6); MU_RUN_TEST(test_encoder_rc6); MU_RUN_TEST(test_decoder_unexpected_end_in_sequence); - MU_RUN_TEST(test_decoder_nec1); - MU_RUN_TEST(test_decoder_nec2); + MU_RUN_TEST(test_decoder_nec); MU_RUN_TEST(test_decoder_samsung32); MU_RUN_TEST(test_decoder_necext1); MU_RUN_TEST(test_mix); diff --git a/applications/tests/irda_decoder_encoder/test_data/irda_nec_test_data.srcdata b/applications/tests/irda_decoder_encoder/test_data/irda_nec_test_data.srcdata index 9b4dae7e725..f97f31ca04c 100644 --- a/applications/tests/irda_decoder_encoder/test_data/irda_nec_test_data.srcdata +++ b/applications/tests/irda_decoder_encoder/test_data/irda_nec_test_data.srcdata @@ -178,6 +178,45 @@ const IrdaMessage test_decoder_nec_expected2[] = { {IrdaProtocolNEC, 0x00, 0x0A, true}, }; +const uint32_t test_decoder_nec_input3[] = { +200000, 8862, 4452, 562, 563, 559, 1681, 563, 1646, 567, 586, 556, 569, 563, 583, 559, 571, 561, 1675, 559, 565, 567, 1673, 561, 561, 561, 592, 561, 565, 567, 579, 563, 567, 565, 584, 558, 1652, 561, 592, 561, 561, 561, 1679, 565, 560, 562, 584, 558, 1659, 564, 585, 557, 566, 566, 1675, 559, 1649, 564, 589, 564, 1649, 564, 1668, 566, 565, 567, 1669, 565, + 43470, 8896, 4432, 561, 561, 561, 1679, 565, 1648, 565, 581, 561, 568, 564, 586, 567, 558, 564, 1676, 558, 564, 558, 1681, 563, 563, 559, 587, 566, 565, 567, 582, 561, 564, 558, 595, 558, 1650, 563, 590, 563, 563, 559, 1674, 560, 570, 562, 587, 566, 1645, 568, 586, 556, 565, 567, 1672, 562, 1651, 562, 584, 558, 1658, 566, 1671, 563, 561, 561, 1679, 565, +200000, 8881, 4383, 569, 549, 573, 548, 574, 541, 571, 550, 572, 547, 575, 539, 573, 551, 571, 1651, 573, 545, 567, 554, 568, 548, 574, 1652, 572, 547, 575, 1645, 568, 1661, 573, 545, 567, 1657, 567, 554, 568, 547, 575, 1652, 572, 547, 575, 539, 573, 1657, 567, 550, 572, 545, 577, 1651, 573, 1648, 576, 545, 567, 1659, 575, 1645, 568, 555, 567, 1657, 567, + 38995, 8883, 4369, 573, 543, 569, 552, 570, 549, 573, 541, 571, 553, 569, 548, 574, 543, 569, 1658, 566, 550, 572, 548, 574, 546, 566, 1653, 571, 553, 569, 1654, 570, 1654, 570, 551, 571, 1651, 573, 547, 575, 545, 567, 1653, 571, 552, 570, 547, 575, 1649, 564, 556, 566, 550, 572, 1655, 569, 1656, 568, 546, 566, 1664, 570, 1653, 571, 547, 565, 1663, 571, +200000, 8987, 4504, 561, 593, 539, 589, 533, 596, 515, 586, 536, 592, 540, 588, 534, 595, 517, 1713, 541, 1664, 570, 1686, 558, 596, 515, 587, 535, 593, 539, 1691, 543, 1689, 565, 588, 513, 1691, 563, 1668, 617, 1613, 641, 1615, 567, 587, 535, 593, 519, 610, 512, 590, 542, 1714, 510, 593, 539, 1691, 563, 591, 510, 1720, 535, 594, 518, 584, 538, 591, 541, + 39546, 8990, 4501, 565, 590, 542, 586, 536, 593, 508, 593, 539, 589, 543, 585, 537, 592, 509, 1720, 545, 1660, 615, 1642, 561, 567, 534, 594, 538, 590, 542, 1688, 535, 1696, 558, 595, 517, 1687, 567, 1664, 621, 1635, 619, 1611, 561, 594, 538, 590, 511, 617, 515, 586, 536, 1721, 513, 589, 543, 1687, 568, 587, 514, 1691, 563, 590, 511, 591, 541, 587, 535, +200000, 8986, 4505, 560, 594, 538, 590, 542, 586, 515, 586, 536, 593, 539, 589, 533, 595, 517, 1714, 540, 587, 535, 594, 518, 1713, 542, 586, 515, 587, 535, 1722, 543, 1662, 562, 592, 540, 1664, 570, 585, 537, 591, 541, 1689, 545, 584, 538, 590, 542, 1688, 536, 593, 539, 589, 512, 590, 542, 586, 536, 1720, 514, 588, 544, 585, 537, 591, 541, 587, 514, + 40671, 8986, 4505, 560, 594, 538, 590, 542, 586, 515, 587, 535, 593, 539, 589, 533, 595, 516, 1714, 541, 587, 535, 594, 518, 1712, 542, 586, 515, 587, 535, 1722, 543, 1662, 561, 592, 540, 1664, 570, 585, 537, 591, 541, 1689, 545, 584, 538, 590, 542, 1688, 536, 593, 539, 589, 512, 590, 542, 586, 536, 1720, 514, 588, 544, 585, 537, 591, 541, 587, 514, +200000, 8990, 4500, 566, 1692, 562, 1668, 566, 588, 534, 594, 518, 584, 538, 591, 541, 587, 535, 1669, 565, 589, 543, 1688, 536, 592, 540, 1691, 563, 1667, 567, 1664, 621, 1635, 568, 586, 515, 587, 535, 593, 539, 589, 543, 1662, 562, 592, 540, 588, 534, 594, 518, 585, 537, 591, 541, 587, 514, 587, 535, 594, 538, 590, 542, 586, 515, 586, 536, 593, 539, + 39544, 8993, 4498, 567, 1690, 564, 1666, 568, 586, 536, 593, 508, 593, 539, 589, 543, 585, 537, 1668, 566, 588, 544, 1687, 537, 591, 541, 1690, 564, 1666, 568, 1663, 561, 1696, 569, 585, 516, 586, 536, 593, 539, 589, 543, 1661, 562, 592, 540, 588, 534, 594, 517, 584, 538, 591, 541, 587, 514, 587, 535, 593, 539, 589, 543, 585, 516, 586, 536, 592, 540, +200000, 8894, 4456, 589, 1676, 589, 571, 582, 574, 589, 571, 582, 1683, 582, 1677, 588, 1682, 583, 574, 589, 568, 585, 1682, 583, 1678, 587, 1680, 585, 574, 589, 565, 588, 575, 588, 1675, 590, 567, 586, 1681, 584, 571, 582, 1685, 590, 568, 585, 569, 584, 1685, 590, 567, 586, 1678, 587, 574, 589, 1672, 582, 578, 585, 1679, 586, 1674, 591, 572, 591, 1672, 582, + 39632, 8912, 4464, 560, 1703, 562, 598, 565, 594, 559, 594, 559, 1711, 564, 1698, 567, 1697, 568, 593, 560, 595, 568, 1698, 567, 1698, 567, 1693, 561, 602, 561, 596, 567, 590, 563, 1704, 561, 594, 559, 1707, 568, 591, 562, 1697, 568, 596, 567, 590, 563, 1700, 565, 596, 567, 1693, 561, 599, 564, 1701, 564, 589, 564, 1706, 559, 1704, 561, 597, 566, 1700, 565, +200000, 9018, 4500, 565, 1666, 568, 1689, 565, 588, 513, 1691, 615, 1616, 618, 1639, 564, 1667, 567, 587, 535, 594, 538, 563, 538, 590, 542, 586, 536, 593, 508, 593, 539, 589, 543, 1688, 535, 592, 540, 588, 544, 585, 537, 591, 510, 1694, 560, 1670, 564, 1693, 562, 1669, 565, 1692, 542, 1689, 565, 588, 534, 595, 517, 585, 537, 591, 541, 587, 535, 568, 544, 584, 538, 591, 541, 1663, 560, 1696, 569, 1662, 562, 1695, 539, 1692, 614, 1616, 566, 1691, 563, 1667, 567, + 23184, 9012, 4505, 560, 1697, 537, 1693, 561, 593, 508, 1696, 569, 1662, 562, 1695, 560, 1671, 563, 591, 541, 587, 535, 594, 518, 584, 538, 590, 542, 586, 515, 613, 509, 593, 539, 1692, 542, 585, 537, 592, 540, 588, 534, 594, 518, 1687, 567, 1663, 560, 1697, 568, 1662, 562, 1695, 539, 1692, 563, 591, 541, 587, 514, 588, 544, 584, 538, 590, 542, 586, 515, 587, 535, 593, 539, 1666, 568, 1689, 565, 1665, 569, 1688, 536, 1695, 570, 1661, 562, 1694, 561, 1670, 564, +200000, 8835, 4446, 537, 562, 539, 562, 539, 1663, 540, 1667, 536, 1669, 534, 560, 531, 573, 539, 559, 532, 1672, 531, 570, 531, 564, 537, 563, 538, 561, 540, 1660, 533, 1677, 536, 561, 540, 557, 534, 567, 534, 1668, 535, 1672, 531, 1675, 538, 555, 536, 1674, 539, 1665, 538, 1666, 537, 1671, 532, 563, 538, 1669, 534, 566, 535, 558, 533, 1677, 536, 562, 539, 558, 533, 568, 533, 1668, 535, 566, 535, 1670, 533, 1667, 536, 568, 533, 1671, 532, 1672, 531, 1676, 537, + 22779, 8870, 4437, 535, + 92592, 8861, 4414, 538, +}; + +const IrdaMessage test_decoder_nec_expected3[] = { + {IrdaProtocolNECext, 0x286, 0xB649, false}, + {IrdaProtocolNECext, 0x286, 0xB649, false}, + {IrdaProtocolNECext, 0x6880, 0xB649, false}, + {IrdaProtocolNECext, 0x6880, 0xB649, false}, + {IrdaProtocolNECext, 0x6380, 0x150F, false}, + {IrdaProtocolNECext, 0x6380, 0x150F, false}, + {IrdaProtocolNECext, 0x6480, 0x849, false}, + {IrdaProtocolNECext, 0x6480, 0x849, false}, + {IrdaProtocolNECext, 0x7A83, 0x8, false}, + {IrdaProtocolNECext, 0x7A83, 0x8, false}, + {IrdaProtocolNEC, 0x71, 0x4A, false}, + {IrdaProtocolNEC, 0x71, 0x4A, false}, + {IrdaProtocolNEC42, 0x7B, 0x0, false}, + {IrdaProtocolNEC42, 0x7B, 0x0, false}, + {IrdaProtocolNEC42, 0x11C, 0x12, false}, +}; + + const IrdaMessage test_nec[] = { {IrdaProtocolNEC, 0x00, 0x00, false}, {IrdaProtocolNEC, 0x01, 0x00, false}, @@ -209,4 +248,61 @@ const IrdaMessage test_nec[] = { {IrdaProtocolNEC, 0x55, 0x55, true}, }; +const IrdaMessage test_nec42[] = { + {IrdaProtocolNEC42, 0x0000, 0x00, false}, + {IrdaProtocolNEC42, 0x0001, 0x00, false}, + {IrdaProtocolNEC42, 0x0001, 0x80, false}, + {IrdaProtocolNEC42, 0x0000, 0x80, false}, + {IrdaProtocolNEC42, 0x0000, 0x00, false}, + {IrdaProtocolNEC42, 0x0000, 0x00, true}, + {IrdaProtocolNEC42, 0x0000, 0x00, false}, + {IrdaProtocolNEC42, 0x0000, 0x00, true}, + {IrdaProtocolNEC42, 0x1FFF, 0xFF, false}, + {IrdaProtocolNEC42, 0x1FFE, 0xFF, false}, + {IrdaProtocolNEC42, 0x1FFE, 0x7F, false}, + {IrdaProtocolNEC42, 0x1FFF, 0x7F, false}, + {IrdaProtocolNEC42, 0x1FFF, 0xFF, false}, + {IrdaProtocolNEC42, 0x1FFF, 0xFF, true}, + {IrdaProtocolNEC42, 0x0AAA, 0x55, false}, + {IrdaProtocolNEC42, 0x1555, 0xAA, false}, + {IrdaProtocolNEC42, 0x1555, 0x55, false}, + {IrdaProtocolNEC42, 0x0AAA, 0xAA, false}, + {IrdaProtocolNEC42, 0x0AAA, 0xAA, true}, + {IrdaProtocolNEC42, 0x0AAA, 0xAA, false}, + {IrdaProtocolNEC42, 0x0AAA, 0xAA, true}, + {IrdaProtocolNEC42, 0x0AAA, 0xAA, true}, + {IrdaProtocolNEC42, 0x1555, 0x55, false}, + {IrdaProtocolNEC42, 0x1555, 0x55, true}, + {IrdaProtocolNEC42, 0x1555, 0x55, true}, + {IrdaProtocolNEC42, 0x1555, 0x55, true}, +}; + +const IrdaMessage test_nec42ext[] = { + {IrdaProtocolNEC42ext, 0x0000000, 0x0000, false}, + {IrdaProtocolNEC42ext, 0x0000001, 0x0000, false}, + {IrdaProtocolNEC42ext, 0x0000001, 0x8000, false}, + {IrdaProtocolNEC42ext, 0x0000000, 0x8000, false}, + {IrdaProtocolNEC42ext, 0x0000000, 0x0000, false}, + {IrdaProtocolNEC42ext, 0x0000000, 0x0000, true}, + {IrdaProtocolNEC42ext, 0x0000000, 0x0000, false}, + {IrdaProtocolNEC42ext, 0x0000000, 0x0000, true}, + {IrdaProtocolNEC42ext, 0x3F000FF, 0xF00F, false}, + {IrdaProtocolNEC42ext, 0x3F000FE, 0xF00F, false}, + {IrdaProtocolNEC42ext, 0x3F000FE, 0x700F, false}, + {IrdaProtocolNEC42ext, 0x3F000FF, 0x700F, false}, + {IrdaProtocolNEC42ext, 0x3F000FF, 0xF00F, false}, + {IrdaProtocolNEC42ext, 0x3F000FF, 0xF00F, true}, + {IrdaProtocolNEC42ext, 0x2AAAAAA, 0x5555, false}, + {IrdaProtocolNEC42ext, 0x1555555, 0xAAAA, false}, + {IrdaProtocolNEC42ext, 0x1555555, 0x5555, false}, + {IrdaProtocolNEC42ext, 0x2AAAAAA, 0xAAAA, false}, + {IrdaProtocolNEC42ext, 0x2AAAAAA, 0xAAAA, true}, + {IrdaProtocolNEC42ext, 0x2AAAAAA, 0xAAAA, false}, + {IrdaProtocolNEC42ext, 0x2AAAAAA, 0xAAAA, true}, + {IrdaProtocolNEC42ext, 0x2AAAAAA, 0xAAAA, true}, + {IrdaProtocolNEC42ext, 0x1555555, 0x5555, false}, + {IrdaProtocolNEC42ext, 0x1555555, 0x5555, true}, + {IrdaProtocolNEC42ext, 0x1555555, 0x5555, true}, + {IrdaProtocolNEC42ext, 0x1555555, 0x5555, true}, +}; diff --git a/applications/tests/irda_decoder_encoder/test_data/irda_necext_test_data.srcdata b/applications/tests/irda_decoder_encoder/test_data/irda_necext_test_data.srcdata index 66c4f947cfc..edd60768464 100644 --- a/applications/tests/irda_decoder_encoder/test_data/irda_necext_test_data.srcdata +++ b/applications/tests/irda_decoder_encoder/test_data/irda_necext_test_data.srcdata @@ -111,147 +111,145 @@ const uint32_t test_decoder_necext_input1[] = { }; const IrdaMessage test_decoder_necext_expected1[] = { - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, false}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, - {IrdaProtocolNECext, 0x7984, 0x12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, false}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, + {IrdaProtocolNECext, 0x7984, 0xed12, true}, }; - - const IrdaMessage test_necext[] = { - {IrdaProtocolNECext, 0x0000, 0x00, false}, - {IrdaProtocolNECext, 0x0001, 0x00, false}, - {IrdaProtocolNECext, 0x0001, 0x80, false}, - {IrdaProtocolNECext, 0x0000, 0x80, false}, - {IrdaProtocolNECext, 0x0000, 0x00, false}, - {IrdaProtocolNECext, 0x0000, 0x00, true}, - {IrdaProtocolNECext, 0x0000, 0x00, false}, - {IrdaProtocolNECext, 0x0000, 0x00, true}, - {IrdaProtocolNECext, 0xFFFF, 0xFF, false}, - {IrdaProtocolNECext, 0xFFFE, 0xFF, false}, - {IrdaProtocolNECext, 0xFFFE, 0x7F, false}, - {IrdaProtocolNECext, 0xFFFF, 0x7F, false}, - {IrdaProtocolNECext, 0xFFFF, 0xFF, false}, - {IrdaProtocolNECext, 0xFFFF, 0xFF, true}, - {IrdaProtocolNECext, 0xAAAA, 0x55, false}, - {IrdaProtocolNECext, 0x5555, 0xAA, false}, - {IrdaProtocolNECext, 0x5555, 0x55, false}, - {IrdaProtocolNECext, 0xAAAA, 0xAA, false}, - {IrdaProtocolNECext, 0xAAAA, 0xAA, true}, + {IrdaProtocolNECext, 0x0000, 0x0000, false}, + {IrdaProtocolNECext, 0x0001, 0x0000, false}, + {IrdaProtocolNECext, 0x0001, 0x8000, false}, + {IrdaProtocolNECext, 0x0000, 0x8000, false}, + {IrdaProtocolNECext, 0x0000, 0x0000, false}, + {IrdaProtocolNECext, 0x0000, 0x0000, true}, + {IrdaProtocolNECext, 0x0000, 0x0000, false}, + {IrdaProtocolNECext, 0x0000, 0x0000, true}, + {IrdaProtocolNECext, 0xFFFF, 0xFFFF, false}, + {IrdaProtocolNECext, 0xFFFE, 0xFFFF, false}, + {IrdaProtocolNECext, 0xFFFE, 0x7FFF, false}, + {IrdaProtocolNECext, 0xFFFF, 0x7FFF, false}, + {IrdaProtocolNECext, 0xFFFF, 0xFFFF, false}, + {IrdaProtocolNECext, 0xFFFF, 0xFFFF, true}, + {IrdaProtocolNECext, 0xAAAA, 0x5555, false}, + {IrdaProtocolNECext, 0x5555, 0xAAAA, false}, + {IrdaProtocolNECext, 0x5555, 0x5555, false}, + {IrdaProtocolNECext, 0xAAAA, 0xAAAA, false}, + {IrdaProtocolNECext, 0xAAAA, 0xAAAA, true}, - {IrdaProtocolNECext, 0xAAAA, 0xAA, false}, - {IrdaProtocolNECext, 0xAAAA, 0xAA, true}, - {IrdaProtocolNECext, 0xAAAA, 0xAA, true}, + {IrdaProtocolNECext, 0xAAAA, 0xAAAA, false}, + {IrdaProtocolNECext, 0xAAAA, 0xAAAA, true}, + {IrdaProtocolNECext, 0xAAAA, 0xAAAA, true}, - {IrdaProtocolNECext, 0x5555, 0x55, false}, - {IrdaProtocolNECext, 0x5555, 0x55, true}, - {IrdaProtocolNECext, 0x5555, 0x55, true}, - {IrdaProtocolNECext, 0x5555, 0x55, true}, + {IrdaProtocolNECext, 0x5555, 0x5555, false}, + {IrdaProtocolNECext, 0x5555, 0x5555, true}, + {IrdaProtocolNECext, 0x5555, 0x5555, true}, + {IrdaProtocolNECext, 0x5555, 0x5555, true}, }; diff --git a/applications/tests/irda_decoder_encoder/test_data/irda_sirc_test_data.srcdata b/applications/tests/irda_decoder_encoder/test_data/irda_sirc_test_data.srcdata index 2968aaca8f9..bacf4be522d 100644 --- a/applications/tests/irda_decoder_encoder/test_data/irda_sirc_test_data.srcdata +++ b/applications/tests/irda_decoder_encoder/test_data/irda_sirc_test_data.srcdata @@ -426,20 +426,14 @@ const IrdaMessage test_decoder_sirc_expected5[] = { {IrdaProtocolSIRC20, 0xFB5, 0x53, false}, }; - - - const IrdaMessage test_encoder_sirc_input1[] = { {IrdaProtocolSIRC, 0xA, 0x55, false}, }; const uint32_t test_encoder_sirc_expected1[] = { -10000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, +10000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, }; - - - const IrdaMessage test_encoder_sirc_input2[] = { {IrdaProtocolSIRC15, 0x7D, 0x53, false}, {IrdaProtocolSIRC15, 0x7D, 0x53, true}, @@ -447,9 +441,9 @@ const IrdaMessage test_encoder_sirc_input2[] = { }; const uint32_t test_encoder_sirc_expected2[] = { - 10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, 600, /* 2 low levels in row */ - 18000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, 600, /* 2 low levels in row */ - 18000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, 600, + 10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, + 18600, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, + 18600, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, }; const IrdaMessage test_sirc[] = { diff --git a/core/furi/check.c b/core/furi/check.c index 77e239bce21..c6c5660864e 100644 --- a/core/furi/check.c +++ b/core/furi/check.c @@ -3,10 +3,7 @@ #include #include -void __furi_abort(void); - void __furi_print_name(void) { - furi_hal_console_puts("\r\n\033[0;31m[E]"); if(task_is_isr_context()) { furi_hal_console_puts("[ISR] "); } else { @@ -19,13 +16,6 @@ void __furi_print_name(void) { furi_hal_console_puts("] "); } } - furi_hal_console_puts("\033[0m"); -} - -void __furi_check(void) { - __furi_print_name(); - furi_hal_console_puts("assertion failed\r\n"); - __furi_abort(); } void __furi_abort(void) { @@ -33,4 +23,13 @@ void __furi_abort(void) { asm("bkpt 1"); while(1) { } -} \ No newline at end of file +} + +void furi_crash(const char* message) { + furi_hal_console_puts("\r\n\033[0;31m[CRASH]"); + __furi_print_name(); + furi_hal_console_puts(message ? message : "Programming Error"); + furi_hal_console_puts("\r\nSystem halted. Connect debugger for more info\r\n"); + furi_hal_console_puts("\033[0m\r\n"); + __furi_abort(); +} diff --git a/core/furi/check.h b/core/furi/check.h index 4f65aa72892..5115fda3f84 100644 --- a/core/furi/check.h +++ b/core/furi/check.h @@ -4,40 +4,18 @@ extern "C" { #endif -// Find how to how get function's pretty name -#ifndef __FURI_CHECK_FUNC -// Use g++'s demangled names in C++ -#if defined __cplusplus && defined __GNUC__ -#define __FURI_CHECK_FUNC __PRETTY_FUNCTION__ - -// C99 requires the use of __func__ -#elif __STDC_VERSION__ >= 199901L -#define __FURI_CHECK_FUNC __func__ - -// Older versions of gcc don't have __func__ but can use __FUNCTION__ -#elif __GNUC__ >= 2 -#define __FURI_CHECK_FUNC __FUNCTION__ - -// failed to detect __func__ support -#else -#define __FURI_CHECK_FUNC ((char*)0) -#endif -#endif -// !__FURI_CHECK_FUNC - -// We have two levels of assertion -// One - furi_check, which always runs, the only difference is in the level of debug information -// The second is furi_assert, which doesn't compile in release mode -#define furi_check(__e) ((__e) ? (void)0 : __furi_check()) +/** Check condition and crash if check failed */ +#define furi_check(__e) ((__e) ? (void)0 : furi_crash("fury_check failed\r\n")) +/** Only in debug build: Assert condition and crash if assert failed */ #ifdef NDEBUG #define furi_assert(__e) ((void)0) #else -#define furi_assert(__e) ((__e) ? (void)0 : __furi_check()) +#define furi_assert(__e) ((__e) ? (void)0 : furi_crash("furi_assert failed\r\n")) #endif -// !NDEBUG -void __furi_check(void); +/** Crash system */ +void furi_crash(const char* message); #ifdef __cplusplus } diff --git a/core/furi/memmgr_heap.c b/core/furi/memmgr_heap.c index 16116f1e6ba..8e57914e96c 100644 --- a/core/furi/memmgr_heap.c +++ b/core/furi/memmgr_heap.c @@ -155,19 +155,21 @@ void memmgr_heap_disable_thread_trace(osThreadId_t thread_id) { } size_t memmgr_heap_get_thread_memory(osThreadId_t thread_id) { - size_t leftovers = 0; + size_t leftovers = MEMMGR_HEAP_UNKNOWN; vTaskSuspendAll(); { memmgr_heap_thread_trace_depth++; MemmgrHeapAllocDict_t* alloc_dict = MemmgrHeapThreadDict_get(memmgr_heap_thread_dict, (uint32_t)thread_id); - furi_check(alloc_dict); - MemmgrHeapAllocDict_it_t alloc_dict_it; - for(MemmgrHeapAllocDict_it(alloc_dict_it, *alloc_dict); - !MemmgrHeapAllocDict_end_p(alloc_dict_it); - MemmgrHeapAllocDict_next(alloc_dict_it)) { - MemmgrHeapAllocDict_itref_t* data = MemmgrHeapAllocDict_ref(alloc_dict_it); - leftovers += data->value; + if(alloc_dict) { + leftovers = 0; + MemmgrHeapAllocDict_it_t alloc_dict_it; + for(MemmgrHeapAllocDict_it(alloc_dict_it, *alloc_dict); + !MemmgrHeapAllocDict_end_p(alloc_dict_it); + MemmgrHeapAllocDict_next(alloc_dict_it)) { + MemmgrHeapAllocDict_itref_t* data = MemmgrHeapAllocDict_ref(alloc_dict_it); + leftovers += data->value; + } } memmgr_heap_thread_trace_depth--; } diff --git a/core/furi/memmgr_heap.h b/core/furi/memmgr_heap.h index 327f8d4f0e7..cbb8fa89ced 100644 --- a/core/furi/memmgr_heap.h +++ b/core/furi/memmgr_heap.h @@ -7,6 +7,8 @@ extern "C" { #endif +#define MEMMGR_HEAP_UNKNOWN 0xFFFFFFFF + /** Memmgr heap enable thread allocation tracking * @param thread_id - thread id to track */ diff --git a/firmware/targets/f6/Inc/aes.h b/firmware/targets/f6/Inc/aes.h deleted file mode 100644 index bde8ad5a821..00000000000 --- a/firmware/targets/f6/Inc/aes.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - ****************************************************************************** - * @file aes.h - * @brief This file contains all the function prototypes for - * the aes.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __AES_H__ -#define __AES_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern CRYP_HandleTypeDef hcryp1; -extern CRYP_HandleTypeDef hcryp2; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_AES1_Init(void); -void MX_AES2_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __AES_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f6/Inc/pka.h b/firmware/targets/f6/Inc/pka.h deleted file mode 100644 index 377ed0105f1..00000000000 --- a/firmware/targets/f6/Inc/pka.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - ****************************************************************************** - * @file pka.h - * @brief This file contains all the function prototypes for - * the pka.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __PKA_H__ -#define __PKA_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern PKA_HandleTypeDef hpka; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_PKA_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __PKA_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f6/Inc/rf.h b/firmware/targets/f6/Inc/rf.h deleted file mode 100644 index 1796e939a9a..00000000000 --- a/firmware/targets/f6/Inc/rf.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - ****************************************************************************** - * @file rf.h - * @brief This file contains all the function prototypes for - * the rf.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __RF_H__ -#define __RF_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_RF_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __RF_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f6/Inc/rng.h b/firmware/targets/f6/Inc/rng.h deleted file mode 100644 index fa121ad11cf..00000000000 --- a/firmware/targets/f6/Inc/rng.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - ****************************************************************************** - * @file rng.h - * @brief This file contains all the function prototypes for - * the rng.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __RNG_H__ -#define __RNG_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern RNG_HandleTypeDef hrng; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_RNG_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __RNG_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f6/Src/aes.c b/firmware/targets/f6/Src/aes.c deleted file mode 100644 index 1a042e9b8d1..00000000000 --- a/firmware/targets/f6/Src/aes.c +++ /dev/null @@ -1,127 +0,0 @@ -/** - ****************************************************************************** - * @file aes.c - * @brief This file provides code for the configuration - * of the AES instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "aes.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -CRYP_HandleTypeDef hcryp1; -__ALIGN_BEGIN static const uint32_t pKeyAES1[4] __ALIGN_END = { - 0x00000000,0x00000000,0x00000000,0x00000000}; -CRYP_HandleTypeDef hcryp2; -__ALIGN_BEGIN static const uint32_t pKeyAES2[4] __ALIGN_END = { - 0x00000000,0x00000000,0x00000000,0x00000000}; - -/* AES1 init function */ -void MX_AES1_Init(void) -{ - - hcryp1.Instance = AES1; - hcryp1.Init.DataType = CRYP_DATATYPE_32B; - hcryp1.Init.KeySize = CRYP_KEYSIZE_128B; - hcryp1.Init.pKey = (uint32_t *)pKeyAES1; - hcryp1.Init.Algorithm = CRYP_AES_ECB; - hcryp1.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_WORD; - hcryp1.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS; - if (HAL_CRYP_Init(&hcryp1) != HAL_OK) - { - Error_Handler(); - } - -} -/* AES2 init function */ -void MX_AES2_Init(void) -{ - - hcryp2.Instance = AES2; - hcryp2.Init.DataType = CRYP_DATATYPE_32B; - hcryp2.Init.KeySize = CRYP_KEYSIZE_128B; - hcryp2.Init.pKey = (uint32_t *)pKeyAES2; - hcryp2.Init.Algorithm = CRYP_AES_ECB; - hcryp2.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_WORD; - hcryp2.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS; - if (HAL_CRYP_Init(&hcryp2) != HAL_OK) - { - Error_Handler(); - } - -} - -void HAL_CRYP_MspInit(CRYP_HandleTypeDef* crypHandle) -{ - - if(crypHandle->Instance==AES1) - { - /* USER CODE BEGIN AES1_MspInit 0 */ - - /* USER CODE END AES1_MspInit 0 */ - /* AES1 clock enable */ - __HAL_RCC_AES1_CLK_ENABLE(); - /* USER CODE BEGIN AES1_MspInit 1 */ - - /* USER CODE END AES1_MspInit 1 */ - } - else if(crypHandle->Instance==AES2) - { - /* USER CODE BEGIN AES2_MspInit 0 */ - - /* USER CODE END AES2_MspInit 0 */ - /* AES2 clock enable */ - __HAL_RCC_AES2_CLK_ENABLE(); - /* USER CODE BEGIN AES2_MspInit 1 */ - - /* USER CODE END AES2_MspInit 1 */ - } -} - -void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef* crypHandle) -{ - - if(crypHandle->Instance==AES1) - { - /* USER CODE BEGIN AES1_MspDeInit 0 */ - - /* USER CODE END AES1_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_AES1_CLK_DISABLE(); - /* USER CODE BEGIN AES1_MspDeInit 1 */ - - /* USER CODE END AES1_MspDeInit 1 */ - } - else if(crypHandle->Instance==AES2) - { - /* USER CODE BEGIN AES2_MspDeInit 0 */ - - /* USER CODE END AES2_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_AES2_CLK_DISABLE(); - /* USER CODE BEGIN AES2_MspDeInit 1 */ - - /* USER CODE END AES2_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f6/Src/pka.c b/firmware/targets/f6/Src/pka.c deleted file mode 100644 index 8377ce5722d..00000000000 --- a/firmware/targets/f6/Src/pka.c +++ /dev/null @@ -1,77 +0,0 @@ -/** - ****************************************************************************** - * @file pka.c - * @brief This file provides code for the configuration - * of the PKA instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "pka.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -PKA_HandleTypeDef hpka; - -/* PKA init function */ -void MX_PKA_Init(void) -{ - - hpka.Instance = PKA; - if (HAL_PKA_Init(&hpka) != HAL_OK) - { - Error_Handler(); - } - -} - -void HAL_PKA_MspInit(PKA_HandleTypeDef* pkaHandle) -{ - - if(pkaHandle->Instance==PKA) - { - /* USER CODE BEGIN PKA_MspInit 0 */ - - /* USER CODE END PKA_MspInit 0 */ - /* PKA clock enable */ - __HAL_RCC_PKA_CLK_ENABLE(); - /* USER CODE BEGIN PKA_MspInit 1 */ - - /* USER CODE END PKA_MspInit 1 */ - } -} - -void HAL_PKA_MspDeInit(PKA_HandleTypeDef* pkaHandle) -{ - - if(pkaHandle->Instance==PKA) - { - /* USER CODE BEGIN PKA_MspDeInit 0 */ - - /* USER CODE END PKA_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_PKA_CLK_DISABLE(); - /* USER CODE BEGIN PKA_MspDeInit 1 */ - - /* USER CODE END PKA_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f6/Src/rf.c b/firmware/targets/f6/Src/rf.c deleted file mode 100644 index 62daf9b2183..00000000000 --- a/firmware/targets/f6/Src/rf.c +++ /dev/null @@ -1,37 +0,0 @@ -/** - ****************************************************************************** - * @file rf.c - * @brief This file provides code for the configuration - * of the RF instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "rf.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -/* RF init function */ -void MX_RF_Init(void) -{ - -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f6/Src/rng.c b/firmware/targets/f6/Src/rng.c deleted file mode 100644 index c2fb144e64a..00000000000 --- a/firmware/targets/f6/Src/rng.c +++ /dev/null @@ -1,77 +0,0 @@ -/** - ****************************************************************************** - * @file rng.c - * @brief This file provides code for the configuration - * of the RNG instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "rng.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -RNG_HandleTypeDef hrng; - -/* RNG init function */ -void MX_RNG_Init(void) -{ - - hrng.Instance = RNG; - if (HAL_RNG_Init(&hrng) != HAL_OK) - { - Error_Handler(); - } - -} - -void HAL_RNG_MspInit(RNG_HandleTypeDef* rngHandle) -{ - - if(rngHandle->Instance==RNG) - { - /* USER CODE BEGIN RNG_MspInit 0 */ - - /* USER CODE END RNG_MspInit 0 */ - /* RNG clock enable */ - __HAL_RCC_RNG_CLK_ENABLE(); - /* USER CODE BEGIN RNG_MspInit 1 */ - - /* USER CODE END RNG_MspInit 1 */ - } -} - -void HAL_RNG_MspDeInit(RNG_HandleTypeDef* rngHandle) -{ - - if(rngHandle->Instance==RNG) - { - /* USER CODE BEGIN RNG_MspDeInit 0 */ - - /* USER CODE END RNG_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_RNG_CLK_DISABLE(); - /* USER CODE BEGIN RNG_MspDeInit 1 */ - - /* USER CODE END RNG_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f6/ble-glue/app_ble.c b/firmware/targets/f6/ble-glue/app_ble.c deleted file mode 100644 index 652c29efe50..00000000000 --- a/firmware/targets/f6/ble-glue/app_ble.c +++ /dev/null @@ -1,140 +0,0 @@ -#include "main.h" - -#include "app_entry.h" -#include "app_common.h" -#include "dbg_trace.h" -#include "ble.h" -#include "tl.h" -#include "app_ble.h" -#include "shci.h" -#include "cmsis_os.h" - -#include - -PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t BleCmdBuffer; - -// PLACE_IN_SECTION("TAG_OTA_END") const uint32_t MagicKeywordValue = 0x94448A29 ; -// PLACE_IN_SECTION("TAG_OTA_START") const uint32_t MagicKeywordAddress = (uint32_t)&MagicKeywordValue; - -osMutexId_t MtxHciId; -osSemaphoreId_t SemHciId; -osThreadId_t HciUserEvtProcessId; - -const osThreadAttr_t HciUserEvtProcess_attr = { - .name = CFG_HCI_USER_EVT_PROCESS_NAME, - .attr_bits = CFG_HCI_USER_EVT_PROCESS_ATTR_BITS, - .cb_mem = CFG_HCI_USER_EVT_PROCESS_CB_MEM, - .cb_size = CFG_HCI_USER_EVT_PROCESS_CB_SIZE, - .stack_mem = CFG_HCI_USER_EVT_PROCESS_STACK_MEM, - .priority = CFG_HCI_USER_EVT_PROCESS_PRIORITY, - .stack_size = CFG_HCI_USER_EVT_PROCESS_STACK_SIZE -}; - -/* Private function prototypes -----------------------------------------------*/ -static void HciUserEvtProcess(void *argument); -static void BLE_UserEvtRx( void * pPayload ); -static void BLE_StatusNot( HCI_TL_CmdStatus_t status ); -static void Ble_Tl_Init( void ); - -bool APP_BLE_Init() { - SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = { - {{0,0,0}}, /**< Header unused */ - {0, /** pBleBufferAddress not used */ - 0, /** BleBufferSize not used */ - CFG_BLE_NUM_GATT_ATTRIBUTES, - CFG_BLE_NUM_GATT_SERVICES, - CFG_BLE_ATT_VALUE_ARRAY_SIZE, - CFG_BLE_NUM_LINK, - CFG_BLE_DATA_LENGTH_EXTENSION, - CFG_BLE_PREPARE_WRITE_LIST_SIZE, - CFG_BLE_MBLOCK_COUNT, - CFG_BLE_MAX_ATT_MTU, - CFG_BLE_SLAVE_SCA, - CFG_BLE_MASTER_SCA, - CFG_BLE_LSE_SOURCE, - CFG_BLE_MAX_CONN_EVENT_LENGTH, - CFG_BLE_HSE_STARTUP_TIME, - CFG_BLE_VITERBI_MODE, - CFG_BLE_LL_ONLY, - 0} - }; - - // Initialize Ble Transport Layer - Ble_Tl_Init( ); - // Register the hci transport layer to handle BLE User Asynchronous Events - HciUserEvtProcessId = osThreadNew(HciUserEvtProcess, NULL, &HciUserEvtProcess_attr); - // Starts the BLE Stack on CPU2 - return (SHCI_C2_BLE_Init( &ble_init_cmd_packet ) == SHCI_Success); -} - -static void Ble_Tl_Init( void ) { - HCI_TL_HciInitConf_t Hci_Tl_Init_Conf; - - MtxHciId = osMutexNew( NULL ); - SemHciId = osSemaphoreNew( 1, 0, NULL ); /*< Create the semaphore and make it busy at initialization */ - - Hci_Tl_Init_Conf.p_cmdbuffer = (uint8_t*)&BleCmdBuffer; - Hci_Tl_Init_Conf.StatusNotCallBack = BLE_StatusNot; - hci_init(BLE_UserEvtRx, (void*) &Hci_Tl_Init_Conf); -} - -static void HciUserEvtProcess(void *argument) { - UNUSED(argument); - - for(;;) - { - osThreadFlagsWait( 1, osFlagsWaitAny, osWaitForever); - hci_user_evt_proc( ); - } -} - -/************************************************************* - * - * WRAP FUNCTIONS - * - *************************************************************/ -void hci_notify_asynch_evt(void* pdata) { - UNUSED(pdata); - osThreadFlagsSet( HciUserEvtProcessId, 1 ); -} - -void hci_cmd_resp_release(uint32_t flag) { - UNUSED(flag); - osSemaphoreRelease( SemHciId ); -} - -void hci_cmd_resp_wait(uint32_t timeout) { - UNUSED(timeout); - osSemaphoreAcquire( SemHciId, osWaitForever ); -} - -static void BLE_UserEvtRx( void * pPayload ) { - SVCCTL_UserEvtFlowStatus_t svctl_return_status; - tHCI_UserEvtRxParam *pParam; - - pParam = (tHCI_UserEvtRxParam *)pPayload; - - svctl_return_status = SVCCTL_UserEvtRx((void *)&(pParam->pckt->evtserial)); - if (svctl_return_status != SVCCTL_UserEvtFlowDisable) { - pParam->status = HCI_TL_UserEventFlow_Enable; - } else { - pParam->status = HCI_TL_UserEventFlow_Disable; - } -} - -static void BLE_StatusNot( HCI_TL_CmdStatus_t status ) { - switch (status) { - case HCI_TL_CmdBusy: - osMutexAcquire( MtxHciId, osWaitForever ); - break; - case HCI_TL_CmdAvailable: - osMutexRelease( MtxHciId ); - break; - default: - break; - } -} - -void SVCCTL_ResumeUserEventFlow( void ) { - hci_resume_flow(); -} diff --git a/firmware/targets/f6/ble-glue/app_conf.h b/firmware/targets/f6/ble-glue/app_conf.h index 381d5ae741f..bfd6f9dd803 100644 --- a/firmware/targets/f6/ble-glue/app_conf.h +++ b/firmware/targets/f6/ble-glue/app_conf.h @@ -427,9 +427,6 @@ typedef enum #define DBG_TRACE_MSG_QUEUE_SIZE 4096 #define MAX_DBG_TRACE_MSG_SIZE 1024 -#define CFG_LED_SUPPORTED 0 -#define CFG_BUTTON_SUPPORTED 0 - /****************************************************************************** * FreeRTOS ******************************************************************************/ @@ -441,34 +438,5 @@ typedef enum #define CFG_SHCI_USER_EVT_PROCESS_PRIORITY osPriorityNone #define CFG_SHCI_USER_EVT_PROCESS_STACK_SIZE (128 * 7) -#define CFG_HCI_USER_EVT_PROCESS_NAME "ble_hci_evt" -#define CFG_HCI_USER_EVT_PROCESS_ATTR_BITS (0) -#define CFG_HCI_USER_EVT_PROCESS_CB_MEM (0) -#define CFG_HCI_USER_EVT_PROCESS_CB_SIZE (0) -#define CFG_HCI_USER_EVT_PROCESS_STACK_MEM (0) -#define CFG_HCI_USER_EVT_PROCESS_PRIORITY osPriorityNone -#define CFG_HCI_USER_EVT_PROCESS_STACK_SIZE (128 * 8) - -#define CFG_ADV_UPDATE_PROCESS_NAME "ble_adv_upd" -#define CFG_ADV_UPDATE_PROCESS_ATTR_BITS (0) -#define CFG_ADV_UPDATE_PROCESS_CB_MEM (0) -#define CFG_ADV_UPDATE_PROCESS_CB_SIZE (0) -#define CFG_ADV_UPDATE_PROCESS_STACK_MEM (0) -#define CFG_ADV_UPDATE_PROCESS_PRIORITY osPriorityNone -#define CFG_ADV_UPDATE_PROCESS_STACK_SIZE (128 * 6) - -#define CFG_HRS_PROCESS_NAME "hrs" -#define CFG_HRS_PROCESS_ATTR_BITS (0) -#define CFG_HRS_PROCESS_CB_MEM (0) -#define CFG_HRS_PROCESS_CB_SIZE (0) -#define CFG_HRS_PROCESS_STACK_MEM (0) -#define CFG_HRS_PROCESS_PRIORITY osPriorityNone -#define CFG_HRS_PROCESS_STACK_SIZE (128 * 8) - -typedef enum { - CFG_LPM_APP, - CFG_LPM_APP_BLE, -} CFG_LPM_Id_t; - #define CFG_OTP_BASE_ADDRESS OTP_AREA_BASE #define CFG_OTP_END_ADRESS OTP_AREA_END_ADDR diff --git a/firmware/targets/f6/ble-glue/app_entry.c b/firmware/targets/f6/ble-glue/app_entry.c index 431fed6aa99..a970da320a2 100644 --- a/firmware/targets/f6/ble-glue/app_entry.c +++ b/firmware/targets/f6/ble-glue/app_entry.c @@ -1,7 +1,7 @@ #include "app_common.h" #include "main.h" #include "app_entry.h" -#include "app_ble.h" +#include "ble_app.h" #include "ble.h" #include "tl.h" #include "cmsis_os.h" @@ -47,8 +47,6 @@ void APPE_Init() { ble_glue_status = BleGlueStatusStartup; SystemPower_Config(); /**< Configure the system Power Mode */ - HW_TS_Init(hw_ts_InitMode_Full, &hrtc); /**< Initialize the TimerServer */ - // APPD_Init(); furi_hal_power_insomnia_enter(); @@ -137,7 +135,7 @@ static void APPE_SysUserEvtRx( void * pPayload ) { /* Traces channel initialization */ // APPD_EnableCPU2( ); - if (APP_BLE_Init()) { + if(ble_app_init()) { FURI_LOG_I("Core2", "BLE stack started"); ble_glue_status = BleGlueStatusStarted; } else { diff --git a/firmware/targets/f6/ble-glue/battery_service.c b/firmware/targets/f6/ble-glue/battery_service.c index 654edd537e0..1dd8c5a0332 100644 --- a/firmware/targets/f6/ble-glue/battery_service.c +++ b/firmware/targets/f6/ble-glue/battery_service.c @@ -31,7 +31,7 @@ void battery_svc_start() { (Char_UUID_t *) &char_battery_level_uuid, 1, CHAR_PROP_READ | CHAR_PROP_NOTIFY, - ATTR_PERMISSION_NONE, + ATTR_PERMISSION_AUTHEN_READ, GATT_DONT_NOTIFY_EVENTS, 10, CHAR_VALUE_LEN_CONSTANT, diff --git a/firmware/targets/f6/ble-glue/ble_app.c b/firmware/targets/f6/ble-glue/ble_app.c new file mode 100644 index 00000000000..e28facd6dd5 --- /dev/null +++ b/firmware/targets/f6/ble-glue/ble_app.c @@ -0,0 +1,119 @@ +#include "ble_app.h" + +#include "hci_tl.h" +#include "ble.h" +#include "shci.h" +#include "cmsis_os.h" +#include "gap.h" + +#include + +#define BLE_APP_TAG "ble app" + +PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t ble_app_cmd_buffer; + +typedef struct { + osMutexId_t hci_mtx; + osSemaphoreId_t hci_sem; + osThreadId_t hci_thread_id; + osThreadAttr_t hci_thread_attr; +} BleApp; + +static BleApp* ble_app; + +static void ble_app_hci_thread(void *arg); +static void ble_app_hci_event_handler(void * pPayload); +static void ble_app_hci_status_not_handler(HCI_TL_CmdStatus_t status); + +bool ble_app_init() { + ble_app = furi_alloc(sizeof(BleApp)); + + // Allocate semafore and mutex for ble command buffer access + ble_app->hci_mtx = osMutexNew(NULL); + ble_app->hci_sem = osSemaphoreNew(1, 0, NULL); + // HCI transport layer thread to handle user asynch events + ble_app->hci_thread_attr.name = "ble hci"; + ble_app->hci_thread_attr.stack_size = 1024; + ble_app->hci_thread_id = osThreadNew(ble_app_hci_thread, NULL, &ble_app->hci_thread_attr); + + // Initialize Ble Transport Layer + HCI_TL_HciInitConf_t hci_tl_config = { + .p_cmdbuffer = (uint8_t*)&ble_app_cmd_buffer, + .StatusNotCallBack = ble_app_hci_status_not_handler, + }; + hci_init(ble_app_hci_event_handler, (void*)&hci_tl_config); + + // Start ble stack on 2nd core + SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = { + .Header = {{0,0,0}}, // Header unused + .Param = { + 0, // pBleBufferAddress not used + 0, // BleBufferSize not used + CFG_BLE_NUM_GATT_ATTRIBUTES, + CFG_BLE_NUM_GATT_SERVICES, + CFG_BLE_ATT_VALUE_ARRAY_SIZE, + CFG_BLE_NUM_LINK, + CFG_BLE_DATA_LENGTH_EXTENSION, + CFG_BLE_PREPARE_WRITE_LIST_SIZE, + CFG_BLE_MBLOCK_COUNT, + CFG_BLE_MAX_ATT_MTU, + CFG_BLE_SLAVE_SCA, + CFG_BLE_MASTER_SCA, + CFG_BLE_LSE_SOURCE, + CFG_BLE_MAX_CONN_EVENT_LENGTH, + CFG_BLE_HSE_STARTUP_TIME, + CFG_BLE_VITERBI_MODE, + CFG_BLE_LL_ONLY, + 0, + } + }; + SHCI_CmdStatus_t status = SHCI_C2_BLE_Init(&ble_init_cmd_packet); + if(status) { + FURI_LOG_E(BLE_APP_TAG, "Failed to start ble stack: %d", status); + } + return status == SHCI_Success; +} + +static void ble_app_hci_thread(void *arg) { + while(1) { + osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); + hci_user_evt_proc(); + } +} + +// Called by WPAN lib +void hci_notify_asynch_evt(void* pdata) { + osThreadFlagsSet(ble_app->hci_thread_id, 1); +} + +void hci_cmd_resp_release(uint32_t flag) { + osSemaphoreRelease(ble_app->hci_sem); +} + +void hci_cmd_resp_wait(uint32_t timeout) { + osSemaphoreAcquire(ble_app->hci_sem, osWaitForever); +} + +static void ble_app_hci_event_handler( void * pPayload ) { + SVCCTL_UserEvtFlowStatus_t svctl_return_status; + tHCI_UserEvtRxParam *pParam = (tHCI_UserEvtRxParam *)pPayload; + + svctl_return_status = SVCCTL_UserEvtRx((void *)&(pParam->pckt->evtserial)); + if (svctl_return_status != SVCCTL_UserEvtFlowDisable) { + pParam->status = HCI_TL_UserEventFlow_Enable; + } else { + pParam->status = HCI_TL_UserEventFlow_Disable; + } +} + +static void ble_app_hci_status_not_handler( HCI_TL_CmdStatus_t status ) { + if(status == HCI_TL_CmdBusy) { + osMutexAcquire(ble_app->hci_mtx, osWaitForever ); + } else if(status == HCI_TL_CmdAvailable) { + osMutexRelease(ble_app->hci_mtx); + } +} + +void SVCCTL_ResumeUserEventFlow( void ) { + hci_resume_flow(); +} diff --git a/firmware/targets/f6/ble-glue/app_ble.h b/firmware/targets/f6/ble-glue/ble_app.h similarity index 72% rename from firmware/targets/f6/ble-glue/app_ble.h rename to firmware/targets/f6/ble-glue/ble_app.h index 08c60fe30e2..17d8dc5f755 100644 --- a/firmware/targets/f6/ble-glue/app_ble.h +++ b/firmware/targets/f6/ble-glue/ble_app.h @@ -5,9 +5,8 @@ extern "C" { #endif #include -#include "hci_tl.h" -bool APP_BLE_Init(); +bool ble_app_init(); #ifdef __cplusplus } diff --git a/firmware/targets/f6/ble-glue/dev_info_service.c b/firmware/targets/f6/ble-glue/dev_info_service.c index db58226b3d3..ae07d9bcd18 100644 --- a/firmware/targets/f6/ble-glue/dev_info_service.c +++ b/firmware/targets/f6/ble-glue/dev_info_service.c @@ -39,7 +39,7 @@ void dev_info_svc_start() { (Char_UUID_t*)&uuid, strlen(dev_info_man_name), CHAR_PROP_READ, - ATTR_PERMISSION_NONE, + ATTR_PERMISSION_AUTHEN_READ, GATT_DONT_NOTIFY_EVENTS, 10, CHAR_VALUE_LEN_CONSTANT, @@ -53,7 +53,7 @@ void dev_info_svc_start() { (Char_UUID_t*)&uuid, strlen(dev_info_serial_num), CHAR_PROP_READ, - ATTR_PERMISSION_NONE, + ATTR_PERMISSION_AUTHEN_READ, GATT_DONT_NOTIFY_EVENTS, 10, CHAR_VALUE_LEN_CONSTANT, @@ -67,7 +67,7 @@ void dev_info_svc_start() { (Char_UUID_t*)&uuid, strlen(dev_info_firmware_rev_num), CHAR_PROP_READ, - ATTR_PERMISSION_NONE, + ATTR_PERMISSION_AUTHEN_READ, GATT_DONT_NOTIFY_EVENTS, 10, CHAR_VALUE_LEN_CONSTANT, @@ -81,7 +81,7 @@ void dev_info_svc_start() { (Char_UUID_t*)&uuid, strlen(dev_info_software_rev_num), CHAR_PROP_READ, - ATTR_PERMISSION_NONE, + ATTR_PERMISSION_AUTHEN_READ, GATT_DONT_NOTIFY_EVENTS, 10, CHAR_VALUE_LEN_CONSTANT, diff --git a/firmware/targets/f6/ble-glue/gap.c b/firmware/targets/f6/ble-glue/gap.c index 19d1b5f183b..74e1d35a3d6 100644 --- a/firmware/targets/f6/ble-glue/gap.c +++ b/firmware/targets/f6/ble-glue/gap.c @@ -31,13 +31,22 @@ typedef struct { typedef struct { GapSvc gap_svc; GapState state; + osMutexId_t state_mutex; uint8_t mac_address[BD_ADDR_SIZE_LOCAL]; Bt* bt; osTimerId advertise_timer; osThreadAttr_t thread_attr; osThreadId_t thread_id; + osMessageQueueId_t command_queue; + bool enable_adv; } Gap; +typedef enum { + GapCommandAdvFast, + GapCommandAdvLowPower, + GapCommandAdvStop, +} GapCommand; + // Identity root key static const uint8_t gap_irk[16] = {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0}; // Encryption root key @@ -49,150 +58,151 @@ static const uint8_t gap_default_mac_addr[] = {0x6c, 0x7a, 0xd8, 0xac, 0x57, 0x7 static Gap* gap = NULL; -static void gap_advertise(GapState new_state); +static void gap_advertise_start(GapState new_state); static void gap_app(void *arg); SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) { - hci_event_pckt *event_pckt; - evt_le_meta_event *meta_evt; - evt_blue_aci *blue_evt; - hci_le_phy_update_complete_event_rp0 *evt_le_phy_update_complete; - uint8_t tx_phy; - uint8_t rx_phy; - tBleStatus ret = BLE_STATUS_INVALID_PARAMS; - - event_pckt = (hci_event_pckt*) ((hci_uart_pckt *) pckt)->data; - - switch (event_pckt->evt) { - case EVT_DISCONN_COMPLETE: - { - hci_disconnection_complete_event_rp0 *disconnection_complete_event = (hci_disconnection_complete_event_rp0 *) event_pckt->data; - if (disconnection_complete_event->Connection_Handle == gap->gap_svc.connection_handle) { - gap->gap_svc.connection_handle = 0; - gap->state = GapStateIdle; - FURI_LOG_I(GAP_TAG, "Disconnect from client"); - } - // Restart advertising - gap_advertise(GapStateAdvFast); - furi_hal_power_insomnia_exit(); - } - break; - - case EVT_LE_META_EVENT: - meta_evt = (evt_le_meta_event*) event_pckt->data; - switch (meta_evt->subevent) { - case EVT_LE_CONN_UPDATE_COMPLETE: - FURI_LOG_D(GAP_TAG, "Connection update event"); - break; - - case EVT_LE_PHY_UPDATE_COMPLETE: - evt_le_phy_update_complete = (hci_le_phy_update_complete_event_rp0*)meta_evt->data; - if(evt_le_phy_update_complete->Status) { - FURI_LOG_E(GAP_TAG, "Update PHY failed, status %d", evt_le_phy_update_complete->Status); - } else { - FURI_LOG_I(GAP_TAG, "Update PHY succeed"); + hci_event_pckt *event_pckt; + evt_le_meta_event *meta_evt; + evt_blue_aci *blue_evt; + hci_le_phy_update_complete_event_rp0 *evt_le_phy_update_complete; + uint8_t tx_phy; + uint8_t rx_phy; + tBleStatus ret = BLE_STATUS_INVALID_PARAMS; + + event_pckt = (hci_event_pckt*) ((hci_uart_pckt *) pckt)->data; + + osMutexAcquire(gap->state_mutex, osWaitForever); + switch (event_pckt->evt) { + case EVT_DISCONN_COMPLETE: + { + hci_disconnection_complete_event_rp0 *disconnection_complete_event = (hci_disconnection_complete_event_rp0 *) event_pckt->data; + if (disconnection_complete_event->Connection_Handle == gap->gap_svc.connection_handle) { + gap->gap_svc.connection_handle = 0; + gap->state = GapStateIdle; + FURI_LOG_I(GAP_TAG, "Disconnect from client"); } - ret = hci_le_read_phy(gap->gap_svc.connection_handle,&tx_phy,&rx_phy); - if(ret) { - FURI_LOG_E(GAP_TAG, "Read PHY failed, status: %d", ret); - } else { - FURI_LOG_I(GAP_TAG, "PHY Params TX= %d, RX= %d ", tx_phy, rx_phy); + if(gap->enable_adv) { + // Restart advertising + gap_start_advertising(); + furi_hal_power_insomnia_exit(); } - break; - - case EVT_LE_CONN_COMPLETE: - furi_hal_power_insomnia_enter(); - hci_le_connection_complete_event_rp0* connection_complete_event = (hci_le_connection_complete_event_rp0 *) meta_evt->data; - FURI_LOG_I(GAP_TAG, "Connection complete for connection handle 0x%x", connection_complete_event->Connection_Handle); - - // Stop advertising as connection completed - osTimerStop(gap->advertise_timer); - - // Update connection status and handle - gap->state = GapStateConnected; - gap->gap_svc.connection_handle = connection_complete_event->Connection_Handle; - - // Start pairing by sending security request - aci_gap_slave_security_req(connection_complete_event->Connection_Handle); - break; - - default: - break; - } - break; - - case EVT_VENDOR: - blue_evt = (evt_blue_aci*) event_pckt->data; - switch (blue_evt->ecode) { - aci_gap_pairing_complete_event_rp0 *pairing_complete; - - case EVT_BLUE_GAP_LIMITED_DISCOVERABLE: - FURI_LOG_I(GAP_TAG, "Limited discoverable event"); - break; - - case EVT_BLUE_GAP_PASS_KEY_REQUEST: - { - // Generate random PIN code - uint32_t pin = rand() % 999999; - aci_gap_pass_key_resp(gap->gap_svc.connection_handle, pin); - FURI_LOG_I(GAP_TAG, "Pass key request event. Pin: %d", pin); - bt_pin_code_show(gap->bt, pin); } - break; - - case EVT_BLUE_GAP_AUTHORIZATION_REQUEST: - FURI_LOG_I(GAP_TAG, "Authorization request event"); - break; - - case EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED: - FURI_LOG_I(GAP_TAG, "Slave security initiated"); - break; - - case EVT_BLUE_GAP_BOND_LOST: - FURI_LOG_I(GAP_TAG, "Bond lost event. Start rebonding"); - aci_gap_allow_rebond(gap->gap_svc.connection_handle); - break; - - case EVT_BLUE_GAP_DEVICE_FOUND: - FURI_LOG_I(GAP_TAG, "Device found event"); - break; - - case EVT_BLUE_GAP_ADDR_NOT_RESOLVED: - FURI_LOG_I(GAP_TAG, "Address not resolved event"); - break; - - case EVT_BLUE_GAP_KEYPRESS_NOTIFICATION: - FURI_LOG_I(GAP_TAG, "Key press notification event"); - break; - - case EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE: - FURI_LOG_I(GAP_TAG, "Hex_value = %lx", - ((aci_gap_numeric_comparison_value_event_rp0 *)(blue_evt->data))->Numeric_Value); - aci_gap_numeric_comparison_value_confirm_yesno(gap->gap_svc.connection_handle, 1); - break; - - case (EVT_BLUE_GAP_PAIRING_CMPLT): - { - pairing_complete = (aci_gap_pairing_complete_event_rp0*)blue_evt->data; - if (pairing_complete->Status) { - FURI_LOG_E(GAP_TAG, "Pairing failed with status: %d. Terminating connection", pairing_complete->Status); - aci_gap_terminate(gap->gap_svc.connection_handle, 5); - } else { - FURI_LOG_I(GAP_TAG, "Pairing complete"); + break; + + case EVT_LE_META_EVENT: + meta_evt = (evt_le_meta_event*) event_pckt->data; + switch (meta_evt->subevent) { + case EVT_LE_CONN_UPDATE_COMPLETE: + FURI_LOG_D(GAP_TAG, "Connection update event"); + break; + + case EVT_LE_PHY_UPDATE_COMPLETE: + evt_le_phy_update_complete = (hci_le_phy_update_complete_event_rp0*)meta_evt->data; + if(evt_le_phy_update_complete->Status) { + FURI_LOG_E(GAP_TAG, "Update PHY failed, status %d", evt_le_phy_update_complete->Status); + } else { + FURI_LOG_I(GAP_TAG, "Update PHY succeed"); + } + ret = hci_le_read_phy(gap->gap_svc.connection_handle,&tx_phy,&rx_phy); + if(ret) { + FURI_LOG_E(GAP_TAG, "Read PHY failed, status: %d", ret); + } else { + FURI_LOG_I(GAP_TAG, "PHY Params TX = %d, RX = %d ", tx_phy, rx_phy); + } + break; + + case EVT_LE_CONN_COMPLETE: + furi_hal_power_insomnia_enter(); + hci_le_connection_complete_event_rp0* connection_complete_event = (hci_le_connection_complete_event_rp0 *) meta_evt->data; + FURI_LOG_I(GAP_TAG, "Connection complete for connection handle 0x%x", connection_complete_event->Connection_Handle); + + // Stop advertising as connection completed + osTimerStop(gap->advertise_timer); + + // Update connection status and handle + gap->state = GapStateConnected; + gap->gap_svc.connection_handle = connection_complete_event->Connection_Handle; + + // Start pairing by sending security request + aci_gap_slave_security_req(connection_complete_event->Connection_Handle); + break; + + default: + break; } - } - break; - - case EVT_BLUE_GAP_PROCEDURE_COMPLETE: - FURI_LOG_I(GAP_TAG, "Procedure complete event"); - break; - } - default: - break; - } - - return SVCCTL_UserEvtFlowEnable; + break; + + case EVT_VENDOR: + blue_evt = (evt_blue_aci*) event_pckt->data; + switch (blue_evt->ecode) { + aci_gap_pairing_complete_event_rp0 *pairing_complete; + + case EVT_BLUE_GAP_LIMITED_DISCOVERABLE: + FURI_LOG_I(GAP_TAG, "Limited discoverable event"); + break; + + case EVT_BLUE_GAP_PASS_KEY_REQUEST: + { + // Generate random PIN code + uint32_t pin = rand() % 999999; + aci_gap_pass_key_resp(gap->gap_svc.connection_handle, pin); + FURI_LOG_I(GAP_TAG, "Pass key request event. Pin: %d", pin); + bt_pin_code_show(gap->bt, pin); + } + break; + + case EVT_BLUE_GAP_AUTHORIZATION_REQUEST: + FURI_LOG_I(GAP_TAG, "Authorization request event"); + break; + + case EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED: + FURI_LOG_I(GAP_TAG, "Slave security initiated"); + break; + + case EVT_BLUE_GAP_BOND_LOST: + FURI_LOG_I(GAP_TAG, "Bond lost event. Start rebonding"); + aci_gap_allow_rebond(gap->gap_svc.connection_handle); + break; + + case EVT_BLUE_GAP_DEVICE_FOUND: + FURI_LOG_I(GAP_TAG, "Device found event"); + break; + + case EVT_BLUE_GAP_ADDR_NOT_RESOLVED: + FURI_LOG_I(GAP_TAG, "Address not resolved event"); + break; + + case EVT_BLUE_GAP_KEYPRESS_NOTIFICATION: + FURI_LOG_I(GAP_TAG, "Key press notification event"); + break; + + case EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE: + FURI_LOG_I(GAP_TAG, "Hex_value = %lx", + ((aci_gap_numeric_comparison_value_event_rp0 *)(blue_evt->data))->Numeric_Value); + aci_gap_numeric_comparison_value_confirm_yesno(gap->gap_svc.connection_handle, 1); + break; + + case EVT_BLUE_GAP_PAIRING_CMPLT: + pairing_complete = (aci_gap_pairing_complete_event_rp0*)blue_evt->data; + if (pairing_complete->Status) { + FURI_LOG_E(GAP_TAG, "Pairing failed with status: %d. Terminating connection", pairing_complete->Status); + aci_gap_terminate(gap->gap_svc.connection_handle, 5); + } else { + FURI_LOG_I(GAP_TAG, "Pairing complete"); + } + break; + + case EVT_BLUE_GAP_PROCEDURE_COMPLETE: + FURI_LOG_I(GAP_TAG, "Procedure complete event"); + break; + } + default: + break; + } + osMutexRelease(gap->state_mutex); + return SVCCTL_UserEvtFlowEnable; } void SVCCTL_SvcInit() { @@ -213,7 +223,7 @@ static void set_advertisment_service_uid(uint8_t* uid, uint8_t uid_len) { gap->gap_svc.adv_svc_uuid_len += uid_len; } -GapState gap_get_status() { +GapState gap_get_state() { return gap->state; } @@ -293,7 +303,7 @@ static void gap_init_svc(Gap* gap) { aci_gap_configure_whitelist(); } -static void gap_advertise(GapState new_state) +static void gap_advertise_start(GapState new_state) { tBleStatus status; uint16_t min_interval; @@ -317,7 +327,6 @@ static void gap_advertise(GapState new_state) } } // Configure advertising - gap->state = new_state; const char* name = furi_hal_version_get_ble_local_device_name_ptr(); status = aci_gap_set_discoverable(ADV_IND, min_interval, max_interval, PUBLIC_ADDR, 0, strlen(name), (uint8_t*)name, @@ -325,17 +334,40 @@ static void gap_advertise(GapState new_state) if(status) { FURI_LOG_E(GAP_TAG, "Set discoverable err: %d", status); } + gap->state = new_state; + bt_update_statusbar(gap->bt); osTimerStart(gap->advertise_timer, INITIAL_ADV_TIMEOUT); } -static void gap_advertise_request(Gap* gap) { - osThreadFlagsSet(gap->thread_id, 1); +static void gap_advertise_stop() { + if(gap->state == GapStateConnected) { + // Terminate connection + aci_gap_terminate(gap->gap_svc.connection_handle, 0x13); + } + if(gap->state > GapStateIdle) { + // Stop advertising + osTimerStop(gap->advertise_timer); + aci_gap_set_non_discoverable(); + gap->state = GapStateIdle; + bt_update_statusbar(gap->bt); + } +} + +void gap_start_advertising() { + gap->enable_adv = true; + GapCommand command = GapCommandAdvFast; + furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); +} + +void gap_stop_advertising() { + gap->enable_adv = false; + GapCommand command = GapCommandAdvStop; + furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); } static void gap_advetise_timer_callback(void* context) { - furi_assert(context); - Gap* gap = context; - gap_advertise_request(gap); + GapCommand command = GapCommandAdvLowPower; + furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); } bool gap_init() { @@ -348,20 +380,25 @@ bool gap_init() { // Open Bt record gap->bt = furi_record_open("bt"); // Create advertising timer - gap->advertise_timer = osTimerNew(gap_advetise_timer_callback, osTimerOnce, &gap, NULL); - // Initialization of HCI & GATT & GAP layer + gap->advertise_timer = osTimerNew(gap_advetise_timer_callback, osTimerOnce, NULL, NULL); + // Initialization of GATT & GAP layer gap_init_svc(gap); // Initialization of the BLE Services SVCCTL_Init(); - // Initialization of the BLE App Context + // Initialization of the GAP state + gap->state_mutex = osMutexNew(NULL); gap->state = GapStateIdle; gap->gap_svc.connection_handle = 0xFFFF; + gap->enable_adv = true; // Thread configuration gap->thread_attr.name = "BLE advertising"; - gap->thread_attr.stack_size = 512; + gap->thread_attr.stack_size = 1024; gap->thread_id = osThreadNew(gap_app, NULL, &gap->thread_attr); + // Command queue allocation + gap->command_queue = osMessageQueueNew(8, sizeof(GapCommand), NULL); + // Start Device Information service dev_info_svc_start(); // Start Battery service @@ -374,14 +411,21 @@ bool gap_init() { adv_service_uid[1] = 0x30; set_advertisment_service_uid(adv_service_uid, sizeof(adv_service_uid)); - gap_advertise(GapStateAdvFast); return true; } static void gap_app(void *arg) { - // TODO Exit from app, stop service, clean memory + GapCommand command; while(1) { - osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); - gap_advertise(GapStateAdvLowPower); + furi_check(osMessageQueueGet(gap->command_queue, &command, NULL, osWaitForever) == osOK); + osMutexAcquire(gap->state_mutex, osWaitForever); + if(command == GapCommandAdvFast) { + gap_advertise_start(GapStateAdvFast); + } else if(command == GapCommandAdvLowPower) { + gap_advertise_start(GapStateAdvLowPower); + } else if(command == GapCommandAdvStop) { + gap_advertise_stop(); + } + osMutexRelease(gap->state_mutex); } } diff --git a/firmware/targets/f6/ble-glue/gap.h b/firmware/targets/f6/ble-glue/gap.h index 3fc2cf4cbb5..93e75122b46 100644 --- a/firmware/targets/f6/ble-glue/gap.h +++ b/firmware/targets/f6/ble-glue/gap.h @@ -15,7 +15,11 @@ typedef enum { bool gap_init(); -GapState gap_get_status(); +void gap_start_advertising(); + +void gap_stop_advertising(); + +GapState gap_get_state(); #ifdef __cplusplus } diff --git a/firmware/targets/f6/ble-glue/serial_service.c b/firmware/targets/f6/ble-glue/serial_service.c index eae2c275f1d..e5ab9d2d7a9 100644 --- a/firmware/targets/f6/ble-glue/serial_service.c +++ b/firmware/targets/f6/ble-glue/serial_service.c @@ -61,7 +61,7 @@ void serial_svc_start() { status = aci_gatt_add_char(serial_svc->svc_handle, UUID_TYPE_128, (const Char_UUID_t*)char_tx_uuid, SERIAL_SVC_DATA_LEN_MAX, CHAR_PROP_WRITE_WITHOUT_RESP | CHAR_PROP_WRITE | CHAR_PROP_READ, - ATTR_PERMISSION_NONE, + ATTR_PERMISSION_AUTHEN_READ | ATTR_PERMISSION_AUTHEN_WRITE, GATT_NOTIFY_ATTRIBUTE_WRITE, 10, CHAR_VALUE_LEN_VARIABLE, @@ -74,7 +74,7 @@ void serial_svc_start() { status = aci_gatt_add_char(serial_svc->svc_handle, UUID_TYPE_128, (const Char_UUID_t*)char_rx_uuid, SERIAL_SVC_DATA_LEN_MAX, CHAR_PROP_READ | CHAR_PROP_INDICATE, - ATTR_PERMISSION_NONE, + ATTR_PERMISSION_AUTHEN_READ, GATT_DONT_NOTIFY_EVENTS, 10, CHAR_VALUE_LEN_VARIABLE, @@ -108,13 +108,15 @@ void serial_svc_stop() { bool serial_svc_update_rx(uint8_t* data, uint8_t data_len) { - furi_assert(data_len < SERIAL_SVC_DATA_LEN_MAX); + if(data_len > SERIAL_SVC_DATA_LEN_MAX) { + return false; + } tBleStatus result = aci_gatt_update_char_value(serial_svc->svc_handle, - serial_svc->rx_char_handle, - 0, - data_len, - data); + serial_svc->rx_char_handle, + 0, + data_len, + data); if(result) { FURI_LOG_E(SERIAL_SERVICE_TAG, "Failed updating RX characteristic: %d", result); } diff --git a/firmware/targets/f6/furi-hal/furi-hal-bt.c b/firmware/targets/f6/furi-hal/furi-hal-bt.c index 4d5e0674d5b..7fab63edd3f 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-bt.c +++ b/firmware/targets/f6/furi-hal/furi-hal-bt.c @@ -4,7 +4,6 @@ #include #include #include -#include #include void furi_hal_bt_init() { @@ -14,10 +13,22 @@ void furi_hal_bt_init() { APPE_Init(); } -bool furi_hal_bt_start_app() { +bool furi_hal_bt_init_app() { return gap_init(); } +void furi_hal_bt_start_advertising() { + if(gap_get_state() == GapStateIdle) { + gap_start_advertising(); + } +} + +void furi_hal_bt_stop_advertising() { + if(furi_hal_bt_is_active()) { + gap_stop_advertising(); + } +} + void furi_hal_bt_dump_state(string_t buffer) { BleGlueStatus status = APPE_Status(); if (status == BleGlueStatusStarted) { @@ -41,7 +52,12 @@ void furi_hal_bt_dump_state(string_t buffer) { } bool furi_hal_bt_is_alive() { - return APPE_Status() == BleGlueStatusStarted; + BleGlueStatus status = APPE_Status(); + return (status == BleGlueStatusBroken) || (status == BleGlueStatusStarted); +} + +bool furi_hal_bt_is_active() { + return gap_get_state() > GapStateIdle; } bool furi_hal_bt_wait_startup() { @@ -56,7 +72,7 @@ bool furi_hal_bt_wait_startup() { return true; } -bool furi_hal_bt_lock_flash() { +bool furi_hal_bt_lock_flash(bool erase_flag) { if (!furi_hal_bt_wait_startup()) { return false; } @@ -64,18 +80,25 @@ bool furi_hal_bt_lock_flash() { while (HAL_HSEM_FastTake(CFG_HW_FLASH_SEMID) != HAL_OK) { osDelay(1); } - - SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON); + HAL_FLASH_Unlock(); - while(LL_FLASH_IsOperationSuspended()) {}; + if(erase_flag) SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON); + + while(LL_FLASH_IsActiveFlag_OperationSuspended()) {}; + + __disable_irq(); return true; } -void furi_hal_bt_unlock_flash() { - SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF); +void furi_hal_bt_unlock_flash(bool erase_flag) { + __enable_irq(); + + if(erase_flag) SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF); + HAL_FLASH_Lock(); + HAL_HSEM_Release(CFG_HW_FLASH_SEMID, HSEM_CPU1_COREID); } diff --git a/firmware/targets/f6/furi-hal/furi-hal-clock.c b/firmware/targets/f6/furi-hal/furi-hal-clock.c index 0ed918e3dc3..2544c769a59 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-clock.c +++ b/firmware/targets/f6/furi-hal/furi-hal-clock.c @@ -1,6 +1,6 @@ #include +#include -#include #include #include #include @@ -107,6 +107,12 @@ void furi_hal_clock_init() { LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOE); LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH); LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_AES1); + + // AHB3 + LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_PKA); + LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_RNG); + LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_AES2); // APB1 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB); @@ -114,6 +120,8 @@ void furi_hal_clock_init() { // APB2 LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); + + FURI_LOG_I("FuriHalClock", "Init OK"); } void furi_hal_clock_switch_to_hsi() { diff --git a/firmware/targets/f6/furi-hal/furi-hal-crypto.c b/firmware/targets/f6/furi-hal/furi-hal-crypto.c new file mode 100644 index 00000000000..3e4ec98fd06 --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-crypto.c @@ -0,0 +1,75 @@ +#include +#include +#include + +CRYP_HandleTypeDef crypt; + +void furi_hal_crypto_init() { + FURI_LOG_I("FuriHalCrypto", "Init OK"); +} + +bool furi_hal_crypto_store_add_key(FuriHalCryptoKey* key, uint8_t* slot) { + furi_assert(key); + furi_assert(slot); + + SHCI_C2_FUS_StoreUsrKey_Cmd_Param_t pParam; + size_t key_data_size = 0; + + if (key->type == FuriHalCryptoKeyTypeMaster) { + pParam.KeyType = KEYTYPE_MASTER; + } else if (key->type == FuriHalCryptoKeyTypeSimple) { + pParam.KeyType = KEYTYPE_SIMPLE; + } else if (key->type == FuriHalCryptoKeyTypeEncrypted) { + pParam.KeyType = KEYTYPE_ENCRYPTED; + key_data_size += 12; + } else { + furi_crash("Incorrect key type"); + } + + if (key->size == FuriHalCryptoKeySize128) { + pParam.KeySize = KEYSIZE_16; + key_data_size += 16; + } else if (key->size == FuriHalCryptoKeySize256) { + pParam.KeySize = KEYSIZE_32; + key_data_size += 32; + } else { + furi_crash("Incorrect key size"); + } + + memcpy(pParam.KeyData, key->data, key_data_size); + + return SHCI_C2_FUS_StoreUsrKey(&pParam, slot) == SHCI_Success; +} + +bool furi_hal_crypto_store_load_key(uint8_t slot, const uint8_t* iv) { + furi_assert(slot > 0 && slot <= 100); + + crypt.Instance = AES1; + crypt.Init.DataType = CRYP_DATATYPE_32B; + crypt.Init.KeySize = CRYP_KEYSIZE_256B; + crypt.Init.Algorithm = CRYP_AES_CBC; + crypt.Init.pInitVect = (uint32_t*)iv; + crypt.Init.pKey = NULL; + + furi_check(HAL_CRYP_Init(&crypt) == HAL_OK); + + if (SHCI_C2_FUS_LoadUsrKey(slot) == SHCI_Success) { + return true; + } else { + furi_check(HAL_CRYP_DeInit(&crypt) == HAL_OK); + return false; + } +} + +bool furi_hal_crypto_store_unload_key(uint8_t slot) { + furi_check(HAL_CRYP_DeInit(&crypt) == HAL_OK); + return SHCI_C2_FUS_UnloadUsrKey(slot) == SHCI_Success; +} + +bool furi_hal_crypto_encrypt(const uint8_t *input, uint8_t *output, size_t size) { + return HAL_CRYP_Encrypt(&crypt, (uint32_t*)input, size/4, (uint32_t*)output, 1000) == HAL_OK; +} + +bool furi_hal_crypto_decrypt(const uint8_t *input, uint8_t *output, size_t size) { + return HAL_CRYP_Decrypt(&crypt, (uint32_t*)input, size/4, (uint32_t*)output, 1000) == HAL_OK; +} diff --git a/firmware/targets/f6/furi-hal/furi-hal-flash.c b/firmware/targets/f6/furi-hal/furi-hal-flash.c index 5346965fd30..c9922122ef3 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-flash.c +++ b/firmware/targets/f6/furi-hal/furi-hal-flash.c @@ -57,7 +57,7 @@ size_t furi_hal_flash_get_free_page_count() { } bool furi_hal_flash_erase(uint8_t page, uint8_t count) { - if (!furi_hal_bt_lock_flash()) { + if (!furi_hal_bt_lock_flash(true)) { return false; } FLASH_EraseInitTypeDef erase; @@ -66,24 +66,24 @@ bool furi_hal_flash_erase(uint8_t page, uint8_t count) { erase.NbPages = count; uint32_t error; HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase, &error); - furi_hal_bt_unlock_flash(); + furi_hal_bt_unlock_flash(true); return status == HAL_OK; } bool furi_hal_flash_write_dword(size_t address, uint64_t data) { - if (!furi_hal_bt_lock_flash()) { + if (!furi_hal_bt_lock_flash(false)) { return false; } HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data); - furi_hal_bt_unlock_flash(); + furi_hal_bt_unlock_flash(false); return status == HAL_OK; } bool furi_hal_flash_write_dword_from(size_t address, size_t source_address) { - if (!furi_hal_bt_lock_flash()) { + if (!furi_hal_bt_lock_flash(false)) { return false; } HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FAST, address, source_address); - furi_hal_bt_unlock_flash(); + furi_hal_bt_unlock_flash(false); return status == HAL_OK; } diff --git a/firmware/targets/f6/furi-hal/furi-hal-interrupt.c b/firmware/targets/f6/furi-hal/furi-hal-interrupt.c index 69cdc4b6994..47e99c9f33e 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-interrupt.c +++ b/firmware/targets/f6/furi-hal/furi-hal-interrupt.c @@ -41,7 +41,7 @@ void furi_hal_interrupt_set_timer_isr(TIM_TypeDef* timer, FuriHalInterruptISR is } furi_hal_tim_tim1_isr = isr; } else { - furi_check(0); + furi_crash(NULL); } } @@ -54,7 +54,7 @@ void furi_hal_interrupt_set_dma_channel_isr(DMA_TypeDef* dma, uint32_t channel, } else if (dma == DMA2) { furi_hal_dma_channel_isr[1][channel] = isr; } else { - furi_check(0); + furi_crash(NULL); } } diff --git a/firmware/targets/f6/furi-hal/furi-hal-irda.c b/firmware/targets/f6/furi-hal/furi-hal-irda.c index a148b44a016..503a36537a8 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-irda.c +++ b/firmware/targets/f6/furi-hal/furi-hal-irda.c @@ -244,7 +244,7 @@ static uint8_t furi_hal_irda_get_current_dma_tx_buffer(void) { static void furi_hal_irda_tx_dma_polarity_isr() { if (LL_DMA_IsActiveFlag_TE1(DMA1)) { LL_DMA_ClearFlag_TE1(DMA1); - furi_check(0); + furi_crash(NULL); } if (LL_DMA_IsActiveFlag_TC1(DMA1) && LL_DMA_IsEnabledIT_TC(DMA1, LL_DMA_CHANNEL_1)) { LL_DMA_ClearFlag_TC1(DMA1); @@ -261,7 +261,7 @@ static void furi_hal_irda_tx_dma_polarity_isr() { static void furi_hal_irda_tx_dma_isr() { if (LL_DMA_IsActiveFlag_TE2(DMA1)) { LL_DMA_ClearFlag_TE2(DMA1); - furi_check(0); + furi_crash(NULL); } if (LL_DMA_IsActiveFlag_HT2(DMA1) && LL_DMA_IsEnabledIT_HT(DMA1, LL_DMA_CHANNEL_2)) { LL_DMA_ClearFlag_HT2(DMA1); @@ -277,7 +277,7 @@ static void furi_hal_irda_tx_dma_isr() { } else if (furi_hal_irda_state == IrdaStateAsyncTxStopReq) { /* fallthrough */ } else { - furi_check(0); + furi_crash(NULL); } } if (LL_DMA_IsActiveFlag_TC2(DMA1) && LL_DMA_IsEnabledIT_TC(DMA1, LL_DMA_CHANNEL_2)) { @@ -557,7 +557,7 @@ static void furi_hal_irda_async_tx_free_resources(void) { void furi_hal_irda_async_tx_start(uint32_t freq, float duty_cycle) { if ((duty_cycle > 1) || (duty_cycle <= 0) || (freq > IRDA_MAX_FREQUENCY) || (freq < IRDA_MIN_FREQUENCY) || (irda_tim_tx.data_callback == NULL)) { - furi_check(0); + furi_crash(NULL); } furi_assert(furi_hal_irda_state == IrdaStateIdle); diff --git a/firmware/targets/f6/furi-hal/furi-hal-rfid.c b/firmware/targets/f6/furi-hal/furi-hal-rfid.c index f4d8ff6b240..8b5266c34bc 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-rfid.c +++ b/firmware/targets/f6/furi-hal/furi-hal-rfid.c @@ -252,7 +252,7 @@ void furi_hal_rfid_set_emulate_pulse(uint32_t pulse) { LFRFID_EMULATE_TIM.Instance->CCR4 = pulse; break; default: - furi_check(0); + furi_crash(NULL); break; } } @@ -276,7 +276,7 @@ void furi_hal_rfid_set_read_pulse(uint32_t pulse) { LFRFID_TIM.Instance->CCR4 = pulse; break; default: - furi_check(0); + furi_crash(NULL); break; } } diff --git a/firmware/targets/f6/furi-hal/furi-hal-subghz.c b/firmware/targets/f6/furi-hal/furi-hal-subghz.c index 679eea74055..4d1f0cbf799 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f6/furi-hal/furi-hal-subghz.c @@ -15,166 +15,174 @@ static const uint8_t furi_hal_subghz_preset_ook_270khz_async_regs[][2] = { // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration /* GPIO GD0 */ - { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input /* FIFO and internals */ - { CC1101_FIFOTHR, 0x47 }, // The only important bit is ADC_RETENTION, FIFO Tx=33 Rx=32 + {CC1101_FIFOTHR, 0x47}, // The only important bit is ADC_RETENTION, FIFO Tx=33 Rx=32 /* Packet engine */ - { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + {CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening /* Frequency Synthesizer Control */ - { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz // Modem Configuration - { CC1101_MDMCFG0, 0x00 }, // Channel spacing is 25kHz - { CC1101_MDMCFG1, 0x00 }, // Channel spacing is 25kHz - { CC1101_MDMCFG2, 0x30 }, // Format ASK/OOK, No preamble/sync - { CC1101_MDMCFG3, 0x32 }, // Data rate is 3.79372 kBaud - { CC1101_MDMCFG4, 0x67 }, // Rx BW filter is 270.833333kHz + {CC1101_MDMCFG0, 0x00}, // Channel spacing is 25kHz + {CC1101_MDMCFG1, 0x00}, // Channel spacing is 25kHz + {CC1101_MDMCFG2, 0x30}, // Format ASK/OOK, No preamble/sync + {CC1101_MDMCFG3, 0x32}, // Data rate is 3.79372 kBaud + {CC1101_MDMCFG4, 0x67}, // Rx BW filter is 270.833333kHz /* Main Radio Control State Machine */ - { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) /* Frequency Offset Compensation Configuration */ - { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + {CC1101_FOCCFG, + 0x18}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off /* Automatic Gain Control */ - { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary - { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET - { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + {CC1101_AGCTRL0, + 0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + {CC1101_AGCTRL1, + 0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + {CC1101_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB /* Wake on radio and timeouts control */ - { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + {CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours /* Frontend configuration */ - { CC1101_FREND0, 0x11 }, // Adjusts current TX LO buffer + high is PATABLE[1] - { CC1101_FREND1, 0xB6 }, // + {CC1101_FREND0, 0x11}, // Adjusts current TX LO buffer + high is PATABLE[1] + {CC1101_FREND1, 0xB6}, // /* Frequency Synthesizer Calibration, valid for 433.92 */ - { CC1101_FSCAL3, 0xE9 }, - { CC1101_FSCAL2, 0x2A }, - { CC1101_FSCAL1, 0x00 }, - { CC1101_FSCAL0, 0x1F }, + {CC1101_FSCAL3, 0xE9}, + {CC1101_FSCAL2, 0x2A}, + {CC1101_FSCAL1, 0x00}, + {CC1101_FSCAL0, 0x1F}, /* Magic f4ckery */ - { CC1101_TEST2, 0x81 }, // FIFOTHR ADC_RETENTION=1 matched value - { CC1101_TEST1, 0x35 }, // FIFOTHR ADC_RETENTION=1 matched value - { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + {CC1101_TEST2, 0x81}, // FIFOTHR ADC_RETENTION=1 matched value + {CC1101_TEST1, 0x35}, // FIFOTHR ADC_RETENTION=1 matched value + {CC1101_TEST0, 0x09}, // VCO selection calibration stage is disabled /* End */ - { 0, 0 }, + {0, 0}, }; static const uint8_t furi_hal_subghz_preset_ook_650khz_async_regs[][2] = { // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration /* GPIO GD0 */ - { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input /* FIFO and internals */ - { CC1101_FIFOTHR, 0x07 }, // The only important bit is ADC_RETENTION + {CC1101_FIFOTHR, 0x07}, // The only important bit is ADC_RETENTION /* Packet engine */ - { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + {CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening /* Frequency Synthesizer Control */ - { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz // Modem Configuration - { CC1101_MDMCFG0, 0x00 }, // Channel spacing is 25kHz - { CC1101_MDMCFG1, 0x00 }, // Channel spacing is 25kHz - { CC1101_MDMCFG2, 0x30 }, // Format ASK/OOK, No preamble/sync - { CC1101_MDMCFG3, 0x32 }, // Data rate is 3.79372 kBaud - { CC1101_MDMCFG4, 0x17 }, // Rx BW filter is 650.000kHz - + {CC1101_MDMCFG0, 0x00}, // Channel spacing is 25kHz + {CC1101_MDMCFG1, 0x00}, // Channel spacing is 25kHz + {CC1101_MDMCFG2, 0x30}, // Format ASK/OOK, No preamble/sync + {CC1101_MDMCFG3, 0x32}, // Data rate is 3.79372 kBaud + {CC1101_MDMCFG4, 0x17}, // Rx BW filter is 650.000kHz + /* Main Radio Control State Machine */ - { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) /* Frequency Offset Compensation Configuration */ - { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + {CC1101_FOCCFG, + 0x18}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off /* Automatic Gain Control */ - { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary - { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET - { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + {CC1101_AGCTRL0, + 0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + {CC1101_AGCTRL1, + 0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + {CC1101_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB /* Wake on radio and timeouts control */ - { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + {CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours /* Frontend configuration */ - { CC1101_FREND0, 0x11 }, // Adjusts current TX LO buffer + high is PATABLE[1] - { CC1101_FREND1, 0xB6 }, // + {CC1101_FREND0, 0x11}, // Adjusts current TX LO buffer + high is PATABLE[1] + {CC1101_FREND1, 0xB6}, // /* Frequency Synthesizer Calibration, valid for 433.92 */ - { CC1101_FSCAL3, 0xE9 }, - { CC1101_FSCAL2, 0x2A }, - { CC1101_FSCAL1, 0x00 }, - { CC1101_FSCAL0, 0x1F }, + {CC1101_FSCAL3, 0xE9}, + {CC1101_FSCAL2, 0x2A}, + {CC1101_FSCAL1, 0x00}, + {CC1101_FSCAL0, 0x1F}, /* Magic f4ckery */ - { CC1101_TEST2, 0x88 }, - { CC1101_TEST1, 0x31 }, - { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + {CC1101_TEST2, 0x88}, + {CC1101_TEST1, 0x31}, + {CC1101_TEST0, 0x09}, // VCO selection calibration stage is disabled /* End */ - { 0, 0 }, + {0, 0}, }; static const uint8_t furi_hal_subghz_preset_2fsk_async_regs[][2] = { - // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration /* GPIO GD0 */ - { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input /* FIFO and internals */ - { CC1101_FIFOTHR, 0x47 }, // The only important bit is ADC_RETENTION + {CC1101_FIFOTHR, 0x47}, // The only important bit is ADC_RETENTION /* Packet engine */ - { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + {CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening /* Frequency Synthesizer Control */ - { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz // Modem Configuration - { CC1101_MDMCFG0, 0xF8 }, - { CC1101_MDMCFG1, 0x00 }, // No preamble/sync - { CC1101_MDMCFG2, 0x80 }, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized) - { CC1101_MDMCFG3, 0x83 }, // Data rate is 9.59587 kBaud - { CC1101_MDMCFG4, 0x88 }, // Rx BW filter is 203.125000kHz + {CC1101_MDMCFG0, 0x00}, + {CC1101_MDMCFG1, 0x02}, + {CC1101_MDMCFG2, 0x04}, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized) + {CC1101_MDMCFG3, 0x8B}, // Data rate is 19.5885 kBaud + {CC1101_MDMCFG4, 0x69}, // Rx BW filter is 270.833333 kHz - { CC1101_DEVIATN, 0x14}, //Deviation 4.760742 khz + {CC1101_DEVIATN, 0x47}, //Deviation 47.607422 khz /* Main Radio Control State Machine */ - { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) /* Frequency Offset Compensation Configuration */ - { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + {CC1101_FOCCFG, + 0x16}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off /* Automatic Gain Control */ - { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary - { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET - { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + {CC1101_AGCTRL0, + 0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + {CC1101_AGCTRL1, + 0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + {CC1101_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB /* Wake on radio and timeouts control */ - { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + {CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours /* Frontend configuration */ - { CC1101_FREND0, 0x10 }, // Adjusts current TX LO buffer - { CC1101_FREND1, 0xB6 }, // + {CC1101_FREND0, 0x10}, // Adjusts current TX LO buffer + {CC1101_FREND1, 0xB6}, // /* Frequency Synthesizer Calibration, valid for 433.92 */ - { CC1101_FSCAL3, 0xE9 }, - { CC1101_FSCAL2, 0x2A }, - { CC1101_FSCAL1, 0x00 }, - { CC1101_FSCAL0, 0x1F }, + {CC1101_FSCAL3, 0xE9}, + {CC1101_FSCAL2, 0x2A}, + {CC1101_FSCAL1, 0x00}, + {CC1101_FSCAL0, 0x1F}, /* Magic f4ckery */ - { CC1101_TEST2, 0x81 }, // FIFOTHR ADC_RETENTION=1 matched value - { CC1101_TEST1, 0x35 }, // FIFOTHR ADC_RETENTION=1 matched value - { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + {CC1101_TEST2, 0x81}, // FIFOTHR ADC_RETENTION=1 matched value + {CC1101_TEST1, 0x35}, // FIFOTHR ADC_RETENTION=1 matched value + {CC1101_TEST0, 0x09}, // VCO selection calibration stage is disabled /* End */ - { 0, 0 }, + {0, 0}, }; static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = { 0x00, @@ -184,8 +192,7 @@ static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = { 0x00, 0x00, 0x00, - 0x00 -}; + 0x00}; static const uint8_t furi_hal_subghz_preset_2fsk_async_patable[8] = { 0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12 0x00, @@ -195,6 +202,7 @@ static const uint8_t furi_hal_subghz_preset_2fsk_async_patable[8] = { 0x00, 0x00, 0x00 + }; void furi_hal_subghz_init() { @@ -217,11 +225,13 @@ void furi_hal_subghz_init() { // GD0 low cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW); - while(hal_gpio_read(&gpio_cc1101_g0) != false); + while(hal_gpio_read(&gpio_cc1101_g0) != false) + ; // GD0 high cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); - while(hal_gpio_read(&gpio_cc1101_g0) != true); + while(hal_gpio_read(&gpio_cc1101_g0) != true) + ; // Reset GD0 to floating state cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); @@ -257,8 +267,7 @@ void furi_hal_subghz_dump_state() { printf( "[furi_hal_subghz] cc1101 chip %d, version %d\r\n", cc1101_get_partnumber(device), - cc1101_get_version(device) - ); + cc1101_get_version(device)); furi_hal_spi_device_return(device); } @@ -266,14 +275,14 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { if(preset == FuriHalSubGhzPresetOok650Async) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_ook_650khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable); - } else if(preset == FuriHalSubGhzPresetOok270Async){ + } else if(preset == FuriHalSubGhzPresetOok270Async) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_ook_270khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable); - } else if(preset == FuriHalSubGhzPreset2FSKAsync){ + } else if(preset == FuriHalSubGhzPreset2FSKAsync) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_2fsk_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_2fsk_async_patable); }else { - furi_check(0); + furi_crash(NULL); } } @@ -289,7 +298,7 @@ void furi_hal_subghz_load_registers(const uint8_t data[][2]) { const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); cc1101_reset(device); uint32_t i = 0; - while (data[i][0]) { + while(data[i][0]) { cc1101_write_reg(device, data[i][0], data[i][1]); i++; } @@ -388,7 +397,7 @@ uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value) { } else if(value >= 778999847 && value <= 928000000) { furi_hal_subghz_set_path(FuriHalSubGhzPath868); } else { - furi_check(0); + furi_crash(NULL); } return value; } @@ -401,7 +410,7 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { while(true) { CC1101Status status = cc1101_get_status(device); - if (status.STATE == CC1101StateIDLE) break; + if(status.STATE == CC1101StateIDLE) break; } furi_hal_spi_device_return(device); @@ -411,20 +420,20 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { void furi_hal_subghz_set_path(FuriHalSubGhzPath path) { const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - if (path == FuriHalSubGhzPath433) { + if(path == FuriHalSubGhzPath433) { hal_gpio_write(&gpio_rf_sw_0, 0); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); - } else if (path == FuriHalSubGhzPath315) { + } else if(path == FuriHalSubGhzPath315) { hal_gpio_write(&gpio_rf_sw_0, 1); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); - } else if (path == FuriHalSubGhzPath868) { + } else if(path == FuriHalSubGhzPath868) { hal_gpio_write(&gpio_rf_sw_0, 1); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); - } else if (path == FuriHalSubGhzPathIsolate) { + } else if(path == FuriHalSubGhzPathIsolate) { hal_gpio_write(&gpio_rf_sw_0, 0); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); } else { - furi_check(0); + furi_crash(NULL); } furi_hal_spi_device_return(device); } @@ -438,24 +447,25 @@ static void furi_hal_subghz_capture_ISR() { if(LL_TIM_IsActiveFlag_CC1(TIM2)) { LL_TIM_ClearFlag_CC1(TIM2); furi_hal_subghz_capture_delta_duration = LL_TIM_IC_GetCaptureCH1(TIM2); - if (furi_hal_subghz_capture_callback) { - furi_hal_subghz_capture_callback(true, furi_hal_subghz_capture_delta_duration, - (void*)furi_hal_subghz_capture_callback_context - ); + if(furi_hal_subghz_capture_callback) { + furi_hal_subghz_capture_callback( + true, + furi_hal_subghz_capture_delta_duration, + (void*)furi_hal_subghz_capture_callback_context); } } // Channel 2 if(LL_TIM_IsActiveFlag_CC2(TIM2)) { LL_TIM_ClearFlag_CC2(TIM2); - if (furi_hal_subghz_capture_callback) { - furi_hal_subghz_capture_callback(false, LL_TIM_IC_GetCaptureCH2(TIM2) - furi_hal_subghz_capture_delta_duration, - (void*)furi_hal_subghz_capture_callback_context - ); + if(furi_hal_subghz_capture_callback) { + furi_hal_subghz_capture_callback( + false, + LL_TIM_IC_GetCaptureCH2(TIM2) - furi_hal_subghz_capture_delta_duration, + (void*)furi_hal_subghz_capture_callback_context); } } } - void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* context) { furi_assert(furi_hal_subghz_state == SubGhzStateIdle); furi_hal_subghz_state = SubGhzStateAsyncRx; @@ -463,12 +473,13 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* furi_hal_subghz_capture_callback = callback; furi_hal_subghz_capture_callback_context = context; - hal_gpio_init_ex(&gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); + hal_gpio_init_ex( + &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); // Timer: base LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); LL_TIM_InitTypeDef TIM_InitStruct = {0}; - TIM_InitStruct.Prescaler = 64-1; + TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 0x7FFFFFFE; TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; @@ -498,7 +509,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* // ISR setup furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_capture_ISR); - NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); + NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(TIM2_IRQn); // Interrupts and channels @@ -508,7 +519,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2); // Enable NVIC - NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); + NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(TIM2_IRQn); // Start timer @@ -534,8 +545,8 @@ void furi_hal_subghz_stop_async_rx() { } #define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL (256) -#define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF (API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL/2) -#define API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME 333 +#define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF (API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL / 2) +#define API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME 333 typedef struct { uint32_t* buffer; @@ -547,12 +558,13 @@ typedef struct { static FuriHalSubGhzAsyncTx furi_hal_subghz_async_tx = {0}; static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { - while (samples > 0) { + while(samples > 0) { bool is_odd = samples % 2; - LevelDuration ld = furi_hal_subghz_async_tx.callback(furi_hal_subghz_async_tx.callback_context); - if (level_duration_is_reset(ld)) { + LevelDuration ld = + furi_hal_subghz_async_tx.callback(furi_hal_subghz_async_tx.callback_context); + if(level_duration_is_reset(ld)) { // One more even sample required to end at low level - if (is_odd) { + if(is_odd) { *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; buffer++; samples--; @@ -560,7 +572,7 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { break; } else { // Inject guard time if level is incorrect - if (is_odd == level_duration_get_level(ld)) { + if(is_odd == level_duration_get_level(ld)) { *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; buffer++; samples--; @@ -579,21 +591,24 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { static void furi_hal_subghz_async_tx_dma_isr() { furi_assert(furi_hal_subghz_state == SubGhzStateAsyncTx); - if (LL_DMA_IsActiveFlag_HT1(DMA1)) { + if(LL_DMA_IsActiveFlag_HT1(DMA1)) { LL_DMA_ClearFlag_HT1(DMA1); - furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); + furi_hal_subghz_async_tx_refill( + furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); } - if (LL_DMA_IsActiveFlag_TC1(DMA1)) { + if(LL_DMA_IsActiveFlag_TC1(DMA1)) { LL_DMA_ClearFlag_TC1(DMA1); - furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer+API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); + furi_hal_subghz_async_tx_refill( + furi_hal_subghz_async_tx.buffer + API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF, + API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); } } static void furi_hal_subghz_async_tx_timer_isr() { if(LL_TIM_IsActiveFlag_UPDATE(TIM2)) { LL_TIM_ClearFlag_UPDATE(TIM2); - if (LL_TIM_GetAutoReload(TIM2) == 0) { - if (furi_hal_subghz_state == SubGhzStateAsyncTx) { + if(LL_TIM_GetAutoReload(TIM2) == 0) { + if(furi_hal_subghz_state == SubGhzStateAsyncTx) { furi_hal_subghz_state = SubGhzStateAsyncTxLast; } else { furi_hal_subghz_state = SubGhzStateAsyncTxEnd; @@ -612,15 +627,18 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* furi_hal_subghz_state = SubGhzStateAsyncTx; - furi_hal_subghz_async_tx.buffer = furi_alloc(API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t)); - furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL); + furi_hal_subghz_async_tx.buffer = + furi_alloc(API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t)); + furi_hal_subghz_async_tx_refill( + furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL); // Connect CC1101_GD0 to TIM2 as output - hal_gpio_init_ex(&gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn1TIM2); + hal_gpio_init_ex( + &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn1TIM2); // Configure DMA LL_DMA_InitTypeDef dma_config = {0}; - dma_config.PeriphOrM2MSrcAddress = (uint32_t)&(TIM2->ARR); + dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM2->ARR); dma_config.MemoryOrM2MDstAddress = (uint32_t)furi_hal_subghz_async_tx.buffer; dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; dma_config.Mode = LL_DMA_MODE_CIRCULAR; @@ -632,7 +650,8 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP; dma_config.Priority = LL_DMA_MODE_NORMAL; LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config); - furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, furi_hal_subghz_async_tx_dma_isr); + furi_hal_interrupt_set_dma_channel_isr( + DMA1, LL_DMA_CHANNEL_1, furi_hal_subghz_async_tx_dma_isr); LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1); LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_1); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); @@ -640,7 +659,7 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* // Configure TIM2 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); LL_TIM_InitTypeDef TIM_InitStruct = {0}; - TIM_InitStruct.Prescaler = 64-1; + TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 1000; TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; @@ -672,7 +691,7 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* furi_hal_subghz_tx(); // Enable NVIC - NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); + NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(TIM2_IRQn); LL_TIM_SetCounter(TIM2, 0); @@ -685,10 +704,9 @@ bool furi_hal_subghz_is_async_tx_complete() { void furi_hal_subghz_stop_async_tx() { furi_assert( - furi_hal_subghz_state == SubGhzStateAsyncTx - || furi_hal_subghz_state == SubGhzStateAsyncTxLast - || furi_hal_subghz_state == SubGhzStateAsyncTxEnd - ); + furi_hal_subghz_state == SubGhzStateAsyncTx || + furi_hal_subghz_state == SubGhzStateAsyncTxLast || + furi_hal_subghz_state == SubGhzStateAsyncTxEnd); // Shutdown radio furi_hal_subghz_idle(); diff --git a/firmware/targets/f6/furi-hal/furi-hal-version.c b/firmware/targets/f6/furi-hal/furi-hal-version.c index a58a9d1c50b..90a3d6c2950 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-version.c +++ b/firmware/targets/f6/furi-hal/furi-hal-version.c @@ -163,7 +163,7 @@ void furi_hal_version_init() { case FuriHalVersionOtpVersion1: furi_hal_version_load_otp_v1(); break; - default: furi_check(0); + default: furi_crash(NULL); } FURI_LOG_I("FuriHalVersion", "Init OK"); } diff --git a/firmware/targets/f6/furi-hal/furi-hal.c b/firmware/targets/f6/furi-hal/furi-hal.c index 2f0d850b580..2ec06dd462c 100644 --- a/firmware/targets/f6/furi-hal/furi-hal.c +++ b/firmware/targets/f6/furi-hal/furi-hal.c @@ -1,10 +1,6 @@ #include -#include #include -#include -#include -#include #include #include #include @@ -34,16 +30,8 @@ void furi_hal_init() { FURI_LOG_I("HAL", "TIM16 OK"); MX_COMP1_Init(); FURI_LOG_I("HAL", "COMP1 OK"); - MX_RF_Init(); - FURI_LOG_I("HAL", "RF OK"); - MX_PKA_Init(); - FURI_LOG_I("HAL", "PKA OK"); - MX_RNG_Init(); - FURI_LOG_I("HAL", "RNG OK"); - MX_AES1_Init(); - FURI_LOG_I("HAL", "AES1 OK"); - MX_AES2_Init(); - FURI_LOG_I("HAL", "AES2 OK"); + + furi_hal_crypto_init(); // VCP + USB furi_hal_vcp_init(); diff --git a/firmware/targets/f6/startup_stm32wb55xx_cm4.s b/firmware/targets/f6/startup_stm32wb55xx_cm4.s index fc26cb429b6..c5c2b3fc3d8 100644 --- a/firmware/targets/f6/startup_stm32wb55xx_cm4.s +++ b/firmware/targets/f6/startup_stm32wb55xx_cm4.s @@ -1,445 +1,444 @@ -/** - ****************************************************************************** - * @file startup_stm32wb55xx_cm4.s - * @author MCD Application Team - * @brief STM32WB55xx devices vector table GCC toolchain. - * This module performs: - * - Set the initial SP - * - Set the initial PC == Reset_Handler, - * - Set the vector table entries with the exceptions ISR address - * - Branches to main in the C library (which eventually - * calls main()). - * After Reset the Cortex-M4 processor is in Thread mode, - * priority is Privileged, and the Stack is set to Main. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - - .syntax unified - .cpu cortex-m4 - .fpu softvfp - .thumb - -.global g_pfnVectors -.global Default_Handler - -/* start address for the initialization values of the .data section. -defined in linker script */ -.word _sidata -/* start address for the .data section. defined in linker script */ -.word _sdata -/* end address for the .data section. defined in linker script */ -.word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss -/* start address for the .MB_MEM2 section. defined in linker script */ -.word _sMB_MEM2 -/* end address for the .MB_MEM2 section. defined in linker script */ -.word _eMB_MEM2 - -/* INIT_BSS macro is used to fill the specified region [start : end] with zeros */ -.macro INIT_BSS start, end - ldr r0, =\start - ldr r1, =\end - movs r3, #0 - bl LoopFillZerobss -.endm - -/* INIT_DATA macro is used to copy data in the region [start : end] starting from 'src' */ -.macro INIT_DATA start, end, src - ldr r0, =\start - ldr r1, =\end - ldr r2, =\src - movs r3, #0 - bl LoopCopyDataInit -.endm - -.section .text.data_initializers -CopyDataInit: - ldr r4, [r2, r3] - str r4, [r0, r3] - adds r3, r3, #4 - -LoopCopyDataInit: - adds r4, r0, r3 - cmp r4, r1 - bcc CopyDataInit - bx lr - -FillZerobss: - str r3, [r0] - adds r0, r0, #4 - -LoopFillZerobss: - cmp r0, r1 - bcc FillZerobss - bx lr - - .section .text.Reset_Handler - .weak Reset_Handler - .type Reset_Handler, %function -Reset_Handler: - ldr r0, =_estack - mov sp, r0 /* set stack pointer */ -/* Call the clock system intitialization function.*/ - bl SystemInit - -/* Copy the data segment initializers from flash to SRAM */ - INIT_DATA _sdata, _edata, _sidata - -/* Zero fill the bss segments. */ - INIT_BSS _sbss, _ebss - INIT_BSS _sMB_MEM2, _eMB_MEM2 - -/* Call static constructors */ - bl __libc_init_array -/* Call the application s entry point.*/ - bl main - -LoopForever: - b LoopForever - -.size Reset_Handler, .-Reset_Handler - -/** - * @brief This is the code that gets called when the processor receives an - * unexpected interrupt. This simply enters an infinite loop, preserving - * the system state for examination by a debugger. - * - * @param None - * @retval None -*/ - .section .text.Default_Handler,"ax",%progbits -Default_Handler: -Infinite_Loop: - b Infinite_Loop - .size Default_Handler, .-Default_Handler -/****************************************************************************** -* -* The minimal vector table for a Cortex-M4. Note that the proper constructs -* must be placed on this to ensure that it ends up at physical address -* 0x0000.0000. -* -******************************************************************************/ - .section .isr_vector,"a",%progbits - .type g_pfnVectors, %object - .size g_pfnVectors, .-g_pfnVectors - - -g_pfnVectors: - .word _estack - .word Reset_Handler - .word NMI_Handler - .word HardFault_Handler - .word MemManage_Handler - .word BusFault_Handler - .word UsageFault_Handler - .word 0 - .word 0 - .word 0 - .word 0 - .word SVC_Handler - .word DebugMon_Handler - .word 0 - .word PendSV_Handler - .word SysTick_Handler - .word WWDG_IRQHandler - .word PVD_PVM_IRQHandler - .word TAMP_STAMP_LSECSS_IRQHandler - .word RTC_WKUP_IRQHandler - .word FLASH_IRQHandler - .word RCC_IRQHandler - .word EXTI0_IRQHandler - .word EXTI1_IRQHandler - .word EXTI2_IRQHandler - .word EXTI3_IRQHandler - .word EXTI4_IRQHandler - .word DMA1_Channel1_IRQHandler - .word DMA1_Channel2_IRQHandler - .word DMA1_Channel3_IRQHandler - .word DMA1_Channel4_IRQHandler - .word DMA1_Channel5_IRQHandler - .word DMA1_Channel6_IRQHandler - .word DMA1_Channel7_IRQHandler - .word ADC1_IRQHandler - .word USB_HP_IRQHandler - .word USB_LP_IRQHandler - .word C2SEV_PWR_C2H_IRQHandler - .word COMP_IRQHandler - .word EXTI9_5_IRQHandler - .word TIM1_BRK_IRQHandler - .word TIM1_UP_TIM16_IRQHandler - .word TIM1_TRG_COM_TIM17_IRQHandler - .word TIM1_CC_IRQHandler - .word TIM2_IRQHandler - .word PKA_IRQHandler - .word I2C1_EV_IRQHandler - .word I2C1_ER_IRQHandler - .word I2C3_EV_IRQHandler - .word I2C3_ER_IRQHandler - .word SPI1_IRQHandler - .word SPI2_IRQHandler - .word USART1_IRQHandler - .word LPUART1_IRQHandler - .word SAI1_IRQHandler - .word TSC_IRQHandler - .word EXTI15_10_IRQHandler - .word RTC_Alarm_IRQHandler - .word CRS_IRQHandler - .word PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler - .word IPCC_C1_RX_IRQHandler - .word IPCC_C1_TX_IRQHandler - .word HSEM_IRQHandler - .word LPTIM1_IRQHandler - .word LPTIM2_IRQHandler - .word LCD_IRQHandler - .word QUADSPI_IRQHandler - .word AES1_IRQHandler - .word AES2_IRQHandler - .word RNG_IRQHandler - .word FPU_IRQHandler - .word DMA2_Channel1_IRQHandler - .word DMA2_Channel2_IRQHandler - .word DMA2_Channel3_IRQHandler - .word DMA2_Channel4_IRQHandler - .word DMA2_Channel5_IRQHandler - .word DMA2_Channel6_IRQHandler - .word DMA2_Channel7_IRQHandler - .word DMAMUX1_OVR_IRQHandler - -/******************************************************************************* -* -* Provide weak aliases for each Exception handler to the Default_Handler. -* As they are weak aliases, any function with the same name will override -* this definition. -* -*******************************************************************************/ - .weak NMI_Handler - .thumb_set NMI_Handler,Default_Handler - - .weak HardFault_Handler - .thumb_set HardFault_Handler,Default_Handler - - .weak MemManage_Handler - .thumb_set MemManage_Handler,Default_Handler - - .weak BusFault_Handler - .thumb_set BusFault_Handler,Default_Handler - - .weak UsageFault_Handler - .thumb_set UsageFault_Handler,Default_Handler - - .weak SVC_Handler - .thumb_set SVC_Handler,Default_Handler - - .weak DebugMon_Handler - .thumb_set DebugMon_Handler,Default_Handler - - .weak PendSV_Handler - .thumb_set PendSV_Handler,Default_Handler - - .weak SysTick_Handler - .thumb_set SysTick_Handler,Default_Handler - - .weak WWDG_IRQHandler - .thumb_set WWDG_IRQHandler,Default_Handler - - .weak PVD_PVM_IRQHandler - .thumb_set PVD_PVM_IRQHandler,Default_Handler - - .weak TAMP_STAMP_LSECSS_IRQHandler - .thumb_set TAMP_STAMP_LSECSS_IRQHandler,Default_Handler - - .weak RTC_WKUP_IRQHandler - .thumb_set RTC_WKUP_IRQHandler,Default_Handler - - .weak FLASH_IRQHandler - .thumb_set FLASH_IRQHandler,Default_Handler - - .weak RCC_IRQHandler - .thumb_set RCC_IRQHandler,Default_Handler - - .weak EXTI0_IRQHandler - .thumb_set EXTI0_IRQHandler,Default_Handler - - .weak EXTI1_IRQHandler - .thumb_set EXTI1_IRQHandler,Default_Handler - - .weak EXTI2_IRQHandler - .thumb_set EXTI2_IRQHandler,Default_Handler - - .weak EXTI3_IRQHandler - .thumb_set EXTI3_IRQHandler,Default_Handler - - .weak EXTI4_IRQHandler - .thumb_set EXTI4_IRQHandler,Default_Handler - - .weak DMA1_Channel1_IRQHandler - .thumb_set DMA1_Channel1_IRQHandler,Default_Handler - - .weak DMA1_Channel2_IRQHandler - .thumb_set DMA1_Channel2_IRQHandler,Default_Handler - - .weak DMA1_Channel3_IRQHandler - .thumb_set DMA1_Channel3_IRQHandler,Default_Handler - - .weak DMA1_Channel4_IRQHandler - .thumb_set DMA1_Channel4_IRQHandler,Default_Handler - - .weak DMA1_Channel5_IRQHandler - .thumb_set DMA1_Channel5_IRQHandler,Default_Handler - - .weak DMA1_Channel6_IRQHandler - .thumb_set DMA1_Channel6_IRQHandler,Default_Handler - - .weak DMA1_Channel7_IRQHandler - .thumb_set DMA1_Channel7_IRQHandler,Default_Handler - - .weak ADC1_IRQHandler - .thumb_set ADC1_IRQHandler,Default_Handler - - .weak USB_HP_IRQHandler - .thumb_set USB_HP_IRQHandler,Default_Handler - - .weak USB_LP_IRQHandler - .thumb_set USB_LP_IRQHandler,Default_Handler - - .weak C2SEV_PWR_C2H_IRQHandler - .thumb_set C2SEV_PWR_C2H_IRQHandler,Default_Handler - - .weak COMP_IRQHandler - .thumb_set COMP_IRQHandler,Default_Handler - - .weak EXTI9_5_IRQHandler - .thumb_set EXTI9_5_IRQHandler,Default_Handler - - .weak TIM1_BRK_IRQHandler - .thumb_set TIM1_BRK_IRQHandler,Default_Handler - - .weak TIM1_UP_TIM16_IRQHandler - .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler - - .weak TIM1_TRG_COM_TIM17_IRQHandler - .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler - - .weak TIM1_CC_IRQHandler - .thumb_set TIM1_CC_IRQHandler,Default_Handler - - .weak TIM2_IRQHandler - .thumb_set TIM2_IRQHandler,Default_Handler - - .weak PKA_IRQHandler - .thumb_set PKA_IRQHandler,Default_Handler - - .weak I2C1_EV_IRQHandler - .thumb_set I2C1_EV_IRQHandler,Default_Handler - - .weak I2C1_ER_IRQHandler - .thumb_set I2C1_ER_IRQHandler,Default_Handler - - .weak I2C3_EV_IRQHandler - .thumb_set I2C3_EV_IRQHandler,Default_Handler - - .weak I2C3_ER_IRQHandler - .thumb_set I2C3_ER_IRQHandler,Default_Handler - - .weak SPI1_IRQHandler - .thumb_set SPI1_IRQHandler,Default_Handler - - .weak SPI2_IRQHandler - .thumb_set SPI2_IRQHandler,Default_Handler - - .weak USART1_IRQHandler - .thumb_set USART1_IRQHandler,Default_Handler - - .weak LPUART1_IRQHandler - .thumb_set LPUART1_IRQHandler,Default_Handler - - .weak SAI1_IRQHandler - .thumb_set SAI1_IRQHandler,Default_Handler - - .weak TSC_IRQHandler - .thumb_set TSC_IRQHandler,Default_Handler - - .weak EXTI15_10_IRQHandler - .thumb_set EXTI15_10_IRQHandler,Default_Handler - - .weak RTC_Alarm_IRQHandler - .thumb_set RTC_Alarm_IRQHandler,Default_Handler - - .weak CRS_IRQHandler - .thumb_set CRS_IRQHandler,Default_Handler - - .weak PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler - .thumb_set PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler,Default_Handler - - .weak IPCC_C1_RX_IRQHandler - .thumb_set IPCC_C1_RX_IRQHandler,Default_Handler - - .weak IPCC_C1_TX_IRQHandler - .thumb_set IPCC_C1_TX_IRQHandler,Default_Handler - - .weak HSEM_IRQHandler - .thumb_set HSEM_IRQHandler,Default_Handler - - .weak LPTIM1_IRQHandler - .thumb_set LPTIM1_IRQHandler,Default_Handler - - .weak LPTIM2_IRQHandler - .thumb_set LPTIM2_IRQHandler,Default_Handler - - .weak LCD_IRQHandler - .thumb_set LCD_IRQHandler,Default_Handler - - .weak QUADSPI_IRQHandler - .thumb_set QUADSPI_IRQHandler,Default_Handler - - .weak AES1_IRQHandler - .thumb_set AES1_IRQHandler,Default_Handler - - .weak AES2_IRQHandler - .thumb_set AES2_IRQHandler,Default_Handler - - .weak RNG_IRQHandler - .thumb_set RNG_IRQHandler,Default_Handler - - .weak FPU_IRQHandler - .thumb_set FPU_IRQHandler,Default_Handler - - .weak DMA2_Channel1_IRQHandler - .thumb_set DMA2_Channel1_IRQHandler,Default_Handler - - .weak DMA2_Channel2_IRQHandler - .thumb_set DMA2_Channel2_IRQHandler,Default_Handler - - .weak DMA2_Channel3_IRQHandler - .thumb_set DMA2_Channel3_IRQHandler,Default_Handler - - .weak DMA2_Channel4_IRQHandler - .thumb_set DMA2_Channel4_IRQHandler,Default_Handler - - .weak DMA2_Channel5_IRQHandler - .thumb_set DMA2_Channel5_IRQHandler,Default_Handler - - .weak DMA2_Channel6_IRQHandler - .thumb_set DMA2_Channel6_IRQHandler,Default_Handler - - .weak DMA2_Channel7_IRQHandler - .thumb_set DMA2_Channel7_IRQHandler,Default_Handler - - .weak DMAMUX1_OVR_IRQHandler - .thumb_set DMAMUX1_OVR_IRQHandler,Default_Handler - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file startup_stm32wb55xx_cm4.s + * @author MCD Application Team + * @brief STM32WB55xx devices vector table GCC toolchain. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M4 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m4 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss +/* start address for the .MB_MEM2 section. defined in linker script */ +.word _sMB_MEM2 +/* end address for the .MB_MEM2 section. defined in linker script */ +.word _eMB_MEM2 + +/* INIT_BSS macro is used to fill the specified region [start : end] with zeros */ +.macro INIT_BSS start, end + ldr r0, =\start + ldr r1, =\end + movs r3, #0 + bl LoopFillZerobss +.endm + +/* INIT_DATA macro is used to copy data in the region [start : end] starting from 'src' */ +.macro INIT_DATA start, end, src + ldr r0, =\start + ldr r1, =\end + ldr r2, =\src + movs r3, #0 + bl LoopCopyDataInit +.endm + +.section .text.data_initializers +CopyDataInit: + ldr r4, [r2, r3] + str r4, [r0, r3] + adds r3, r3, #4 + +LoopCopyDataInit: + adds r4, r0, r3 + cmp r4, r1 + bcc CopyDataInit + bx lr + +FillZerobss: + str r3, [r0] + adds r0, r0, #4 + +LoopFillZerobss: + cmp r0, r1 + bcc FillZerobss + bx lr + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr r0, =_estack + mov sp, r0 /* set stack pointer */ +/* Call the clock system intitialization function.*/ + bl SystemInit + +/* Copy the data segment initializers from flash to SRAM */ + INIT_DATA _sdata, _edata, _sidata + +/* Zero fill the bss segments. */ + INIT_BSS _sbss, _ebss + INIT_BSS _sMB_MEM2, _eMB_MEM2 + +/* Call static constructors */ + bl __libc_init_array +/* Call the application s entry point.*/ + bl main + +LoopForever: + b LoopForever + +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex-M4. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + .word WWDG_IRQHandler + .word PVD_PVM_IRQHandler + .word TAMP_STAMP_LSECSS_IRQHandler + .word RTC_WKUP_IRQHandler + .word FLASH_IRQHandler + .word RCC_IRQHandler + .word EXTI0_IRQHandler + .word EXTI1_IRQHandler + .word EXTI2_IRQHandler + .word EXTI3_IRQHandler + .word EXTI4_IRQHandler + .word DMA1_Channel1_IRQHandler + .word DMA1_Channel2_IRQHandler + .word DMA1_Channel3_IRQHandler + .word DMA1_Channel4_IRQHandler + .word DMA1_Channel5_IRQHandler + .word DMA1_Channel6_IRQHandler + .word DMA1_Channel7_IRQHandler + .word ADC1_IRQHandler + .word USB_HP_IRQHandler + .word USB_LP_IRQHandler + .word C2SEV_PWR_C2H_IRQHandler + .word COMP_IRQHandler + .word EXTI9_5_IRQHandler + .word TIM1_BRK_IRQHandler + .word TIM1_UP_TIM16_IRQHandler + .word TIM1_TRG_COM_TIM17_IRQHandler + .word TIM1_CC_IRQHandler + .word TIM2_IRQHandler + .word PKA_IRQHandler + .word I2C1_EV_IRQHandler + .word I2C1_ER_IRQHandler + .word I2C3_EV_IRQHandler + .word I2C3_ER_IRQHandler + .word SPI1_IRQHandler + .word SPI2_IRQHandler + .word USART1_IRQHandler + .word LPUART1_IRQHandler + .word SAI1_IRQHandler + .word TSC_IRQHandler + .word EXTI15_10_IRQHandler + .word RTC_Alarm_IRQHandler + .word CRS_IRQHandler + .word PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler + .word IPCC_C1_RX_IRQHandler + .word IPCC_C1_TX_IRQHandler + .word HSEM_IRQHandler + .word LPTIM1_IRQHandler + .word LPTIM2_IRQHandler + .word LCD_IRQHandler + .word QUADSPI_IRQHandler + .word AES1_IRQHandler + .word AES2_IRQHandler + .word RNG_IRQHandler + .word FPU_IRQHandler + .word DMA2_Channel1_IRQHandler + .word DMA2_Channel2_IRQHandler + .word DMA2_Channel3_IRQHandler + .word DMA2_Channel4_IRQHandler + .word DMA2_Channel5_IRQHandler + .word DMA2_Channel6_IRQHandler + .word DMA2_Channel7_IRQHandler + .word DMAMUX1_OVR_IRQHandler + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_PVM_IRQHandler + .thumb_set PVD_PVM_IRQHandler,Default_Handler + + .weak TAMP_STAMP_LSECSS_IRQHandler + .thumb_set TAMP_STAMP_LSECSS_IRQHandler,Default_Handler + + .weak RTC_WKUP_IRQHandler + .thumb_set RTC_WKUP_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak DMA1_Channel1_IRQHandler + .thumb_set DMA1_Channel1_IRQHandler,Default_Handler + + .weak DMA1_Channel2_IRQHandler + .thumb_set DMA1_Channel2_IRQHandler,Default_Handler + + .weak DMA1_Channel3_IRQHandler + .thumb_set DMA1_Channel3_IRQHandler,Default_Handler + + .weak DMA1_Channel4_IRQHandler + .thumb_set DMA1_Channel4_IRQHandler,Default_Handler + + .weak DMA1_Channel5_IRQHandler + .thumb_set DMA1_Channel5_IRQHandler,Default_Handler + + .weak DMA1_Channel6_IRQHandler + .thumb_set DMA1_Channel6_IRQHandler,Default_Handler + + .weak DMA1_Channel7_IRQHandler + .thumb_set DMA1_Channel7_IRQHandler,Default_Handler + + .weak ADC1_IRQHandler + .thumb_set ADC1_IRQHandler,Default_Handler + + .weak USB_HP_IRQHandler + .thumb_set USB_HP_IRQHandler,Default_Handler + + .weak USB_LP_IRQHandler + .thumb_set USB_LP_IRQHandler,Default_Handler + + .weak C2SEV_PWR_C2H_IRQHandler + .thumb_set C2SEV_PWR_C2H_IRQHandler,Default_Handler + + .weak COMP_IRQHandler + .thumb_set COMP_IRQHandler,Default_Handler + + .weak EXTI9_5_IRQHandler + .thumb_set EXTI9_5_IRQHandler,Default_Handler + + .weak TIM1_BRK_IRQHandler + .thumb_set TIM1_BRK_IRQHandler,Default_Handler + + .weak TIM1_UP_TIM16_IRQHandler + .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler + + .weak TIM1_TRG_COM_TIM17_IRQHandler + .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak PKA_IRQHandler + .thumb_set PKA_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak LPUART1_IRQHandler + .thumb_set LPUART1_IRQHandler,Default_Handler + + .weak SAI1_IRQHandler + .thumb_set SAI1_IRQHandler,Default_Handler + + .weak TSC_IRQHandler + .thumb_set TSC_IRQHandler,Default_Handler + + .weak EXTI15_10_IRQHandler + .thumb_set EXTI15_10_IRQHandler,Default_Handler + + .weak RTC_Alarm_IRQHandler + .thumb_set RTC_Alarm_IRQHandler,Default_Handler + + .weak CRS_IRQHandler + .thumb_set CRS_IRQHandler,Default_Handler + + .weak PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler + .thumb_set PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler,Default_Handler + + .weak IPCC_C1_RX_IRQHandler + .thumb_set IPCC_C1_RX_IRQHandler,Default_Handler + + .weak IPCC_C1_TX_IRQHandler + .thumb_set IPCC_C1_TX_IRQHandler,Default_Handler + + .weak HSEM_IRQHandler + .thumb_set HSEM_IRQHandler,Default_Handler + + .weak LPTIM1_IRQHandler + .thumb_set LPTIM1_IRQHandler,Default_Handler + + .weak LPTIM2_IRQHandler + .thumb_set LPTIM2_IRQHandler,Default_Handler + + .weak LCD_IRQHandler + .thumb_set LCD_IRQHandler,Default_Handler + + .weak QUADSPI_IRQHandler + .thumb_set QUADSPI_IRQHandler,Default_Handler + + .weak AES1_IRQHandler + .thumb_set AES1_IRQHandler,Default_Handler + + .weak AES2_IRQHandler + .thumb_set AES2_IRQHandler,Default_Handler + + .weak RNG_IRQHandler + .thumb_set RNG_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak DMA2_Channel1_IRQHandler + .thumb_set DMA2_Channel1_IRQHandler,Default_Handler + + .weak DMA2_Channel2_IRQHandler + .thumb_set DMA2_Channel2_IRQHandler,Default_Handler + + .weak DMA2_Channel3_IRQHandler + .thumb_set DMA2_Channel3_IRQHandler,Default_Handler + + .weak DMA2_Channel4_IRQHandler + .thumb_set DMA2_Channel4_IRQHandler,Default_Handler + + .weak DMA2_Channel5_IRQHandler + .thumb_set DMA2_Channel5_IRQHandler,Default_Handler + + .weak DMA2_Channel6_IRQHandler + .thumb_set DMA2_Channel6_IRQHandler,Default_Handler + + .weak DMA2_Channel7_IRQHandler + .thumb_set DMA2_Channel7_IRQHandler,Default_Handler + + .weak DMAMUX1_OVR_IRQHandler + .thumb_set DMAMUX1_OVR_IRQHandler,Default_Handler + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f6/target.mk b/firmware/targets/f6/target.mk index d020c155c5a..fe9501499cb 100644 --- a/firmware/targets/f6/target.mk +++ b/firmware/targets/f6/target.mk @@ -53,12 +53,9 @@ C_SOURCES += \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_ipcc.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd_ex.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pka.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr_ex.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc_ex.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rng.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc_ex.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim.c \ @@ -81,7 +78,6 @@ CFLAGS += \ -I$(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \ -I$(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F C_SOURCES += \ - $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/croutine.c \ $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c \ $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/list.c \ $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/queue.c \ diff --git a/firmware/targets/f7/Inc/aes.h b/firmware/targets/f7/Inc/aes.h deleted file mode 100644 index bde8ad5a821..00000000000 --- a/firmware/targets/f7/Inc/aes.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - ****************************************************************************** - * @file aes.h - * @brief This file contains all the function prototypes for - * the aes.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __AES_H__ -#define __AES_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern CRYP_HandleTypeDef hcryp1; -extern CRYP_HandleTypeDef hcryp2; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_AES1_Init(void); -void MX_AES2_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __AES_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/Inc/pka.h b/firmware/targets/f7/Inc/pka.h deleted file mode 100644 index 377ed0105f1..00000000000 --- a/firmware/targets/f7/Inc/pka.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - ****************************************************************************** - * @file pka.h - * @brief This file contains all the function prototypes for - * the pka.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __PKA_H__ -#define __PKA_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern PKA_HandleTypeDef hpka; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_PKA_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __PKA_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/Inc/rf.h b/firmware/targets/f7/Inc/rf.h deleted file mode 100644 index 1796e939a9a..00000000000 --- a/firmware/targets/f7/Inc/rf.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - ****************************************************************************** - * @file rf.h - * @brief This file contains all the function prototypes for - * the rf.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __RF_H__ -#define __RF_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_RF_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __RF_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/Inc/rng.h b/firmware/targets/f7/Inc/rng.h deleted file mode 100644 index fa121ad11cf..00000000000 --- a/firmware/targets/f7/Inc/rng.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - ****************************************************************************** - * @file rng.h - * @brief This file contains all the function prototypes for - * the rng.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __RNG_H__ -#define __RNG_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern RNG_HandleTypeDef hrng; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_RNG_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __RNG_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/Src/aes.c b/firmware/targets/f7/Src/aes.c deleted file mode 100644 index 1a042e9b8d1..00000000000 --- a/firmware/targets/f7/Src/aes.c +++ /dev/null @@ -1,127 +0,0 @@ -/** - ****************************************************************************** - * @file aes.c - * @brief This file provides code for the configuration - * of the AES instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "aes.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -CRYP_HandleTypeDef hcryp1; -__ALIGN_BEGIN static const uint32_t pKeyAES1[4] __ALIGN_END = { - 0x00000000,0x00000000,0x00000000,0x00000000}; -CRYP_HandleTypeDef hcryp2; -__ALIGN_BEGIN static const uint32_t pKeyAES2[4] __ALIGN_END = { - 0x00000000,0x00000000,0x00000000,0x00000000}; - -/* AES1 init function */ -void MX_AES1_Init(void) -{ - - hcryp1.Instance = AES1; - hcryp1.Init.DataType = CRYP_DATATYPE_32B; - hcryp1.Init.KeySize = CRYP_KEYSIZE_128B; - hcryp1.Init.pKey = (uint32_t *)pKeyAES1; - hcryp1.Init.Algorithm = CRYP_AES_ECB; - hcryp1.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_WORD; - hcryp1.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS; - if (HAL_CRYP_Init(&hcryp1) != HAL_OK) - { - Error_Handler(); - } - -} -/* AES2 init function */ -void MX_AES2_Init(void) -{ - - hcryp2.Instance = AES2; - hcryp2.Init.DataType = CRYP_DATATYPE_32B; - hcryp2.Init.KeySize = CRYP_KEYSIZE_128B; - hcryp2.Init.pKey = (uint32_t *)pKeyAES2; - hcryp2.Init.Algorithm = CRYP_AES_ECB; - hcryp2.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_WORD; - hcryp2.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS; - if (HAL_CRYP_Init(&hcryp2) != HAL_OK) - { - Error_Handler(); - } - -} - -void HAL_CRYP_MspInit(CRYP_HandleTypeDef* crypHandle) -{ - - if(crypHandle->Instance==AES1) - { - /* USER CODE BEGIN AES1_MspInit 0 */ - - /* USER CODE END AES1_MspInit 0 */ - /* AES1 clock enable */ - __HAL_RCC_AES1_CLK_ENABLE(); - /* USER CODE BEGIN AES1_MspInit 1 */ - - /* USER CODE END AES1_MspInit 1 */ - } - else if(crypHandle->Instance==AES2) - { - /* USER CODE BEGIN AES2_MspInit 0 */ - - /* USER CODE END AES2_MspInit 0 */ - /* AES2 clock enable */ - __HAL_RCC_AES2_CLK_ENABLE(); - /* USER CODE BEGIN AES2_MspInit 1 */ - - /* USER CODE END AES2_MspInit 1 */ - } -} - -void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef* crypHandle) -{ - - if(crypHandle->Instance==AES1) - { - /* USER CODE BEGIN AES1_MspDeInit 0 */ - - /* USER CODE END AES1_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_AES1_CLK_DISABLE(); - /* USER CODE BEGIN AES1_MspDeInit 1 */ - - /* USER CODE END AES1_MspDeInit 1 */ - } - else if(crypHandle->Instance==AES2) - { - /* USER CODE BEGIN AES2_MspDeInit 0 */ - - /* USER CODE END AES2_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_AES2_CLK_DISABLE(); - /* USER CODE BEGIN AES2_MspDeInit 1 */ - - /* USER CODE END AES2_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/Src/pka.c b/firmware/targets/f7/Src/pka.c deleted file mode 100644 index 8377ce5722d..00000000000 --- a/firmware/targets/f7/Src/pka.c +++ /dev/null @@ -1,77 +0,0 @@ -/** - ****************************************************************************** - * @file pka.c - * @brief This file provides code for the configuration - * of the PKA instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "pka.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -PKA_HandleTypeDef hpka; - -/* PKA init function */ -void MX_PKA_Init(void) -{ - - hpka.Instance = PKA; - if (HAL_PKA_Init(&hpka) != HAL_OK) - { - Error_Handler(); - } - -} - -void HAL_PKA_MspInit(PKA_HandleTypeDef* pkaHandle) -{ - - if(pkaHandle->Instance==PKA) - { - /* USER CODE BEGIN PKA_MspInit 0 */ - - /* USER CODE END PKA_MspInit 0 */ - /* PKA clock enable */ - __HAL_RCC_PKA_CLK_ENABLE(); - /* USER CODE BEGIN PKA_MspInit 1 */ - - /* USER CODE END PKA_MspInit 1 */ - } -} - -void HAL_PKA_MspDeInit(PKA_HandleTypeDef* pkaHandle) -{ - - if(pkaHandle->Instance==PKA) - { - /* USER CODE BEGIN PKA_MspDeInit 0 */ - - /* USER CODE END PKA_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_PKA_CLK_DISABLE(); - /* USER CODE BEGIN PKA_MspDeInit 1 */ - - /* USER CODE END PKA_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/Src/rf.c b/firmware/targets/f7/Src/rf.c deleted file mode 100644 index 62daf9b2183..00000000000 --- a/firmware/targets/f7/Src/rf.c +++ /dev/null @@ -1,37 +0,0 @@ -/** - ****************************************************************************** - * @file rf.c - * @brief This file provides code for the configuration - * of the RF instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "rf.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -/* RF init function */ -void MX_RF_Init(void) -{ - -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/Src/rng.c b/firmware/targets/f7/Src/rng.c deleted file mode 100644 index c2fb144e64a..00000000000 --- a/firmware/targets/f7/Src/rng.c +++ /dev/null @@ -1,77 +0,0 @@ -/** - ****************************************************************************** - * @file rng.c - * @brief This file provides code for the configuration - * of the RNG instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "rng.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -RNG_HandleTypeDef hrng; - -/* RNG init function */ -void MX_RNG_Init(void) -{ - - hrng.Instance = RNG; - if (HAL_RNG_Init(&hrng) != HAL_OK) - { - Error_Handler(); - } - -} - -void HAL_RNG_MspInit(RNG_HandleTypeDef* rngHandle) -{ - - if(rngHandle->Instance==RNG) - { - /* USER CODE BEGIN RNG_MspInit 0 */ - - /* USER CODE END RNG_MspInit 0 */ - /* RNG clock enable */ - __HAL_RCC_RNG_CLK_ENABLE(); - /* USER CODE BEGIN RNG_MspInit 1 */ - - /* USER CODE END RNG_MspInit 1 */ - } -} - -void HAL_RNG_MspDeInit(RNG_HandleTypeDef* rngHandle) -{ - - if(rngHandle->Instance==RNG) - { - /* USER CODE BEGIN RNG_MspDeInit 0 */ - - /* USER CODE END RNG_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_RNG_CLK_DISABLE(); - /* USER CODE BEGIN RNG_MspDeInit 1 */ - - /* USER CODE END RNG_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/ble-glue/app_ble.c b/firmware/targets/f7/ble-glue/app_ble.c deleted file mode 100644 index 652c29efe50..00000000000 --- a/firmware/targets/f7/ble-glue/app_ble.c +++ /dev/null @@ -1,140 +0,0 @@ -#include "main.h" - -#include "app_entry.h" -#include "app_common.h" -#include "dbg_trace.h" -#include "ble.h" -#include "tl.h" -#include "app_ble.h" -#include "shci.h" -#include "cmsis_os.h" - -#include - -PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t BleCmdBuffer; - -// PLACE_IN_SECTION("TAG_OTA_END") const uint32_t MagicKeywordValue = 0x94448A29 ; -// PLACE_IN_SECTION("TAG_OTA_START") const uint32_t MagicKeywordAddress = (uint32_t)&MagicKeywordValue; - -osMutexId_t MtxHciId; -osSemaphoreId_t SemHciId; -osThreadId_t HciUserEvtProcessId; - -const osThreadAttr_t HciUserEvtProcess_attr = { - .name = CFG_HCI_USER_EVT_PROCESS_NAME, - .attr_bits = CFG_HCI_USER_EVT_PROCESS_ATTR_BITS, - .cb_mem = CFG_HCI_USER_EVT_PROCESS_CB_MEM, - .cb_size = CFG_HCI_USER_EVT_PROCESS_CB_SIZE, - .stack_mem = CFG_HCI_USER_EVT_PROCESS_STACK_MEM, - .priority = CFG_HCI_USER_EVT_PROCESS_PRIORITY, - .stack_size = CFG_HCI_USER_EVT_PROCESS_STACK_SIZE -}; - -/* Private function prototypes -----------------------------------------------*/ -static void HciUserEvtProcess(void *argument); -static void BLE_UserEvtRx( void * pPayload ); -static void BLE_StatusNot( HCI_TL_CmdStatus_t status ); -static void Ble_Tl_Init( void ); - -bool APP_BLE_Init() { - SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = { - {{0,0,0}}, /**< Header unused */ - {0, /** pBleBufferAddress not used */ - 0, /** BleBufferSize not used */ - CFG_BLE_NUM_GATT_ATTRIBUTES, - CFG_BLE_NUM_GATT_SERVICES, - CFG_BLE_ATT_VALUE_ARRAY_SIZE, - CFG_BLE_NUM_LINK, - CFG_BLE_DATA_LENGTH_EXTENSION, - CFG_BLE_PREPARE_WRITE_LIST_SIZE, - CFG_BLE_MBLOCK_COUNT, - CFG_BLE_MAX_ATT_MTU, - CFG_BLE_SLAVE_SCA, - CFG_BLE_MASTER_SCA, - CFG_BLE_LSE_SOURCE, - CFG_BLE_MAX_CONN_EVENT_LENGTH, - CFG_BLE_HSE_STARTUP_TIME, - CFG_BLE_VITERBI_MODE, - CFG_BLE_LL_ONLY, - 0} - }; - - // Initialize Ble Transport Layer - Ble_Tl_Init( ); - // Register the hci transport layer to handle BLE User Asynchronous Events - HciUserEvtProcessId = osThreadNew(HciUserEvtProcess, NULL, &HciUserEvtProcess_attr); - // Starts the BLE Stack on CPU2 - return (SHCI_C2_BLE_Init( &ble_init_cmd_packet ) == SHCI_Success); -} - -static void Ble_Tl_Init( void ) { - HCI_TL_HciInitConf_t Hci_Tl_Init_Conf; - - MtxHciId = osMutexNew( NULL ); - SemHciId = osSemaphoreNew( 1, 0, NULL ); /*< Create the semaphore and make it busy at initialization */ - - Hci_Tl_Init_Conf.p_cmdbuffer = (uint8_t*)&BleCmdBuffer; - Hci_Tl_Init_Conf.StatusNotCallBack = BLE_StatusNot; - hci_init(BLE_UserEvtRx, (void*) &Hci_Tl_Init_Conf); -} - -static void HciUserEvtProcess(void *argument) { - UNUSED(argument); - - for(;;) - { - osThreadFlagsWait( 1, osFlagsWaitAny, osWaitForever); - hci_user_evt_proc( ); - } -} - -/************************************************************* - * - * WRAP FUNCTIONS - * - *************************************************************/ -void hci_notify_asynch_evt(void* pdata) { - UNUSED(pdata); - osThreadFlagsSet( HciUserEvtProcessId, 1 ); -} - -void hci_cmd_resp_release(uint32_t flag) { - UNUSED(flag); - osSemaphoreRelease( SemHciId ); -} - -void hci_cmd_resp_wait(uint32_t timeout) { - UNUSED(timeout); - osSemaphoreAcquire( SemHciId, osWaitForever ); -} - -static void BLE_UserEvtRx( void * pPayload ) { - SVCCTL_UserEvtFlowStatus_t svctl_return_status; - tHCI_UserEvtRxParam *pParam; - - pParam = (tHCI_UserEvtRxParam *)pPayload; - - svctl_return_status = SVCCTL_UserEvtRx((void *)&(pParam->pckt->evtserial)); - if (svctl_return_status != SVCCTL_UserEvtFlowDisable) { - pParam->status = HCI_TL_UserEventFlow_Enable; - } else { - pParam->status = HCI_TL_UserEventFlow_Disable; - } -} - -static void BLE_StatusNot( HCI_TL_CmdStatus_t status ) { - switch (status) { - case HCI_TL_CmdBusy: - osMutexAcquire( MtxHciId, osWaitForever ); - break; - case HCI_TL_CmdAvailable: - osMutexRelease( MtxHciId ); - break; - default: - break; - } -} - -void SVCCTL_ResumeUserEventFlow( void ) { - hci_resume_flow(); -} diff --git a/firmware/targets/f7/ble-glue/app_conf.h b/firmware/targets/f7/ble-glue/app_conf.h index 381d5ae741f..bfd6f9dd803 100644 --- a/firmware/targets/f7/ble-glue/app_conf.h +++ b/firmware/targets/f7/ble-glue/app_conf.h @@ -427,9 +427,6 @@ typedef enum #define DBG_TRACE_MSG_QUEUE_SIZE 4096 #define MAX_DBG_TRACE_MSG_SIZE 1024 -#define CFG_LED_SUPPORTED 0 -#define CFG_BUTTON_SUPPORTED 0 - /****************************************************************************** * FreeRTOS ******************************************************************************/ @@ -441,34 +438,5 @@ typedef enum #define CFG_SHCI_USER_EVT_PROCESS_PRIORITY osPriorityNone #define CFG_SHCI_USER_EVT_PROCESS_STACK_SIZE (128 * 7) -#define CFG_HCI_USER_EVT_PROCESS_NAME "ble_hci_evt" -#define CFG_HCI_USER_EVT_PROCESS_ATTR_BITS (0) -#define CFG_HCI_USER_EVT_PROCESS_CB_MEM (0) -#define CFG_HCI_USER_EVT_PROCESS_CB_SIZE (0) -#define CFG_HCI_USER_EVT_PROCESS_STACK_MEM (0) -#define CFG_HCI_USER_EVT_PROCESS_PRIORITY osPriorityNone -#define CFG_HCI_USER_EVT_PROCESS_STACK_SIZE (128 * 8) - -#define CFG_ADV_UPDATE_PROCESS_NAME "ble_adv_upd" -#define CFG_ADV_UPDATE_PROCESS_ATTR_BITS (0) -#define CFG_ADV_UPDATE_PROCESS_CB_MEM (0) -#define CFG_ADV_UPDATE_PROCESS_CB_SIZE (0) -#define CFG_ADV_UPDATE_PROCESS_STACK_MEM (0) -#define CFG_ADV_UPDATE_PROCESS_PRIORITY osPriorityNone -#define CFG_ADV_UPDATE_PROCESS_STACK_SIZE (128 * 6) - -#define CFG_HRS_PROCESS_NAME "hrs" -#define CFG_HRS_PROCESS_ATTR_BITS (0) -#define CFG_HRS_PROCESS_CB_MEM (0) -#define CFG_HRS_PROCESS_CB_SIZE (0) -#define CFG_HRS_PROCESS_STACK_MEM (0) -#define CFG_HRS_PROCESS_PRIORITY osPriorityNone -#define CFG_HRS_PROCESS_STACK_SIZE (128 * 8) - -typedef enum { - CFG_LPM_APP, - CFG_LPM_APP_BLE, -} CFG_LPM_Id_t; - #define CFG_OTP_BASE_ADDRESS OTP_AREA_BASE #define CFG_OTP_END_ADRESS OTP_AREA_END_ADDR diff --git a/firmware/targets/f7/ble-glue/app_entry.c b/firmware/targets/f7/ble-glue/app_entry.c index 431fed6aa99..a970da320a2 100644 --- a/firmware/targets/f7/ble-glue/app_entry.c +++ b/firmware/targets/f7/ble-glue/app_entry.c @@ -1,7 +1,7 @@ #include "app_common.h" #include "main.h" #include "app_entry.h" -#include "app_ble.h" +#include "ble_app.h" #include "ble.h" #include "tl.h" #include "cmsis_os.h" @@ -47,8 +47,6 @@ void APPE_Init() { ble_glue_status = BleGlueStatusStartup; SystemPower_Config(); /**< Configure the system Power Mode */ - HW_TS_Init(hw_ts_InitMode_Full, &hrtc); /**< Initialize the TimerServer */ - // APPD_Init(); furi_hal_power_insomnia_enter(); @@ -137,7 +135,7 @@ static void APPE_SysUserEvtRx( void * pPayload ) { /* Traces channel initialization */ // APPD_EnableCPU2( ); - if (APP_BLE_Init()) { + if(ble_app_init()) { FURI_LOG_I("Core2", "BLE stack started"); ble_glue_status = BleGlueStatusStarted; } else { diff --git a/firmware/targets/f7/ble-glue/battery_service.c b/firmware/targets/f7/ble-glue/battery_service.c index 654edd537e0..1dd8c5a0332 100644 --- a/firmware/targets/f7/ble-glue/battery_service.c +++ b/firmware/targets/f7/ble-glue/battery_service.c @@ -31,7 +31,7 @@ void battery_svc_start() { (Char_UUID_t *) &char_battery_level_uuid, 1, CHAR_PROP_READ | CHAR_PROP_NOTIFY, - ATTR_PERMISSION_NONE, + ATTR_PERMISSION_AUTHEN_READ, GATT_DONT_NOTIFY_EVENTS, 10, CHAR_VALUE_LEN_CONSTANT, diff --git a/firmware/targets/f7/ble-glue/ble_app.c b/firmware/targets/f7/ble-glue/ble_app.c new file mode 100644 index 00000000000..e28facd6dd5 --- /dev/null +++ b/firmware/targets/f7/ble-glue/ble_app.c @@ -0,0 +1,119 @@ +#include "ble_app.h" + +#include "hci_tl.h" +#include "ble.h" +#include "shci.h" +#include "cmsis_os.h" +#include "gap.h" + +#include + +#define BLE_APP_TAG "ble app" + +PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t ble_app_cmd_buffer; + +typedef struct { + osMutexId_t hci_mtx; + osSemaphoreId_t hci_sem; + osThreadId_t hci_thread_id; + osThreadAttr_t hci_thread_attr; +} BleApp; + +static BleApp* ble_app; + +static void ble_app_hci_thread(void *arg); +static void ble_app_hci_event_handler(void * pPayload); +static void ble_app_hci_status_not_handler(HCI_TL_CmdStatus_t status); + +bool ble_app_init() { + ble_app = furi_alloc(sizeof(BleApp)); + + // Allocate semafore and mutex for ble command buffer access + ble_app->hci_mtx = osMutexNew(NULL); + ble_app->hci_sem = osSemaphoreNew(1, 0, NULL); + // HCI transport layer thread to handle user asynch events + ble_app->hci_thread_attr.name = "ble hci"; + ble_app->hci_thread_attr.stack_size = 1024; + ble_app->hci_thread_id = osThreadNew(ble_app_hci_thread, NULL, &ble_app->hci_thread_attr); + + // Initialize Ble Transport Layer + HCI_TL_HciInitConf_t hci_tl_config = { + .p_cmdbuffer = (uint8_t*)&ble_app_cmd_buffer, + .StatusNotCallBack = ble_app_hci_status_not_handler, + }; + hci_init(ble_app_hci_event_handler, (void*)&hci_tl_config); + + // Start ble stack on 2nd core + SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = { + .Header = {{0,0,0}}, // Header unused + .Param = { + 0, // pBleBufferAddress not used + 0, // BleBufferSize not used + CFG_BLE_NUM_GATT_ATTRIBUTES, + CFG_BLE_NUM_GATT_SERVICES, + CFG_BLE_ATT_VALUE_ARRAY_SIZE, + CFG_BLE_NUM_LINK, + CFG_BLE_DATA_LENGTH_EXTENSION, + CFG_BLE_PREPARE_WRITE_LIST_SIZE, + CFG_BLE_MBLOCK_COUNT, + CFG_BLE_MAX_ATT_MTU, + CFG_BLE_SLAVE_SCA, + CFG_BLE_MASTER_SCA, + CFG_BLE_LSE_SOURCE, + CFG_BLE_MAX_CONN_EVENT_LENGTH, + CFG_BLE_HSE_STARTUP_TIME, + CFG_BLE_VITERBI_MODE, + CFG_BLE_LL_ONLY, + 0, + } + }; + SHCI_CmdStatus_t status = SHCI_C2_BLE_Init(&ble_init_cmd_packet); + if(status) { + FURI_LOG_E(BLE_APP_TAG, "Failed to start ble stack: %d", status); + } + return status == SHCI_Success; +} + +static void ble_app_hci_thread(void *arg) { + while(1) { + osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); + hci_user_evt_proc(); + } +} + +// Called by WPAN lib +void hci_notify_asynch_evt(void* pdata) { + osThreadFlagsSet(ble_app->hci_thread_id, 1); +} + +void hci_cmd_resp_release(uint32_t flag) { + osSemaphoreRelease(ble_app->hci_sem); +} + +void hci_cmd_resp_wait(uint32_t timeout) { + osSemaphoreAcquire(ble_app->hci_sem, osWaitForever); +} + +static void ble_app_hci_event_handler( void * pPayload ) { + SVCCTL_UserEvtFlowStatus_t svctl_return_status; + tHCI_UserEvtRxParam *pParam = (tHCI_UserEvtRxParam *)pPayload; + + svctl_return_status = SVCCTL_UserEvtRx((void *)&(pParam->pckt->evtserial)); + if (svctl_return_status != SVCCTL_UserEvtFlowDisable) { + pParam->status = HCI_TL_UserEventFlow_Enable; + } else { + pParam->status = HCI_TL_UserEventFlow_Disable; + } +} + +static void ble_app_hci_status_not_handler( HCI_TL_CmdStatus_t status ) { + if(status == HCI_TL_CmdBusy) { + osMutexAcquire(ble_app->hci_mtx, osWaitForever ); + } else if(status == HCI_TL_CmdAvailable) { + osMutexRelease(ble_app->hci_mtx); + } +} + +void SVCCTL_ResumeUserEventFlow( void ) { + hci_resume_flow(); +} diff --git a/firmware/targets/f7/ble-glue/app_ble.h b/firmware/targets/f7/ble-glue/ble_app.h similarity index 72% rename from firmware/targets/f7/ble-glue/app_ble.h rename to firmware/targets/f7/ble-glue/ble_app.h index 08c60fe30e2..17d8dc5f755 100644 --- a/firmware/targets/f7/ble-glue/app_ble.h +++ b/firmware/targets/f7/ble-glue/ble_app.h @@ -5,9 +5,8 @@ extern "C" { #endif #include -#include "hci_tl.h" -bool APP_BLE_Init(); +bool ble_app_init(); #ifdef __cplusplus } diff --git a/firmware/targets/f7/ble-glue/dev_info_service.c b/firmware/targets/f7/ble-glue/dev_info_service.c index db58226b3d3..ae07d9bcd18 100644 --- a/firmware/targets/f7/ble-glue/dev_info_service.c +++ b/firmware/targets/f7/ble-glue/dev_info_service.c @@ -39,7 +39,7 @@ void dev_info_svc_start() { (Char_UUID_t*)&uuid, strlen(dev_info_man_name), CHAR_PROP_READ, - ATTR_PERMISSION_NONE, + ATTR_PERMISSION_AUTHEN_READ, GATT_DONT_NOTIFY_EVENTS, 10, CHAR_VALUE_LEN_CONSTANT, @@ -53,7 +53,7 @@ void dev_info_svc_start() { (Char_UUID_t*)&uuid, strlen(dev_info_serial_num), CHAR_PROP_READ, - ATTR_PERMISSION_NONE, + ATTR_PERMISSION_AUTHEN_READ, GATT_DONT_NOTIFY_EVENTS, 10, CHAR_VALUE_LEN_CONSTANT, @@ -67,7 +67,7 @@ void dev_info_svc_start() { (Char_UUID_t*)&uuid, strlen(dev_info_firmware_rev_num), CHAR_PROP_READ, - ATTR_PERMISSION_NONE, + ATTR_PERMISSION_AUTHEN_READ, GATT_DONT_NOTIFY_EVENTS, 10, CHAR_VALUE_LEN_CONSTANT, @@ -81,7 +81,7 @@ void dev_info_svc_start() { (Char_UUID_t*)&uuid, strlen(dev_info_software_rev_num), CHAR_PROP_READ, - ATTR_PERMISSION_NONE, + ATTR_PERMISSION_AUTHEN_READ, GATT_DONT_NOTIFY_EVENTS, 10, CHAR_VALUE_LEN_CONSTANT, diff --git a/firmware/targets/f7/ble-glue/gap.c b/firmware/targets/f7/ble-glue/gap.c index 19d1b5f183b..74e1d35a3d6 100644 --- a/firmware/targets/f7/ble-glue/gap.c +++ b/firmware/targets/f7/ble-glue/gap.c @@ -31,13 +31,22 @@ typedef struct { typedef struct { GapSvc gap_svc; GapState state; + osMutexId_t state_mutex; uint8_t mac_address[BD_ADDR_SIZE_LOCAL]; Bt* bt; osTimerId advertise_timer; osThreadAttr_t thread_attr; osThreadId_t thread_id; + osMessageQueueId_t command_queue; + bool enable_adv; } Gap; +typedef enum { + GapCommandAdvFast, + GapCommandAdvLowPower, + GapCommandAdvStop, +} GapCommand; + // Identity root key static const uint8_t gap_irk[16] = {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0}; // Encryption root key @@ -49,150 +58,151 @@ static const uint8_t gap_default_mac_addr[] = {0x6c, 0x7a, 0xd8, 0xac, 0x57, 0x7 static Gap* gap = NULL; -static void gap_advertise(GapState new_state); +static void gap_advertise_start(GapState new_state); static void gap_app(void *arg); SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) { - hci_event_pckt *event_pckt; - evt_le_meta_event *meta_evt; - evt_blue_aci *blue_evt; - hci_le_phy_update_complete_event_rp0 *evt_le_phy_update_complete; - uint8_t tx_phy; - uint8_t rx_phy; - tBleStatus ret = BLE_STATUS_INVALID_PARAMS; - - event_pckt = (hci_event_pckt*) ((hci_uart_pckt *) pckt)->data; - - switch (event_pckt->evt) { - case EVT_DISCONN_COMPLETE: - { - hci_disconnection_complete_event_rp0 *disconnection_complete_event = (hci_disconnection_complete_event_rp0 *) event_pckt->data; - if (disconnection_complete_event->Connection_Handle == gap->gap_svc.connection_handle) { - gap->gap_svc.connection_handle = 0; - gap->state = GapStateIdle; - FURI_LOG_I(GAP_TAG, "Disconnect from client"); - } - // Restart advertising - gap_advertise(GapStateAdvFast); - furi_hal_power_insomnia_exit(); - } - break; - - case EVT_LE_META_EVENT: - meta_evt = (evt_le_meta_event*) event_pckt->data; - switch (meta_evt->subevent) { - case EVT_LE_CONN_UPDATE_COMPLETE: - FURI_LOG_D(GAP_TAG, "Connection update event"); - break; - - case EVT_LE_PHY_UPDATE_COMPLETE: - evt_le_phy_update_complete = (hci_le_phy_update_complete_event_rp0*)meta_evt->data; - if(evt_le_phy_update_complete->Status) { - FURI_LOG_E(GAP_TAG, "Update PHY failed, status %d", evt_le_phy_update_complete->Status); - } else { - FURI_LOG_I(GAP_TAG, "Update PHY succeed"); + hci_event_pckt *event_pckt; + evt_le_meta_event *meta_evt; + evt_blue_aci *blue_evt; + hci_le_phy_update_complete_event_rp0 *evt_le_phy_update_complete; + uint8_t tx_phy; + uint8_t rx_phy; + tBleStatus ret = BLE_STATUS_INVALID_PARAMS; + + event_pckt = (hci_event_pckt*) ((hci_uart_pckt *) pckt)->data; + + osMutexAcquire(gap->state_mutex, osWaitForever); + switch (event_pckt->evt) { + case EVT_DISCONN_COMPLETE: + { + hci_disconnection_complete_event_rp0 *disconnection_complete_event = (hci_disconnection_complete_event_rp0 *) event_pckt->data; + if (disconnection_complete_event->Connection_Handle == gap->gap_svc.connection_handle) { + gap->gap_svc.connection_handle = 0; + gap->state = GapStateIdle; + FURI_LOG_I(GAP_TAG, "Disconnect from client"); } - ret = hci_le_read_phy(gap->gap_svc.connection_handle,&tx_phy,&rx_phy); - if(ret) { - FURI_LOG_E(GAP_TAG, "Read PHY failed, status: %d", ret); - } else { - FURI_LOG_I(GAP_TAG, "PHY Params TX= %d, RX= %d ", tx_phy, rx_phy); + if(gap->enable_adv) { + // Restart advertising + gap_start_advertising(); + furi_hal_power_insomnia_exit(); } - break; - - case EVT_LE_CONN_COMPLETE: - furi_hal_power_insomnia_enter(); - hci_le_connection_complete_event_rp0* connection_complete_event = (hci_le_connection_complete_event_rp0 *) meta_evt->data; - FURI_LOG_I(GAP_TAG, "Connection complete for connection handle 0x%x", connection_complete_event->Connection_Handle); - - // Stop advertising as connection completed - osTimerStop(gap->advertise_timer); - - // Update connection status and handle - gap->state = GapStateConnected; - gap->gap_svc.connection_handle = connection_complete_event->Connection_Handle; - - // Start pairing by sending security request - aci_gap_slave_security_req(connection_complete_event->Connection_Handle); - break; - - default: - break; - } - break; - - case EVT_VENDOR: - blue_evt = (evt_blue_aci*) event_pckt->data; - switch (blue_evt->ecode) { - aci_gap_pairing_complete_event_rp0 *pairing_complete; - - case EVT_BLUE_GAP_LIMITED_DISCOVERABLE: - FURI_LOG_I(GAP_TAG, "Limited discoverable event"); - break; - - case EVT_BLUE_GAP_PASS_KEY_REQUEST: - { - // Generate random PIN code - uint32_t pin = rand() % 999999; - aci_gap_pass_key_resp(gap->gap_svc.connection_handle, pin); - FURI_LOG_I(GAP_TAG, "Pass key request event. Pin: %d", pin); - bt_pin_code_show(gap->bt, pin); } - break; - - case EVT_BLUE_GAP_AUTHORIZATION_REQUEST: - FURI_LOG_I(GAP_TAG, "Authorization request event"); - break; - - case EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED: - FURI_LOG_I(GAP_TAG, "Slave security initiated"); - break; - - case EVT_BLUE_GAP_BOND_LOST: - FURI_LOG_I(GAP_TAG, "Bond lost event. Start rebonding"); - aci_gap_allow_rebond(gap->gap_svc.connection_handle); - break; - - case EVT_BLUE_GAP_DEVICE_FOUND: - FURI_LOG_I(GAP_TAG, "Device found event"); - break; - - case EVT_BLUE_GAP_ADDR_NOT_RESOLVED: - FURI_LOG_I(GAP_TAG, "Address not resolved event"); - break; - - case EVT_BLUE_GAP_KEYPRESS_NOTIFICATION: - FURI_LOG_I(GAP_TAG, "Key press notification event"); - break; - - case EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE: - FURI_LOG_I(GAP_TAG, "Hex_value = %lx", - ((aci_gap_numeric_comparison_value_event_rp0 *)(blue_evt->data))->Numeric_Value); - aci_gap_numeric_comparison_value_confirm_yesno(gap->gap_svc.connection_handle, 1); - break; - - case (EVT_BLUE_GAP_PAIRING_CMPLT): - { - pairing_complete = (aci_gap_pairing_complete_event_rp0*)blue_evt->data; - if (pairing_complete->Status) { - FURI_LOG_E(GAP_TAG, "Pairing failed with status: %d. Terminating connection", pairing_complete->Status); - aci_gap_terminate(gap->gap_svc.connection_handle, 5); - } else { - FURI_LOG_I(GAP_TAG, "Pairing complete"); + break; + + case EVT_LE_META_EVENT: + meta_evt = (evt_le_meta_event*) event_pckt->data; + switch (meta_evt->subevent) { + case EVT_LE_CONN_UPDATE_COMPLETE: + FURI_LOG_D(GAP_TAG, "Connection update event"); + break; + + case EVT_LE_PHY_UPDATE_COMPLETE: + evt_le_phy_update_complete = (hci_le_phy_update_complete_event_rp0*)meta_evt->data; + if(evt_le_phy_update_complete->Status) { + FURI_LOG_E(GAP_TAG, "Update PHY failed, status %d", evt_le_phy_update_complete->Status); + } else { + FURI_LOG_I(GAP_TAG, "Update PHY succeed"); + } + ret = hci_le_read_phy(gap->gap_svc.connection_handle,&tx_phy,&rx_phy); + if(ret) { + FURI_LOG_E(GAP_TAG, "Read PHY failed, status: %d", ret); + } else { + FURI_LOG_I(GAP_TAG, "PHY Params TX = %d, RX = %d ", tx_phy, rx_phy); + } + break; + + case EVT_LE_CONN_COMPLETE: + furi_hal_power_insomnia_enter(); + hci_le_connection_complete_event_rp0* connection_complete_event = (hci_le_connection_complete_event_rp0 *) meta_evt->data; + FURI_LOG_I(GAP_TAG, "Connection complete for connection handle 0x%x", connection_complete_event->Connection_Handle); + + // Stop advertising as connection completed + osTimerStop(gap->advertise_timer); + + // Update connection status and handle + gap->state = GapStateConnected; + gap->gap_svc.connection_handle = connection_complete_event->Connection_Handle; + + // Start pairing by sending security request + aci_gap_slave_security_req(connection_complete_event->Connection_Handle); + break; + + default: + break; } - } - break; - - case EVT_BLUE_GAP_PROCEDURE_COMPLETE: - FURI_LOG_I(GAP_TAG, "Procedure complete event"); - break; - } - default: - break; - } - - return SVCCTL_UserEvtFlowEnable; + break; + + case EVT_VENDOR: + blue_evt = (evt_blue_aci*) event_pckt->data; + switch (blue_evt->ecode) { + aci_gap_pairing_complete_event_rp0 *pairing_complete; + + case EVT_BLUE_GAP_LIMITED_DISCOVERABLE: + FURI_LOG_I(GAP_TAG, "Limited discoverable event"); + break; + + case EVT_BLUE_GAP_PASS_KEY_REQUEST: + { + // Generate random PIN code + uint32_t pin = rand() % 999999; + aci_gap_pass_key_resp(gap->gap_svc.connection_handle, pin); + FURI_LOG_I(GAP_TAG, "Pass key request event. Pin: %d", pin); + bt_pin_code_show(gap->bt, pin); + } + break; + + case EVT_BLUE_GAP_AUTHORIZATION_REQUEST: + FURI_LOG_I(GAP_TAG, "Authorization request event"); + break; + + case EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED: + FURI_LOG_I(GAP_TAG, "Slave security initiated"); + break; + + case EVT_BLUE_GAP_BOND_LOST: + FURI_LOG_I(GAP_TAG, "Bond lost event. Start rebonding"); + aci_gap_allow_rebond(gap->gap_svc.connection_handle); + break; + + case EVT_BLUE_GAP_DEVICE_FOUND: + FURI_LOG_I(GAP_TAG, "Device found event"); + break; + + case EVT_BLUE_GAP_ADDR_NOT_RESOLVED: + FURI_LOG_I(GAP_TAG, "Address not resolved event"); + break; + + case EVT_BLUE_GAP_KEYPRESS_NOTIFICATION: + FURI_LOG_I(GAP_TAG, "Key press notification event"); + break; + + case EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE: + FURI_LOG_I(GAP_TAG, "Hex_value = %lx", + ((aci_gap_numeric_comparison_value_event_rp0 *)(blue_evt->data))->Numeric_Value); + aci_gap_numeric_comparison_value_confirm_yesno(gap->gap_svc.connection_handle, 1); + break; + + case EVT_BLUE_GAP_PAIRING_CMPLT: + pairing_complete = (aci_gap_pairing_complete_event_rp0*)blue_evt->data; + if (pairing_complete->Status) { + FURI_LOG_E(GAP_TAG, "Pairing failed with status: %d. Terminating connection", pairing_complete->Status); + aci_gap_terminate(gap->gap_svc.connection_handle, 5); + } else { + FURI_LOG_I(GAP_TAG, "Pairing complete"); + } + break; + + case EVT_BLUE_GAP_PROCEDURE_COMPLETE: + FURI_LOG_I(GAP_TAG, "Procedure complete event"); + break; + } + default: + break; + } + osMutexRelease(gap->state_mutex); + return SVCCTL_UserEvtFlowEnable; } void SVCCTL_SvcInit() { @@ -213,7 +223,7 @@ static void set_advertisment_service_uid(uint8_t* uid, uint8_t uid_len) { gap->gap_svc.adv_svc_uuid_len += uid_len; } -GapState gap_get_status() { +GapState gap_get_state() { return gap->state; } @@ -293,7 +303,7 @@ static void gap_init_svc(Gap* gap) { aci_gap_configure_whitelist(); } -static void gap_advertise(GapState new_state) +static void gap_advertise_start(GapState new_state) { tBleStatus status; uint16_t min_interval; @@ -317,7 +327,6 @@ static void gap_advertise(GapState new_state) } } // Configure advertising - gap->state = new_state; const char* name = furi_hal_version_get_ble_local_device_name_ptr(); status = aci_gap_set_discoverable(ADV_IND, min_interval, max_interval, PUBLIC_ADDR, 0, strlen(name), (uint8_t*)name, @@ -325,17 +334,40 @@ static void gap_advertise(GapState new_state) if(status) { FURI_LOG_E(GAP_TAG, "Set discoverable err: %d", status); } + gap->state = new_state; + bt_update_statusbar(gap->bt); osTimerStart(gap->advertise_timer, INITIAL_ADV_TIMEOUT); } -static void gap_advertise_request(Gap* gap) { - osThreadFlagsSet(gap->thread_id, 1); +static void gap_advertise_stop() { + if(gap->state == GapStateConnected) { + // Terminate connection + aci_gap_terminate(gap->gap_svc.connection_handle, 0x13); + } + if(gap->state > GapStateIdle) { + // Stop advertising + osTimerStop(gap->advertise_timer); + aci_gap_set_non_discoverable(); + gap->state = GapStateIdle; + bt_update_statusbar(gap->bt); + } +} + +void gap_start_advertising() { + gap->enable_adv = true; + GapCommand command = GapCommandAdvFast; + furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); +} + +void gap_stop_advertising() { + gap->enable_adv = false; + GapCommand command = GapCommandAdvStop; + furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); } static void gap_advetise_timer_callback(void* context) { - furi_assert(context); - Gap* gap = context; - gap_advertise_request(gap); + GapCommand command = GapCommandAdvLowPower; + furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); } bool gap_init() { @@ -348,20 +380,25 @@ bool gap_init() { // Open Bt record gap->bt = furi_record_open("bt"); // Create advertising timer - gap->advertise_timer = osTimerNew(gap_advetise_timer_callback, osTimerOnce, &gap, NULL); - // Initialization of HCI & GATT & GAP layer + gap->advertise_timer = osTimerNew(gap_advetise_timer_callback, osTimerOnce, NULL, NULL); + // Initialization of GATT & GAP layer gap_init_svc(gap); // Initialization of the BLE Services SVCCTL_Init(); - // Initialization of the BLE App Context + // Initialization of the GAP state + gap->state_mutex = osMutexNew(NULL); gap->state = GapStateIdle; gap->gap_svc.connection_handle = 0xFFFF; + gap->enable_adv = true; // Thread configuration gap->thread_attr.name = "BLE advertising"; - gap->thread_attr.stack_size = 512; + gap->thread_attr.stack_size = 1024; gap->thread_id = osThreadNew(gap_app, NULL, &gap->thread_attr); + // Command queue allocation + gap->command_queue = osMessageQueueNew(8, sizeof(GapCommand), NULL); + // Start Device Information service dev_info_svc_start(); // Start Battery service @@ -374,14 +411,21 @@ bool gap_init() { adv_service_uid[1] = 0x30; set_advertisment_service_uid(adv_service_uid, sizeof(adv_service_uid)); - gap_advertise(GapStateAdvFast); return true; } static void gap_app(void *arg) { - // TODO Exit from app, stop service, clean memory + GapCommand command; while(1) { - osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); - gap_advertise(GapStateAdvLowPower); + furi_check(osMessageQueueGet(gap->command_queue, &command, NULL, osWaitForever) == osOK); + osMutexAcquire(gap->state_mutex, osWaitForever); + if(command == GapCommandAdvFast) { + gap_advertise_start(GapStateAdvFast); + } else if(command == GapCommandAdvLowPower) { + gap_advertise_start(GapStateAdvLowPower); + } else if(command == GapCommandAdvStop) { + gap_advertise_stop(); + } + osMutexRelease(gap->state_mutex); } } diff --git a/firmware/targets/f7/ble-glue/gap.h b/firmware/targets/f7/ble-glue/gap.h index 3fc2cf4cbb5..93e75122b46 100644 --- a/firmware/targets/f7/ble-glue/gap.h +++ b/firmware/targets/f7/ble-glue/gap.h @@ -15,7 +15,11 @@ typedef enum { bool gap_init(); -GapState gap_get_status(); +void gap_start_advertising(); + +void gap_stop_advertising(); + +GapState gap_get_state(); #ifdef __cplusplus } diff --git a/firmware/targets/f7/ble-glue/serial_service.c b/firmware/targets/f7/ble-glue/serial_service.c index eae2c275f1d..e5ab9d2d7a9 100644 --- a/firmware/targets/f7/ble-glue/serial_service.c +++ b/firmware/targets/f7/ble-glue/serial_service.c @@ -61,7 +61,7 @@ void serial_svc_start() { status = aci_gatt_add_char(serial_svc->svc_handle, UUID_TYPE_128, (const Char_UUID_t*)char_tx_uuid, SERIAL_SVC_DATA_LEN_MAX, CHAR_PROP_WRITE_WITHOUT_RESP | CHAR_PROP_WRITE | CHAR_PROP_READ, - ATTR_PERMISSION_NONE, + ATTR_PERMISSION_AUTHEN_READ | ATTR_PERMISSION_AUTHEN_WRITE, GATT_NOTIFY_ATTRIBUTE_WRITE, 10, CHAR_VALUE_LEN_VARIABLE, @@ -74,7 +74,7 @@ void serial_svc_start() { status = aci_gatt_add_char(serial_svc->svc_handle, UUID_TYPE_128, (const Char_UUID_t*)char_rx_uuid, SERIAL_SVC_DATA_LEN_MAX, CHAR_PROP_READ | CHAR_PROP_INDICATE, - ATTR_PERMISSION_NONE, + ATTR_PERMISSION_AUTHEN_READ, GATT_DONT_NOTIFY_EVENTS, 10, CHAR_VALUE_LEN_VARIABLE, @@ -108,13 +108,15 @@ void serial_svc_stop() { bool serial_svc_update_rx(uint8_t* data, uint8_t data_len) { - furi_assert(data_len < SERIAL_SVC_DATA_LEN_MAX); + if(data_len > SERIAL_SVC_DATA_LEN_MAX) { + return false; + } tBleStatus result = aci_gatt_update_char_value(serial_svc->svc_handle, - serial_svc->rx_char_handle, - 0, - data_len, - data); + serial_svc->rx_char_handle, + 0, + data_len, + data); if(result) { FURI_LOG_E(SERIAL_SERVICE_TAG, "Failed updating RX characteristic: %d", result); } diff --git a/firmware/targets/f7/furi-hal/furi-hal-bt.c b/firmware/targets/f7/furi-hal/furi-hal-bt.c index 4d5e0674d5b..7fab63edd3f 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-bt.c +++ b/firmware/targets/f7/furi-hal/furi-hal-bt.c @@ -4,7 +4,6 @@ #include #include #include -#include #include void furi_hal_bt_init() { @@ -14,10 +13,22 @@ void furi_hal_bt_init() { APPE_Init(); } -bool furi_hal_bt_start_app() { +bool furi_hal_bt_init_app() { return gap_init(); } +void furi_hal_bt_start_advertising() { + if(gap_get_state() == GapStateIdle) { + gap_start_advertising(); + } +} + +void furi_hal_bt_stop_advertising() { + if(furi_hal_bt_is_active()) { + gap_stop_advertising(); + } +} + void furi_hal_bt_dump_state(string_t buffer) { BleGlueStatus status = APPE_Status(); if (status == BleGlueStatusStarted) { @@ -41,7 +52,12 @@ void furi_hal_bt_dump_state(string_t buffer) { } bool furi_hal_bt_is_alive() { - return APPE_Status() == BleGlueStatusStarted; + BleGlueStatus status = APPE_Status(); + return (status == BleGlueStatusBroken) || (status == BleGlueStatusStarted); +} + +bool furi_hal_bt_is_active() { + return gap_get_state() > GapStateIdle; } bool furi_hal_bt_wait_startup() { @@ -56,7 +72,7 @@ bool furi_hal_bt_wait_startup() { return true; } -bool furi_hal_bt_lock_flash() { +bool furi_hal_bt_lock_flash(bool erase_flag) { if (!furi_hal_bt_wait_startup()) { return false; } @@ -64,18 +80,25 @@ bool furi_hal_bt_lock_flash() { while (HAL_HSEM_FastTake(CFG_HW_FLASH_SEMID) != HAL_OK) { osDelay(1); } - - SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON); + HAL_FLASH_Unlock(); - while(LL_FLASH_IsOperationSuspended()) {}; + if(erase_flag) SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON); + + while(LL_FLASH_IsActiveFlag_OperationSuspended()) {}; + + __disable_irq(); return true; } -void furi_hal_bt_unlock_flash() { - SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF); +void furi_hal_bt_unlock_flash(bool erase_flag) { + __enable_irq(); + + if(erase_flag) SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF); + HAL_FLASH_Lock(); + HAL_HSEM_Release(CFG_HW_FLASH_SEMID, HSEM_CPU1_COREID); } diff --git a/firmware/targets/f7/furi-hal/furi-hal-clock.c b/firmware/targets/f7/furi-hal/furi-hal-clock.c index 0ed918e3dc3..2544c769a59 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-clock.c +++ b/firmware/targets/f7/furi-hal/furi-hal-clock.c @@ -1,6 +1,6 @@ #include +#include -#include #include #include #include @@ -107,6 +107,12 @@ void furi_hal_clock_init() { LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOE); LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH); LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_AES1); + + // AHB3 + LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_PKA); + LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_RNG); + LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_AES2); // APB1 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB); @@ -114,6 +120,8 @@ void furi_hal_clock_init() { // APB2 LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); + + FURI_LOG_I("FuriHalClock", "Init OK"); } void furi_hal_clock_switch_to_hsi() { diff --git a/firmware/targets/f7/furi-hal/furi-hal-crypto.c b/firmware/targets/f7/furi-hal/furi-hal-crypto.c new file mode 100644 index 00000000000..3e4ec98fd06 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-crypto.c @@ -0,0 +1,75 @@ +#include +#include +#include + +CRYP_HandleTypeDef crypt; + +void furi_hal_crypto_init() { + FURI_LOG_I("FuriHalCrypto", "Init OK"); +} + +bool furi_hal_crypto_store_add_key(FuriHalCryptoKey* key, uint8_t* slot) { + furi_assert(key); + furi_assert(slot); + + SHCI_C2_FUS_StoreUsrKey_Cmd_Param_t pParam; + size_t key_data_size = 0; + + if (key->type == FuriHalCryptoKeyTypeMaster) { + pParam.KeyType = KEYTYPE_MASTER; + } else if (key->type == FuriHalCryptoKeyTypeSimple) { + pParam.KeyType = KEYTYPE_SIMPLE; + } else if (key->type == FuriHalCryptoKeyTypeEncrypted) { + pParam.KeyType = KEYTYPE_ENCRYPTED; + key_data_size += 12; + } else { + furi_crash("Incorrect key type"); + } + + if (key->size == FuriHalCryptoKeySize128) { + pParam.KeySize = KEYSIZE_16; + key_data_size += 16; + } else if (key->size == FuriHalCryptoKeySize256) { + pParam.KeySize = KEYSIZE_32; + key_data_size += 32; + } else { + furi_crash("Incorrect key size"); + } + + memcpy(pParam.KeyData, key->data, key_data_size); + + return SHCI_C2_FUS_StoreUsrKey(&pParam, slot) == SHCI_Success; +} + +bool furi_hal_crypto_store_load_key(uint8_t slot, const uint8_t* iv) { + furi_assert(slot > 0 && slot <= 100); + + crypt.Instance = AES1; + crypt.Init.DataType = CRYP_DATATYPE_32B; + crypt.Init.KeySize = CRYP_KEYSIZE_256B; + crypt.Init.Algorithm = CRYP_AES_CBC; + crypt.Init.pInitVect = (uint32_t*)iv; + crypt.Init.pKey = NULL; + + furi_check(HAL_CRYP_Init(&crypt) == HAL_OK); + + if (SHCI_C2_FUS_LoadUsrKey(slot) == SHCI_Success) { + return true; + } else { + furi_check(HAL_CRYP_DeInit(&crypt) == HAL_OK); + return false; + } +} + +bool furi_hal_crypto_store_unload_key(uint8_t slot) { + furi_check(HAL_CRYP_DeInit(&crypt) == HAL_OK); + return SHCI_C2_FUS_UnloadUsrKey(slot) == SHCI_Success; +} + +bool furi_hal_crypto_encrypt(const uint8_t *input, uint8_t *output, size_t size) { + return HAL_CRYP_Encrypt(&crypt, (uint32_t*)input, size/4, (uint32_t*)output, 1000) == HAL_OK; +} + +bool furi_hal_crypto_decrypt(const uint8_t *input, uint8_t *output, size_t size) { + return HAL_CRYP_Decrypt(&crypt, (uint32_t*)input, size/4, (uint32_t*)output, 1000) == HAL_OK; +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-flash.c b/firmware/targets/f7/furi-hal/furi-hal-flash.c index 5346965fd30..c9922122ef3 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-flash.c +++ b/firmware/targets/f7/furi-hal/furi-hal-flash.c @@ -57,7 +57,7 @@ size_t furi_hal_flash_get_free_page_count() { } bool furi_hal_flash_erase(uint8_t page, uint8_t count) { - if (!furi_hal_bt_lock_flash()) { + if (!furi_hal_bt_lock_flash(true)) { return false; } FLASH_EraseInitTypeDef erase; @@ -66,24 +66,24 @@ bool furi_hal_flash_erase(uint8_t page, uint8_t count) { erase.NbPages = count; uint32_t error; HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase, &error); - furi_hal_bt_unlock_flash(); + furi_hal_bt_unlock_flash(true); return status == HAL_OK; } bool furi_hal_flash_write_dword(size_t address, uint64_t data) { - if (!furi_hal_bt_lock_flash()) { + if (!furi_hal_bt_lock_flash(false)) { return false; } HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data); - furi_hal_bt_unlock_flash(); + furi_hal_bt_unlock_flash(false); return status == HAL_OK; } bool furi_hal_flash_write_dword_from(size_t address, size_t source_address) { - if (!furi_hal_bt_lock_flash()) { + if (!furi_hal_bt_lock_flash(false)) { return false; } HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FAST, address, source_address); - furi_hal_bt_unlock_flash(); + furi_hal_bt_unlock_flash(false); return status == HAL_OK; } diff --git a/firmware/targets/f7/furi-hal/furi-hal-interrupt.c b/firmware/targets/f7/furi-hal/furi-hal-interrupt.c index 69cdc4b6994..47e99c9f33e 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-interrupt.c +++ b/firmware/targets/f7/furi-hal/furi-hal-interrupt.c @@ -41,7 +41,7 @@ void furi_hal_interrupt_set_timer_isr(TIM_TypeDef* timer, FuriHalInterruptISR is } furi_hal_tim_tim1_isr = isr; } else { - furi_check(0); + furi_crash(NULL); } } @@ -54,7 +54,7 @@ void furi_hal_interrupt_set_dma_channel_isr(DMA_TypeDef* dma, uint32_t channel, } else if (dma == DMA2) { furi_hal_dma_channel_isr[1][channel] = isr; } else { - furi_check(0); + furi_crash(NULL); } } diff --git a/firmware/targets/f7/furi-hal/furi-hal-irda.c b/firmware/targets/f7/furi-hal/furi-hal-irda.c index a148b44a016..503a36537a8 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-irda.c +++ b/firmware/targets/f7/furi-hal/furi-hal-irda.c @@ -244,7 +244,7 @@ static uint8_t furi_hal_irda_get_current_dma_tx_buffer(void) { static void furi_hal_irda_tx_dma_polarity_isr() { if (LL_DMA_IsActiveFlag_TE1(DMA1)) { LL_DMA_ClearFlag_TE1(DMA1); - furi_check(0); + furi_crash(NULL); } if (LL_DMA_IsActiveFlag_TC1(DMA1) && LL_DMA_IsEnabledIT_TC(DMA1, LL_DMA_CHANNEL_1)) { LL_DMA_ClearFlag_TC1(DMA1); @@ -261,7 +261,7 @@ static void furi_hal_irda_tx_dma_polarity_isr() { static void furi_hal_irda_tx_dma_isr() { if (LL_DMA_IsActiveFlag_TE2(DMA1)) { LL_DMA_ClearFlag_TE2(DMA1); - furi_check(0); + furi_crash(NULL); } if (LL_DMA_IsActiveFlag_HT2(DMA1) && LL_DMA_IsEnabledIT_HT(DMA1, LL_DMA_CHANNEL_2)) { LL_DMA_ClearFlag_HT2(DMA1); @@ -277,7 +277,7 @@ static void furi_hal_irda_tx_dma_isr() { } else if (furi_hal_irda_state == IrdaStateAsyncTxStopReq) { /* fallthrough */ } else { - furi_check(0); + furi_crash(NULL); } } if (LL_DMA_IsActiveFlag_TC2(DMA1) && LL_DMA_IsEnabledIT_TC(DMA1, LL_DMA_CHANNEL_2)) { @@ -557,7 +557,7 @@ static void furi_hal_irda_async_tx_free_resources(void) { void furi_hal_irda_async_tx_start(uint32_t freq, float duty_cycle) { if ((duty_cycle > 1) || (duty_cycle <= 0) || (freq > IRDA_MAX_FREQUENCY) || (freq < IRDA_MIN_FREQUENCY) || (irda_tim_tx.data_callback == NULL)) { - furi_check(0); + furi_crash(NULL); } furi_assert(furi_hal_irda_state == IrdaStateIdle); diff --git a/firmware/targets/f7/furi-hal/furi-hal-rfid.c b/firmware/targets/f7/furi-hal/furi-hal-rfid.c index b4ec96fc00f..2a968b7a772 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-rfid.c +++ b/firmware/targets/f7/furi-hal/furi-hal-rfid.c @@ -261,7 +261,7 @@ void furi_hal_rfid_set_emulate_pulse(uint32_t pulse) { LFRFID_EMULATE_TIM.Instance->CCR4 = pulse; break; default: - furi_check(0); + furi_crash(NULL); break; } } @@ -285,7 +285,7 @@ void furi_hal_rfid_set_read_pulse(uint32_t pulse) { LFRFID_TIM.Instance->CCR4 = pulse; break; default: - furi_check(0); + furi_crash(NULL); break; } } diff --git a/firmware/targets/f7/furi-hal/furi-hal-subghz.c b/firmware/targets/f7/furi-hal/furi-hal-subghz.c index 679eea74055..7e8c12cdc40 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f7/furi-hal/furi-hal-subghz.c @@ -15,166 +15,174 @@ static const uint8_t furi_hal_subghz_preset_ook_270khz_async_regs[][2] = { // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration /* GPIO GD0 */ - { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input /* FIFO and internals */ - { CC1101_FIFOTHR, 0x47 }, // The only important bit is ADC_RETENTION, FIFO Tx=33 Rx=32 + {CC1101_FIFOTHR, 0x47}, // The only important bit is ADC_RETENTION, FIFO Tx=33 Rx=32 /* Packet engine */ - { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + {CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening /* Frequency Synthesizer Control */ - { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz // Modem Configuration - { CC1101_MDMCFG0, 0x00 }, // Channel spacing is 25kHz - { CC1101_MDMCFG1, 0x00 }, // Channel spacing is 25kHz - { CC1101_MDMCFG2, 0x30 }, // Format ASK/OOK, No preamble/sync - { CC1101_MDMCFG3, 0x32 }, // Data rate is 3.79372 kBaud - { CC1101_MDMCFG4, 0x67 }, // Rx BW filter is 270.833333kHz + {CC1101_MDMCFG0, 0x00}, // Channel spacing is 25kHz + {CC1101_MDMCFG1, 0x00}, // Channel spacing is 25kHz + {CC1101_MDMCFG2, 0x30}, // Format ASK/OOK, No preamble/sync + {CC1101_MDMCFG3, 0x32}, // Data rate is 3.79372 kBaud + {CC1101_MDMCFG4, 0x67}, // Rx BW filter is 270.833333kHz /* Main Radio Control State Machine */ - { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) /* Frequency Offset Compensation Configuration */ - { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + {CC1101_FOCCFG, + 0x18}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off /* Automatic Gain Control */ - { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary - { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET - { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + {CC1101_AGCTRL0, + 0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + {CC1101_AGCTRL1, + 0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + {CC1101_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB /* Wake on radio and timeouts control */ - { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + {CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours /* Frontend configuration */ - { CC1101_FREND0, 0x11 }, // Adjusts current TX LO buffer + high is PATABLE[1] - { CC1101_FREND1, 0xB6 }, // + {CC1101_FREND0, 0x11}, // Adjusts current TX LO buffer + high is PATABLE[1] + {CC1101_FREND1, 0xB6}, // /* Frequency Synthesizer Calibration, valid for 433.92 */ - { CC1101_FSCAL3, 0xE9 }, - { CC1101_FSCAL2, 0x2A }, - { CC1101_FSCAL1, 0x00 }, - { CC1101_FSCAL0, 0x1F }, + {CC1101_FSCAL3, 0xE9}, + {CC1101_FSCAL2, 0x2A}, + {CC1101_FSCAL1, 0x00}, + {CC1101_FSCAL0, 0x1F}, /* Magic f4ckery */ - { CC1101_TEST2, 0x81 }, // FIFOTHR ADC_RETENTION=1 matched value - { CC1101_TEST1, 0x35 }, // FIFOTHR ADC_RETENTION=1 matched value - { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + {CC1101_TEST2, 0x81}, // FIFOTHR ADC_RETENTION=1 matched value + {CC1101_TEST1, 0x35}, // FIFOTHR ADC_RETENTION=1 matched value + {CC1101_TEST0, 0x09}, // VCO selection calibration stage is disabled /* End */ - { 0, 0 }, + {0, 0}, }; static const uint8_t furi_hal_subghz_preset_ook_650khz_async_regs[][2] = { // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration /* GPIO GD0 */ - { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input /* FIFO and internals */ - { CC1101_FIFOTHR, 0x07 }, // The only important bit is ADC_RETENTION + {CC1101_FIFOTHR, 0x07}, // The only important bit is ADC_RETENTION /* Packet engine */ - { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + {CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening /* Frequency Synthesizer Control */ - { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz // Modem Configuration - { CC1101_MDMCFG0, 0x00 }, // Channel spacing is 25kHz - { CC1101_MDMCFG1, 0x00 }, // Channel spacing is 25kHz - { CC1101_MDMCFG2, 0x30 }, // Format ASK/OOK, No preamble/sync - { CC1101_MDMCFG3, 0x32 }, // Data rate is 3.79372 kBaud - { CC1101_MDMCFG4, 0x17 }, // Rx BW filter is 650.000kHz - + {CC1101_MDMCFG0, 0x00}, // Channel spacing is 25kHz + {CC1101_MDMCFG1, 0x00}, // Channel spacing is 25kHz + {CC1101_MDMCFG2, 0x30}, // Format ASK/OOK, No preamble/sync + {CC1101_MDMCFG3, 0x32}, // Data rate is 3.79372 kBaud + {CC1101_MDMCFG4, 0x17}, // Rx BW filter is 650.000kHz + /* Main Radio Control State Machine */ - { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) /* Frequency Offset Compensation Configuration */ - { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + {CC1101_FOCCFG, + 0x18}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off /* Automatic Gain Control */ - { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary - { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET - { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + {CC1101_AGCTRL0, + 0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + {CC1101_AGCTRL1, + 0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + {CC1101_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB /* Wake on radio and timeouts control */ - { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + {CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours /* Frontend configuration */ - { CC1101_FREND0, 0x11 }, // Adjusts current TX LO buffer + high is PATABLE[1] - { CC1101_FREND1, 0xB6 }, // + {CC1101_FREND0, 0x11}, // Adjusts current TX LO buffer + high is PATABLE[1] + {CC1101_FREND1, 0xB6}, // /* Frequency Synthesizer Calibration, valid for 433.92 */ - { CC1101_FSCAL3, 0xE9 }, - { CC1101_FSCAL2, 0x2A }, - { CC1101_FSCAL1, 0x00 }, - { CC1101_FSCAL0, 0x1F }, + {CC1101_FSCAL3, 0xE9}, + {CC1101_FSCAL2, 0x2A}, + {CC1101_FSCAL1, 0x00}, + {CC1101_FSCAL0, 0x1F}, /* Magic f4ckery */ - { CC1101_TEST2, 0x88 }, - { CC1101_TEST1, 0x31 }, - { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + {CC1101_TEST2, 0x88}, + {CC1101_TEST1, 0x31}, + {CC1101_TEST0, 0x09}, // VCO selection calibration stage is disabled /* End */ - { 0, 0 }, + {0, 0}, }; static const uint8_t furi_hal_subghz_preset_2fsk_async_regs[][2] = { - // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration /* GPIO GD0 */ - { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input /* FIFO and internals */ - { CC1101_FIFOTHR, 0x47 }, // The only important bit is ADC_RETENTION + {CC1101_FIFOTHR, 0x47}, // The only important bit is ADC_RETENTION /* Packet engine */ - { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + {CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening /* Frequency Synthesizer Control */ - { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz // Modem Configuration - { CC1101_MDMCFG0, 0xF8 }, - { CC1101_MDMCFG1, 0x00 }, // No preamble/sync - { CC1101_MDMCFG2, 0x80 }, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized) - { CC1101_MDMCFG3, 0x83 }, // Data rate is 9.59587 kBaud - { CC1101_MDMCFG4, 0x88 }, // Rx BW filter is 203.125000kHz + {CC1101_MDMCFG0, 0x00}, + {CC1101_MDMCFG1, 0x02}, + {CC1101_MDMCFG2, 0x04}, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized) + {CC1101_MDMCFG3, 0x8B}, // Data rate is 19.5885 kBaud + {CC1101_MDMCFG4, 0x69}, // Rx BW filter is 270.833333 kHz - { CC1101_DEVIATN, 0x14}, //Deviation 4.760742 khz + {CC1101_DEVIATN, 0x47}, //Deviation 47.607422 khz /* Main Radio Control State Machine */ - { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) /* Frequency Offset Compensation Configuration */ - { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + {CC1101_FOCCFG, + 0x16}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off /* Automatic Gain Control */ - { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary - { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET - { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + {CC1101_AGCTRL0, + 0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + {CC1101_AGCTRL1, + 0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + {CC1101_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB /* Wake on radio and timeouts control */ - { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + {CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours /* Frontend configuration */ - { CC1101_FREND0, 0x10 }, // Adjusts current TX LO buffer - { CC1101_FREND1, 0xB6 }, // + {CC1101_FREND0, 0x10}, // Adjusts current TX LO buffer + {CC1101_FREND1, 0xB6}, // /* Frequency Synthesizer Calibration, valid for 433.92 */ - { CC1101_FSCAL3, 0xE9 }, - { CC1101_FSCAL2, 0x2A }, - { CC1101_FSCAL1, 0x00 }, - { CC1101_FSCAL0, 0x1F }, + {CC1101_FSCAL3, 0xE9}, + {CC1101_FSCAL2, 0x2A}, + {CC1101_FSCAL1, 0x00}, + {CC1101_FSCAL0, 0x1F}, /* Magic f4ckery */ - { CC1101_TEST2, 0x81 }, // FIFOTHR ADC_RETENTION=1 matched value - { CC1101_TEST1, 0x35 }, // FIFOTHR ADC_RETENTION=1 matched value - { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + {CC1101_TEST2, 0x81}, // FIFOTHR ADC_RETENTION=1 matched value + {CC1101_TEST1, 0x35}, // FIFOTHR ADC_RETENTION=1 matched value + {CC1101_TEST0, 0x09}, // VCO selection calibration stage is disabled /* End */ - { 0, 0 }, + {0, 0}, }; static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = { 0x00, @@ -184,8 +192,7 @@ static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = { 0x00, 0x00, 0x00, - 0x00 -}; + 0x00}; static const uint8_t furi_hal_subghz_preset_2fsk_async_patable[8] = { 0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12 0x00, @@ -194,8 +201,7 @@ static const uint8_t furi_hal_subghz_preset_2fsk_async_patable[8] = { 0x00, 0x00, 0x00, - 0x00 -}; + 0x00}; void furi_hal_subghz_init() { furi_assert(furi_hal_subghz_state == SubGhzStateInit); @@ -217,11 +223,13 @@ void furi_hal_subghz_init() { // GD0 low cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW); - while(hal_gpio_read(&gpio_cc1101_g0) != false); + while(hal_gpio_read(&gpio_cc1101_g0) != false) + ; // GD0 high cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); - while(hal_gpio_read(&gpio_cc1101_g0) != true); + while(hal_gpio_read(&gpio_cc1101_g0) != true) + ; // Reset GD0 to floating state cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); @@ -257,8 +265,7 @@ void furi_hal_subghz_dump_state() { printf( "[furi_hal_subghz] cc1101 chip %d, version %d\r\n", cc1101_get_partnumber(device), - cc1101_get_version(device) - ); + cc1101_get_version(device)); furi_hal_spi_device_return(device); } @@ -266,14 +273,14 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { if(preset == FuriHalSubGhzPresetOok650Async) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_ook_650khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable); - } else if(preset == FuriHalSubGhzPresetOok270Async){ + } else if(preset == FuriHalSubGhzPresetOok270Async) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_ook_270khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable); - } else if(preset == FuriHalSubGhzPreset2FSKAsync){ + } else if(preset == FuriHalSubGhzPreset2FSKAsync) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_2fsk_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_2fsk_async_patable); }else { - furi_check(0); + furi_crash(NULL); } } @@ -289,7 +296,7 @@ void furi_hal_subghz_load_registers(const uint8_t data[][2]) { const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); cc1101_reset(device); uint32_t i = 0; - while (data[i][0]) { + while(data[i][0]) { cc1101_write_reg(device, data[i][0], data[i][1]); i++; } @@ -388,7 +395,7 @@ uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value) { } else if(value >= 778999847 && value <= 928000000) { furi_hal_subghz_set_path(FuriHalSubGhzPath868); } else { - furi_check(0); + furi_crash(NULL); } return value; } @@ -401,7 +408,7 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { while(true) { CC1101Status status = cc1101_get_status(device); - if (status.STATE == CC1101StateIDLE) break; + if(status.STATE == CC1101StateIDLE) break; } furi_hal_spi_device_return(device); @@ -411,20 +418,20 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { void furi_hal_subghz_set_path(FuriHalSubGhzPath path) { const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - if (path == FuriHalSubGhzPath433) { + if(path == FuriHalSubGhzPath433) { hal_gpio_write(&gpio_rf_sw_0, 0); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); - } else if (path == FuriHalSubGhzPath315) { + } else if(path == FuriHalSubGhzPath315) { hal_gpio_write(&gpio_rf_sw_0, 1); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); - } else if (path == FuriHalSubGhzPath868) { + } else if(path == FuriHalSubGhzPath868) { hal_gpio_write(&gpio_rf_sw_0, 1); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); - } else if (path == FuriHalSubGhzPathIsolate) { + } else if(path == FuriHalSubGhzPathIsolate) { hal_gpio_write(&gpio_rf_sw_0, 0); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); } else { - furi_check(0); + furi_crash(NULL); } furi_hal_spi_device_return(device); } @@ -438,24 +445,25 @@ static void furi_hal_subghz_capture_ISR() { if(LL_TIM_IsActiveFlag_CC1(TIM2)) { LL_TIM_ClearFlag_CC1(TIM2); furi_hal_subghz_capture_delta_duration = LL_TIM_IC_GetCaptureCH1(TIM2); - if (furi_hal_subghz_capture_callback) { - furi_hal_subghz_capture_callback(true, furi_hal_subghz_capture_delta_duration, - (void*)furi_hal_subghz_capture_callback_context - ); + if(furi_hal_subghz_capture_callback) { + furi_hal_subghz_capture_callback( + true, + furi_hal_subghz_capture_delta_duration, + (void*)furi_hal_subghz_capture_callback_context); } } // Channel 2 if(LL_TIM_IsActiveFlag_CC2(TIM2)) { LL_TIM_ClearFlag_CC2(TIM2); - if (furi_hal_subghz_capture_callback) { - furi_hal_subghz_capture_callback(false, LL_TIM_IC_GetCaptureCH2(TIM2) - furi_hal_subghz_capture_delta_duration, - (void*)furi_hal_subghz_capture_callback_context - ); + if(furi_hal_subghz_capture_callback) { + furi_hal_subghz_capture_callback( + false, + LL_TIM_IC_GetCaptureCH2(TIM2) - furi_hal_subghz_capture_delta_duration, + (void*)furi_hal_subghz_capture_callback_context); } } } - void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* context) { furi_assert(furi_hal_subghz_state == SubGhzStateIdle); furi_hal_subghz_state = SubGhzStateAsyncRx; @@ -463,12 +471,13 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* furi_hal_subghz_capture_callback = callback; furi_hal_subghz_capture_callback_context = context; - hal_gpio_init_ex(&gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); + hal_gpio_init_ex( + &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); // Timer: base LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); LL_TIM_InitTypeDef TIM_InitStruct = {0}; - TIM_InitStruct.Prescaler = 64-1; + TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 0x7FFFFFFE; TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; @@ -498,7 +507,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* // ISR setup furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_capture_ISR); - NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); + NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(TIM2_IRQn); // Interrupts and channels @@ -508,7 +517,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2); // Enable NVIC - NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); + NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(TIM2_IRQn); // Start timer @@ -534,8 +543,8 @@ void furi_hal_subghz_stop_async_rx() { } #define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL (256) -#define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF (API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL/2) -#define API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME 333 +#define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF (API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL / 2) +#define API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME 333 typedef struct { uint32_t* buffer; @@ -547,12 +556,13 @@ typedef struct { static FuriHalSubGhzAsyncTx furi_hal_subghz_async_tx = {0}; static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { - while (samples > 0) { + while(samples > 0) { bool is_odd = samples % 2; - LevelDuration ld = furi_hal_subghz_async_tx.callback(furi_hal_subghz_async_tx.callback_context); - if (level_duration_is_reset(ld)) { + LevelDuration ld = + furi_hal_subghz_async_tx.callback(furi_hal_subghz_async_tx.callback_context); + if(level_duration_is_reset(ld)) { // One more even sample required to end at low level - if (is_odd) { + if(is_odd) { *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; buffer++; samples--; @@ -560,7 +570,7 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { break; } else { // Inject guard time if level is incorrect - if (is_odd == level_duration_get_level(ld)) { + if(is_odd == level_duration_get_level(ld)) { *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; buffer++; samples--; @@ -579,21 +589,24 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { static void furi_hal_subghz_async_tx_dma_isr() { furi_assert(furi_hal_subghz_state == SubGhzStateAsyncTx); - if (LL_DMA_IsActiveFlag_HT1(DMA1)) { + if(LL_DMA_IsActiveFlag_HT1(DMA1)) { LL_DMA_ClearFlag_HT1(DMA1); - furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); + furi_hal_subghz_async_tx_refill( + furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); } - if (LL_DMA_IsActiveFlag_TC1(DMA1)) { + if(LL_DMA_IsActiveFlag_TC1(DMA1)) { LL_DMA_ClearFlag_TC1(DMA1); - furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer+API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); + furi_hal_subghz_async_tx_refill( + furi_hal_subghz_async_tx.buffer + API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF, + API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); } } static void furi_hal_subghz_async_tx_timer_isr() { if(LL_TIM_IsActiveFlag_UPDATE(TIM2)) { LL_TIM_ClearFlag_UPDATE(TIM2); - if (LL_TIM_GetAutoReload(TIM2) == 0) { - if (furi_hal_subghz_state == SubGhzStateAsyncTx) { + if(LL_TIM_GetAutoReload(TIM2) == 0) { + if(furi_hal_subghz_state == SubGhzStateAsyncTx) { furi_hal_subghz_state = SubGhzStateAsyncTxLast; } else { furi_hal_subghz_state = SubGhzStateAsyncTxEnd; @@ -612,15 +625,18 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* furi_hal_subghz_state = SubGhzStateAsyncTx; - furi_hal_subghz_async_tx.buffer = furi_alloc(API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t)); - furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL); + furi_hal_subghz_async_tx.buffer = + furi_alloc(API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t)); + furi_hal_subghz_async_tx_refill( + furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL); // Connect CC1101_GD0 to TIM2 as output - hal_gpio_init_ex(&gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn1TIM2); + hal_gpio_init_ex( + &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn1TIM2); // Configure DMA LL_DMA_InitTypeDef dma_config = {0}; - dma_config.PeriphOrM2MSrcAddress = (uint32_t)&(TIM2->ARR); + dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM2->ARR); dma_config.MemoryOrM2MDstAddress = (uint32_t)furi_hal_subghz_async_tx.buffer; dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; dma_config.Mode = LL_DMA_MODE_CIRCULAR; @@ -632,7 +648,8 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP; dma_config.Priority = LL_DMA_MODE_NORMAL; LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config); - furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, furi_hal_subghz_async_tx_dma_isr); + furi_hal_interrupt_set_dma_channel_isr( + DMA1, LL_DMA_CHANNEL_1, furi_hal_subghz_async_tx_dma_isr); LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1); LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_1); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); @@ -640,7 +657,7 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* // Configure TIM2 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); LL_TIM_InitTypeDef TIM_InitStruct = {0}; - TIM_InitStruct.Prescaler = 64-1; + TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 1000; TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; @@ -672,7 +689,7 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* furi_hal_subghz_tx(); // Enable NVIC - NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); + NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(TIM2_IRQn); LL_TIM_SetCounter(TIM2, 0); @@ -685,10 +702,9 @@ bool furi_hal_subghz_is_async_tx_complete() { void furi_hal_subghz_stop_async_tx() { furi_assert( - furi_hal_subghz_state == SubGhzStateAsyncTx - || furi_hal_subghz_state == SubGhzStateAsyncTxLast - || furi_hal_subghz_state == SubGhzStateAsyncTxEnd - ); + furi_hal_subghz_state == SubGhzStateAsyncTx || + furi_hal_subghz_state == SubGhzStateAsyncTxLast || + furi_hal_subghz_state == SubGhzStateAsyncTxEnd); // Shutdown radio furi_hal_subghz_idle(); diff --git a/firmware/targets/f7/furi-hal/furi-hal-version.c b/firmware/targets/f7/furi-hal/furi-hal-version.c index d2f500395ee..b0c3c3504c2 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-version.c +++ b/firmware/targets/f7/furi-hal/furi-hal-version.c @@ -163,7 +163,7 @@ void furi_hal_version_init() { case FuriHalVersionOtpVersion1: furi_hal_version_load_otp_v1(); break; - default: furi_check(0); + default: furi_crash(NULL); } FURI_LOG_I("FuriHalVersion", "Init OK"); } diff --git a/firmware/targets/f7/furi-hal/furi-hal.c b/firmware/targets/f7/furi-hal/furi-hal.c index 2f0d850b580..2ec06dd462c 100644 --- a/firmware/targets/f7/furi-hal/furi-hal.c +++ b/firmware/targets/f7/furi-hal/furi-hal.c @@ -1,10 +1,6 @@ #include -#include #include -#include -#include -#include #include #include #include @@ -34,16 +30,8 @@ void furi_hal_init() { FURI_LOG_I("HAL", "TIM16 OK"); MX_COMP1_Init(); FURI_LOG_I("HAL", "COMP1 OK"); - MX_RF_Init(); - FURI_LOG_I("HAL", "RF OK"); - MX_PKA_Init(); - FURI_LOG_I("HAL", "PKA OK"); - MX_RNG_Init(); - FURI_LOG_I("HAL", "RNG OK"); - MX_AES1_Init(); - FURI_LOG_I("HAL", "AES1 OK"); - MX_AES2_Init(); - FURI_LOG_I("HAL", "AES2 OK"); + + furi_hal_crypto_init(); // VCP + USB furi_hal_vcp_init(); diff --git a/firmware/targets/f7/target.mk b/firmware/targets/f7/target.mk index d020c155c5a..fe9501499cb 100644 --- a/firmware/targets/f7/target.mk +++ b/firmware/targets/f7/target.mk @@ -53,12 +53,9 @@ C_SOURCES += \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_ipcc.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd_ex.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pka.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr_ex.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc_ex.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rng.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc_ex.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim.c \ @@ -81,7 +78,6 @@ CFLAGS += \ -I$(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \ -I$(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F C_SOURCES += \ - $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/croutine.c \ $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c \ $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/list.c \ $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/queue.c \ diff --git a/firmware/targets/furi-hal-include/furi-hal-bt.h b/firmware/targets/furi-hal-include/furi-hal-bt.h index 801e3c48e99..61cc413e77f 100644 --- a/firmware/targets/furi-hal-include/furi-hal-bt.h +++ b/firmware/targets/furi-hal-include/furi-hal-bt.h @@ -11,7 +11,16 @@ extern "C" { void furi_hal_bt_init(); /** Start BLE app */ -bool furi_hal_bt_start_app(); +bool furi_hal_bt_init_app(); + +/** Start advertising */ +void furi_hal_bt_start_advertising(); + +/** Stop advertising */ +void furi_hal_bt_stop_advertising(); + +/** Returns true if BLE is advertising */ +bool furi_hal_bt_is_active(); /** Get BT/BLE system component state */ void furi_hal_bt_dump_state(string_t buffer); @@ -26,10 +35,10 @@ bool furi_hal_bt_wait_startup(); * Lock shared access to flash controller * @return true if lock was successful, false if not */ -bool furi_hal_bt_lock_flash(); +bool furi_hal_bt_lock_flash(bool erase_flag); /** Unlock shared access to flash controller */ -void furi_hal_bt_unlock_flash(); +void furi_hal_bt_unlock_flash(bool erase_flag); /** Start ble tone tx at given channel and power */ void furi_hal_bt_start_tone_tx(uint8_t channel, uint8_t power); diff --git a/firmware/targets/furi-hal-include/furi-hal-crypto.h b/firmware/targets/furi-hal-include/furi-hal-crypto.h new file mode 100644 index 00000000000..304a3dbebcb --- /dev/null +++ b/firmware/targets/furi-hal-include/furi-hal-crypto.h @@ -0,0 +1,66 @@ +#pragma once + +#include +#include +#include + +/** FuriHalCryptoKey Type */ +typedef enum { + FuriHalCryptoKeyTypeMaster, /**< Master key */ + FuriHalCryptoKeyTypeSimple, /**< Simple enencrypted key */ + FuriHalCryptoKeyTypeEncrypted, /**< Encrypted with Master key */ +} FuriHalCryptoKeyType; + +/** FuriHalCryptoKey Size in bits */ +typedef enum { + FuriHalCryptoKeySize128, + FuriHalCryptoKeySize256, +} FuriHalCryptoKeySize; + +/** FuriHalCryptoKey */ +typedef struct { + FuriHalCryptoKeyType type; + FuriHalCryptoKeySize size; + uint8_t* data; +} FuriHalCryptoKey; + +/** Initialize cryptography layer + * This includes AES engines, PKA and RNG + */ +void furi_hal_crypto_init(); + +/** Store key in crypto storage + * @param key - FuriHalCryptoKey to store. Only Master, Simple or Encrypted + * @param slot - pinter to int where store slot number will be saved + * @return true on success + */ +bool furi_hal_crypto_store_add_key(FuriHalCryptoKey* key, uint8_t* slot); + +/** Init AES engine and load key from crypto store + * @param slot - store slot number + * @return true on success + */ +bool furi_hal_crypto_store_load_key(uint8_t slot, const uint8_t* iv); + +/** Unload key engine and deinit AES engine + * @param slot - store slot number + * @return true on success + */ +bool furi_hal_crypto_store_unload_key(uint8_t slot); + + +/** Encrypt data + * @param input - pointer to input data + * @param output - pointer to output data + * @param size - input/output buffer size in bytes + * @return true on success + */ +bool furi_hal_crypto_encrypt(const uint8_t *input, uint8_t *output, size_t size); + +/** Decrypt data + * @param input - pointer to input data + * @param output - pointer to output data + * @param size - input/output buffer size in bytes + * @return true on success + */ +bool furi_hal_crypto_decrypt(const uint8_t *input, uint8_t *output, size_t size); diff --git a/firmware/targets/furi-hal-include/furi-hal.h b/firmware/targets/furi-hal-include/furi-hal.h index dc5162b8a64..0fc9f2ac08d 100644 --- a/firmware/targets/furi-hal-include/furi-hal.h +++ b/firmware/targets/furi-hal-include/furi-hal.h @@ -6,6 +6,7 @@ template struct STOP_EXTERNING_ME {}; #include "furi-hal-boot.h" #include "furi-hal-clock.h" +#include "furi-hal-crypto.h" #include "furi-hal-console.h" #include "furi-hal-os.h" #include "furi-hal-i2c.h" diff --git a/lib/app-template/app-template.h b/lib/app-template/app-template.h index 27949dd0a08..a1e79c6ba2f 100644 --- a/lib/app-template/app-template.h +++ b/lib/app-template/app-template.h @@ -36,7 +36,7 @@ template AppTemplate::AppTemplate() // TODO: use plain os mutex? if(!init_mutex(&state_mutex, &state, sizeof(TState))) { printf("cannot create mutex\n"); - furi_check(0); + furi_crash(NULL); } // open gui diff --git a/lib/irda/encoder_decoder/common/irda_common_decoder.c b/lib/irda/encoder_decoder/common/irda_common_decoder.c index d64b798d60c..87458f37e27 100644 --- a/lib/irda/encoder_decoder/common/irda_common_decoder.c +++ b/lib/irda/encoder_decoder/common/irda_common_decoder.c @@ -1,4 +1,5 @@ #include "furi/check.h" +#include "furi/common_defines.h" #include "irda.h" #include "irda_common_i.h" #include @@ -39,11 +40,12 @@ static bool irda_check_preamble(IrdaCommonDecoder* decoder) { bool result = false; bool start_level = (decoder->level + decoder->timings_cnt + 1) % 2; + if (decoder->timings_cnt == 0) + return false; + // align to start at Mark timing if (!start_level) { - if (decoder->timings_cnt > 0) { - decoder->timings_cnt = consume_samples(decoder->timings, decoder->timings_cnt, 1); - } + decoder->timings_cnt = consume_samples(decoder->timings, decoder->timings_cnt, 1); } if (decoder->protocol->timings.preamble_mark == 0) { @@ -66,45 +68,75 @@ static bool irda_check_preamble(IrdaCommonDecoder* decoder) { return result; } -/* Pulse Distance Modulation */ -IrdaStatus irda_common_decode_pdm(IrdaCommonDecoder* decoder) { + +/** + * decoder->protocol->databit_len[0] contains biggest amount of bits, for this protocol. + * decoder->protocol->databit_len[1...] contains lesser values, but which can be decoded + * for some protocol modifications. + */ +static IrdaStatus irda_common_decode_bits(IrdaCommonDecoder* decoder) { furi_assert(decoder); - uint32_t* timings = decoder->timings; - IrdaStatus status = IrdaStatusError; + IrdaStatus status = IrdaStatusOk; + const IrdaTimings* timings = &decoder->protocol->timings; + + while (decoder->timings_cnt && (status == IrdaStatusOk)) { + bool level = (decoder->level + decoder->timings_cnt + 1) % 2; + uint32_t timing = decoder->timings[0]; + + /* check if short protocol version can be decoded */ + if (timings->min_split_time && !level && (timing > timings->min_split_time)) { + for (int i = 1; decoder->protocol->databit_len[i] && (i < COUNT_OF(decoder->protocol->databit_len)); ++i) { + if (decoder->protocol->databit_len[i] == decoder->databit_cnt) { + return IrdaStatusReady; + } + } + } + + status = decoder->protocol->decode(decoder, level, timing); + furi_assert(status == IrdaStatusError || status == IrdaStatusOk); + if (status == IrdaStatusError) { + break; + } + decoder->timings_cnt = consume_samples(decoder->timings, decoder->timings_cnt, 1); + + /* check if largest protocol version can be decoded */ + if (level && (decoder->protocol->databit_len[0] == decoder->databit_cnt)) { + status = IrdaStatusReady; + break; + } + } + + return status; +} + +/* Pulse Distance-Width Modulation */ +IrdaStatus irda_common_decode_pdwm(IrdaCommonDecoder* decoder, bool level, uint32_t timing) { + furi_assert(decoder); + + IrdaStatus status = IrdaStatusOk; uint32_t bit_tolerance = decoder->protocol->timings.bit_tolerance; uint16_t bit1_mark = decoder->protocol->timings.bit1_mark; uint16_t bit1_space = decoder->protocol->timings.bit1_space; uint16_t bit0_mark = decoder->protocol->timings.bit0_mark; uint16_t bit0_space = decoder->protocol->timings.bit0_space; - while (1) { - // Stop bit - if ((decoder->databit_cnt == decoder->protocol->databit_len) && (decoder->timings_cnt == 1)) { - if (MATCH_TIMING(timings[0], bit1_mark, bit_tolerance)) { - decoder->timings_cnt = 0; - status = IrdaStatusReady; - } else { - status = IrdaStatusError; - } - break; - } + bool analyze_timing = level ^ (bit1_mark == bit0_mark); + uint16_t bit1 = level ? bit1_mark : bit1_space; + uint16_t bit0 = level ? bit0_mark : bit0_space; + uint16_t no_info_timing = (bit1_mark == bit0_mark) ? bit1_mark : bit1_space; - if (decoder->timings_cnt >= 2) { - if (MATCH_TIMING(timings[0], bit1_mark, bit_tolerance) - && MATCH_TIMING(timings[1], bit1_space, bit_tolerance)) { - accumulate_lsb(decoder, 1); - } else if (MATCH_TIMING(timings[0], bit0_mark, bit_tolerance) - && MATCH_TIMING(timings[1], bit0_space, bit_tolerance)) { - accumulate_lsb(decoder, 0); - } else { - status = IrdaStatusError; - break; - } - decoder->timings_cnt = consume_samples(decoder->timings, decoder->timings_cnt, 2); + if (analyze_timing) { + if (MATCH_TIMING(timing, bit1, bit_tolerance)) { + accumulate_lsb(decoder, 1); + } else if (MATCH_TIMING(timing, bit0, bit_tolerance)) { + accumulate_lsb(decoder, 0); } else { - status = IrdaStatusOk; - break; + status = IrdaStatusError; + } + } else { + if (!MATCH_TIMING(timing, no_info_timing, bit_tolerance)) { + status = IrdaStatusError; } } @@ -112,111 +144,59 @@ IrdaStatus irda_common_decode_pdm(IrdaCommonDecoder* decoder) { } /* level switch detection goes in middle of time-quant */ -IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder) { +IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder, bool level, uint32_t timing) { furi_assert(decoder); - IrdaStatus status = IrdaStatusOk; uint16_t bit = decoder->protocol->timings.bit1_mark; uint16_t tolerance = decoder->protocol->timings.bit_tolerance; - while (decoder->timings_cnt) { - uint32_t timing = decoder->timings[0]; - bool* switch_detect = &decoder->switch_detect; - furi_assert((*switch_detect == true) || (*switch_detect == false)); + bool* switch_detect = &decoder->switch_detect; + furi_assert((*switch_detect == true) || (*switch_detect == false)); - bool single_timing = MATCH_TIMING(timing, bit, tolerance); - bool double_timing = MATCH_TIMING(timing, 2*bit, tolerance); + bool single_timing = MATCH_TIMING(timing, bit, tolerance); + bool double_timing = MATCH_TIMING(timing, 2*bit, tolerance); - if(!single_timing && !double_timing) { - status = IrdaStatusError; - break; - } + if(!single_timing && !double_timing) { + return IrdaStatusError; + } - if ((decoder->protocol->manchester_start_from_space) && (decoder->databit_cnt == 0)) { - *switch_detect = 1; /* fake as we were previously in the middle of time-quant */ - decoder->data[0] = 0; /* first captured timing should be Mark */ - ++decoder->databit_cnt; - } + if (decoder->protocol->manchester_start_from_space && (decoder->databit_cnt == 0)) { + *switch_detect = 1; /* fake as we were previously in the middle of time-quant */ + accumulate_lsb(decoder, 0); + } - if (*switch_detect == 0) { - if (double_timing) { - status = IrdaStatusError; - break; - } - /* only single timing - level switch required in the middle of time-quant */ - *switch_detect = 1; - } else { - /* double timing means we in the middle of time-quant again */ - if (single_timing) - *switch_detect = 0; + if (*switch_detect == 0) { + if (double_timing) { + return IrdaStatusError; } + /* only single timing - level switch required in the middle of time-quant */ + *switch_detect = 1; + } else { + /* double timing means we're in the middle of time-quant again */ + if (single_timing) + *switch_detect = 0; + } - decoder->timings_cnt = consume_samples(decoder->timings, decoder->timings_cnt, 1); - status = IrdaStatusOk; - bool level = (decoder->level + decoder->timings_cnt) % 2; - - if (decoder->databit_cnt < decoder->protocol->databit_len) { - if (*switch_detect) { - accumulate_lsb(decoder, level); - } - if (decoder->databit_cnt == decoder->protocol->databit_len) { - if (level) { - status = IrdaStatusReady; - break; - } - } - } else { - furi_assert(level); - /* cover case: sequence should be stopped after last bit was received */ - if (single_timing) { - status = IrdaStatusReady; - break; - } else { - status = IrdaStatusError; - } - } + if (*switch_detect) { + accumulate_lsb(decoder, level); } - return status; + return IrdaStatusOk; } -/* Pulse Width Modulation */ -IrdaStatus irda_common_decode_pwm(IrdaCommonDecoder* decoder) { - furi_assert(decoder); +IrdaMessage* irda_common_decoder_check_ready(IrdaCommonDecoder* decoder) { + IrdaMessage* message = NULL; - uint32_t* timings = decoder->timings; - IrdaStatus status = IrdaStatusOk; - uint32_t bit_tolerance = decoder->protocol->timings.bit_tolerance; - uint16_t bit1_mark = decoder->protocol->timings.bit1_mark; - uint16_t bit1_space = decoder->protocol->timings.bit1_space; - uint16_t bit0_mark = decoder->protocol->timings.bit0_mark; - - while (decoder->timings_cnt) { - bool level = (decoder->level + decoder->timings_cnt + 1) % 2; - - if (level) { - if (MATCH_TIMING(timings[0], bit1_mark, bit_tolerance)) { - accumulate_lsb(decoder, 1); - } else if (MATCH_TIMING(timings[0], bit0_mark, bit_tolerance)) { - accumulate_lsb(decoder, 0); - } else { - status = IrdaStatusError; - break; - } + if (decoder->protocol->interpret(decoder)) { + decoder->databit_cnt = 0; + message = &decoder->message; + if (decoder->protocol->decode_repeat) { + decoder->state = IrdaCommonDecoderStateProcessRepeat; } else { - if (!MATCH_TIMING(timings[0], bit1_space, bit_tolerance)) { - status = IrdaStatusError; - break; - } - } - decoder->timings_cnt = consume_samples(decoder->timings, decoder->timings_cnt, 1); - - if (decoder->databit_cnt == decoder->protocol->databit_len) { - status = IrdaStatusReady; - break; + decoder->state = IrdaCommonDecoderStateWaitPreamble; } } - return status; + return message; } IrdaMessage* irda_common_decode(IrdaCommonDecoder* decoder, bool level, uint32_t duration) { @@ -245,12 +225,13 @@ IrdaMessage* irda_common_decode(IrdaCommonDecoder* decoder, bool level, uint32_t } break; case IrdaCommonDecoderStateDecode: - status = decoder->protocol->decode(decoder); + status = irda_common_decode_bits(decoder); if (status == IrdaStatusReady) { - if (decoder->protocol->interpret(decoder)) { - message = &decoder->message; - decoder->state = IrdaCommonDecoderStateProcessRepeat; - } else { + message = irda_common_decoder_check_ready(decoder); + if (message) { + continue; + } else if (decoder->protocol->databit_len[0] == decoder->databit_cnt) { + /* error: can't decode largest protocol - begin decoding from start */ decoder->state = IrdaCommonDecoderStateWaitPreamble; } } else if (status == IrdaStatusError) { @@ -259,10 +240,6 @@ IrdaMessage* irda_common_decode(IrdaCommonDecoder* decoder, bool level, uint32_t } break; case IrdaCommonDecoderStateProcessRepeat: - if (!decoder->protocol->decode_repeat) { - decoder->state = IrdaCommonDecoderStateWaitPreamble; - continue; - } status = decoder->protocol->decode_repeat(decoder); if (status == IrdaStatusError) { irda_common_decoder_reset_state(decoder); @@ -282,9 +259,14 @@ IrdaMessage* irda_common_decode(IrdaCommonDecoder* decoder, bool level, uint32_t void* irda_common_decoder_alloc(const IrdaCommonProtocolSpec* protocol) { furi_assert(protocol); + /* protocol->databit_len[0] has to contain biggest value of bits that can be decoded */ + for (int i = 1; i < COUNT_OF(protocol->databit_len); ++i) { + furi_assert(protocol->databit_len[i] <= protocol->databit_len[0]); + } + uint32_t alloc_size = sizeof(IrdaCommonDecoder) - + protocol->databit_len / 8 - + !!(protocol->databit_len % 8); + + protocol->databit_len[0] / 8 + + !!(protocol->databit_len[0] % 8); IrdaCommonDecoder* decoder = furi_alloc(alloc_size); memset(decoder, 0, alloc_size); decoder->protocol = protocol; diff --git a/lib/irda/encoder_decoder/common/irda_common_encoder.c b/lib/irda/encoder_decoder/common/irda_common_encoder.c index cdb65d0a9d4..aefbda35f78 100644 --- a/lib/irda/encoder_decoder/common/irda_common_encoder.c +++ b/lib/irda/encoder_decoder/common/irda_common_encoder.c @@ -4,6 +4,19 @@ #include #include #include "irda_i.h" +#include + +static IrdaStatus irda_common_encode_bits(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { + IrdaStatus status = encoder->protocol->encode(encoder, duration, level); + furi_assert(status == IrdaStatusOk); + ++encoder->timings_encoded; + encoder->timings_sum += *duration; + if ((encoder->bits_encoded == encoder->bits_to_encode) && *level) { + status = IrdaStatusDone; + } + + return status; +} /* * @@ -32,14 +45,12 @@ IrdaStatus irda_common_encode_manchester(IrdaCommonEncoder* encoder, uint32_t* d *level = even_timing ^ logic_value; *duration = timings->bit1_mark; - if (even_timing) /* start encoding from space */ + if (even_timing) ++encoder->bits_encoded; - ++encoder->timings_encoded; - encoder->timings_sum += *duration; + else if (*level && (encoder->bits_encoded + 1 == encoder->bits_to_encode)) + ++encoder->bits_encoded; /* don't encode last space */ - bool finish = (encoder->bits_encoded == encoder->protocol->databit_len); - finish |= (encoder->bits_encoded == (encoder->protocol->databit_len-1)) && *level && !even_timing; - return finish ? IrdaStatusDone : IrdaStatusOk; + return IrdaStatusOk; } IrdaStatus irda_common_encode_pdwm(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { @@ -47,39 +58,25 @@ IrdaStatus irda_common_encode_pdwm(IrdaCommonEncoder* encoder, uint32_t* duratio furi_assert(duration); furi_assert(level); - bool done = false; const IrdaTimings* timings = &encoder->protocol->timings; uint8_t index = encoder->bits_encoded / 8; uint8_t shift = encoder->bits_encoded % 8; // LSB first bool logic_value = !!(encoder->data[index] & (0x01 << shift)); - - // stop bit - if (encoder->bits_encoded == encoder->protocol->databit_len) { - furi_assert(!encoder->protocol->no_stop_bit); - *duration = timings->bit1_mark; - *level = true; - ++encoder->timings_encoded; - encoder->timings_sum += *duration; - return IrdaStatusDone; - } + bool pwm = timings->bit1_space == timings->bit0_space; if (encoder->timings_encoded % 2) { /* start encoding from space */ *duration = logic_value ? timings->bit1_mark : timings->bit0_mark; *level = true; + if (pwm) + ++encoder->bits_encoded; } else { *duration = logic_value ? timings->bit1_space : timings->bit0_space; *level = false; - ++encoder->bits_encoded; - } - - if ((encoder->bits_encoded == encoder->protocol->databit_len) - && encoder->protocol->no_stop_bit) { - done = true; + if (!pwm) + ++encoder->bits_encoded; } - ++encoder->timings_encoded; - encoder->timings_sum += *duration; - return done ? IrdaStatusDone : IrdaStatusOk; + return IrdaStatusOk; } IrdaStatus irda_common_encode(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { @@ -116,7 +113,7 @@ IrdaStatus irda_common_encode(IrdaCommonEncoder* encoder, uint32_t* duration, bo } /* FALLTHROUGH */ case IrdaCommonEncoderStateEncode: - status = encoder->protocol->encode(encoder, duration, level); + status = irda_common_encode_bits(encoder, duration, level); if (status == IrdaStatusDone) { if (encoder->protocol->encode_repeat) { encoder->state = IrdaCommonEncoderStateEncodeRepeat; @@ -138,10 +135,18 @@ IrdaStatus irda_common_encode(IrdaCommonEncoder* encoder, uint32_t* duration, bo void* irda_common_encoder_alloc(const IrdaCommonProtocolSpec* protocol) { furi_assert(protocol); + if (protocol->decode == irda_common_decode_pdwm) { + furi_assert((protocol->timings.bit1_mark == protocol->timings.bit0_mark) ^ (protocol->timings.bit1_space == protocol->timings.bit0_space)); + } + + /* protocol->databit_len[0] has to contain biggest value of bits that can be decoded */ + for (int i = 1; i < COUNT_OF(protocol->databit_len); ++i) { + furi_assert(protocol->databit_len[i] <= protocol->databit_len[0]); + } - uint32_t alloc_size = sizeof(IrdaCommonEncoder) - + protocol->databit_len / 8 - + !!(protocol->databit_len % 8); + uint32_t alloc_size = sizeof(IrdaCommonDecoder) + + protocol->databit_len[0] / 8 + + !!(protocol->databit_len[0] % 8); IrdaCommonEncoder* encoder = furi_alloc(alloc_size); memset(encoder, 0, alloc_size); encoder->protocol = protocol; @@ -162,8 +167,14 @@ void irda_common_encoder_reset(IrdaCommonEncoder* encoder) { encoder->state = IrdaCommonEncoderStateSilence; encoder->switch_detect = 0; - uint8_t bytes_to_clear = encoder->protocol->databit_len / 8 - + !!(encoder->protocol->databit_len % 8); + uint8_t max_databit_len = 0; + + for (int i = 0; i < COUNT_OF(encoder->protocol->databit_len); ++i) { + max_databit_len = MAX(max_databit_len, encoder->protocol->databit_len[i]); + } + + uint8_t bytes_to_clear = max_databit_len / 8 + + !!(max_databit_len % 8); memset(encoder->data, 0, bytes_to_clear); } diff --git a/lib/irda/encoder_decoder/common/irda_common_i.h b/lib/irda/encoder_decoder/common/irda_common_i.h index 5cf7b584a2f..d751061730a 100644 --- a/lib/irda/encoder_decoder/common/irda_common_i.h +++ b/lib/irda/encoder_decoder/common/irda_common_i.h @@ -11,7 +11,8 @@ typedef struct IrdaCommonDecoder IrdaCommonDecoder; typedef struct IrdaCommonEncoder IrdaCommonEncoder; -typedef IrdaStatus (*IrdaCommonDecode)(IrdaCommonDecoder*); +typedef IrdaStatus (*IrdaCommonDecode)(IrdaCommonDecoder*, bool, uint32_t); +typedef IrdaStatus (*IrdaCommonDecodeRepeat)(IrdaCommonDecoder*); typedef bool (*IrdaCommonInterpret)(IrdaCommonDecoder*); typedef IrdaStatus (*IrdaCommonEncode)(IrdaCommonEncoder* encoder, uint32_t* out, bool* polarity); @@ -19,9 +20,9 @@ typedef struct { IrdaTimings timings; bool manchester_start_from_space; bool no_stop_bit; - uint32_t databit_len; + uint8_t databit_len[4]; IrdaCommonDecode decode; - IrdaCommonDecode decode_repeat; + IrdaCommonDecodeRepeat decode_repeat; IrdaCommonInterpret interpret; IrdaCommonEncode encode; IrdaCommonEncode encode_repeat; @@ -57,7 +58,8 @@ struct IrdaCommonEncoder { const IrdaCommonProtocolSpec* protocol; IrdaCommonStateEncoder state; bool switch_detect; - uint32_t bits_encoded; + uint8_t bits_to_encode; + uint8_t bits_encoded; uint32_t timings_sum; uint32_t timings_encoded; void* context; @@ -65,12 +67,12 @@ struct IrdaCommonEncoder { }; IrdaMessage* irda_common_decode(IrdaCommonDecoder *decoder, bool level, uint32_t duration); -IrdaStatus irda_common_decode_pdm(IrdaCommonDecoder* decoder); -IrdaStatus irda_common_decode_pwm(IrdaCommonDecoder* decoder); -IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder); +IrdaStatus irda_common_decode_pdwm(IrdaCommonDecoder* decoder, bool level, uint32_t timing); +IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder, bool level, uint32_t timing); void* irda_common_decoder_alloc(const IrdaCommonProtocolSpec *protocol); void irda_common_decoder_free(IrdaCommonDecoder* decoder); void irda_common_decoder_reset(IrdaCommonDecoder* decoder); +IrdaMessage* irda_common_decoder_check_ready(IrdaCommonDecoder* decoder); IrdaStatus irda_common_encode(IrdaCommonEncoder* encoder, uint32_t* duration, bool* polarity); IrdaStatus irda_common_encode_pdwm(IrdaCommonEncoder* encoder, uint32_t* duration, bool* polarity); diff --git a/lib/irda/encoder_decoder/common/irda_common_protocol_defs.c b/lib/irda/encoder_decoder/common/irda_common_protocol_defs.c index 75e3b604d11..617448873a1 100644 --- a/lib/irda/encoder_decoder/common/irda_common_protocol_defs.c +++ b/lib/irda/encoder_decoder/common/irda_common_protocol_defs.c @@ -12,10 +12,12 @@ const IrdaCommonProtocolSpec protocol_nec = { .preamble_tolerance = IRDA_NEC_PREAMBLE_TOLERANCE, .bit_tolerance = IRDA_NEC_BIT_TOLERANCE, .silence_time = IRDA_NEC_SILENCE, + .min_split_time = IRDA_NEC_MIN_SPLIT_TIME, }, - .databit_len = 32, + .databit_len[0] = 42, + .databit_len[1] = 32, .no_stop_bit = false, - .decode = irda_common_decode_pdm, + .decode = irda_common_decode_pdwm, .encode = irda_common_encode_pdwm, .interpret = irda_decoder_nec_interpret, .decode_repeat = irda_decoder_nec_decode_repeat, @@ -34,9 +36,9 @@ const IrdaCommonProtocolSpec protocol_samsung32 = { .bit_tolerance = IRDA_SAMSUNG_BIT_TOLERANCE, .silence_time = IRDA_SAMSUNG_SILENCE, }, - .databit_len = 32, + .databit_len[0] = 32, .no_stop_bit = false, - .decode = irda_common_decode_pdm, + .decode = irda_common_decode_pdwm, .encode = irda_common_encode_pdwm, .interpret = irda_decoder_samsung32_interpret, .decode_repeat = irda_decoder_samsung32_decode_repeat, @@ -52,7 +54,7 @@ const IrdaCommonProtocolSpec protocol_rc6 = { .bit_tolerance = IRDA_RC6_BIT_TOLERANCE, .silence_time = IRDA_RC6_SILENCE, }, - .databit_len = 1 + 3 + 1 + 8 + 8, // start_bit + 3 mode bits, + 1 toggle bit (x2 timing) + 8 address + 8 command + .databit_len[0] = 1 + 3 + 1 + 8 + 8, // start_bit + 3 mode bits, + 1 toggle bit (x2 timing) + 8 address + 8 command .manchester_start_from_space = false, .decode = irda_decoder_rc6_decode_manchester, .encode = irda_encoder_rc6_encode_manchester, @@ -70,7 +72,7 @@ const IrdaCommonProtocolSpec protocol_rc5 = { .bit_tolerance = IRDA_RC5_BIT_TOLERANCE, .silence_time = IRDA_RC5_SILENCE, }, - .databit_len = 1 + 1 + 1 + 5 + 6, // start_bit + start_bit/command_bit + toggle_bit + 5 address + 6 command + .databit_len[0] = 1 + 1 + 1 + 5 + 6, // start_bit + start_bit/command_bit + toggle_bit + 5 address + 6 command .manchester_start_from_space = true, .decode = irda_common_decode_manchester, .encode = irda_common_encode_manchester, @@ -90,10 +92,13 @@ const IrdaCommonProtocolSpec protocol_sirc = { .preamble_tolerance = IRDA_SIRC_PREAMBLE_TOLERANCE, .bit_tolerance = IRDA_SIRC_BIT_TOLERANCE, .silence_time = IRDA_SIRC_SILENCE, + .min_split_time = IRDA_SIRC_MIN_SPLIT_TIME, }, - .databit_len = 20, /* 12/15/20 */ + .databit_len[0] = 20, + .databit_len[1] = 15, + .databit_len[2] = 12, .no_stop_bit = true, - .decode = irda_common_decode_pwm, + .decode = irda_common_decode_pdwm, .encode = irda_common_encode_pdwm, .interpret = irda_decoder_sirc_interpret, .decode_repeat = NULL, diff --git a/lib/irda/encoder_decoder/irda.c b/lib/irda/encoder_decoder/irda.c index 73bd4f5e50f..19a4df468e2 100644 --- a/lib/irda/encoder_decoder/irda.c +++ b/lib/irda/encoder_decoder/irda.c @@ -45,6 +45,7 @@ static const IrdaEncoderDecoder irda_encoder_decoder[] = { .alloc = irda_decoder_nec_alloc, .decode = irda_decoder_nec_decode, .reset = irda_decoder_nec_reset, + .check_ready = irda_decoder_nec_check_ready, .free = irda_decoder_nec_free}, .encoder = { .alloc = irda_encoder_nec_alloc, diff --git a/lib/irda/encoder_decoder/irda.h b/lib/irda/encoder_decoder/irda.h index 25a13528e16..c6151cac89c 100644 --- a/lib/irda/encoder_decoder/irda.h +++ b/lib/irda/encoder_decoder/irda.h @@ -21,14 +21,16 @@ typedef struct IrdaEncoderHandler IrdaEncoderHandler; typedef enum { IrdaProtocolUnknown = -1, IrdaProtocolNEC = 0, - IrdaProtocolNECext = 1, - IrdaProtocolSamsung32 = 2, - IrdaProtocolRC6 = 3, - IrdaProtocolRC5 = 4, - IrdaProtocolRC5X = 5, - IrdaProtocolSIRC = 6, - IrdaProtocolSIRC15 = 7, - IrdaProtocolSIRC20 = 8, + IrdaProtocolNECext, + IrdaProtocolNEC42, + IrdaProtocolNEC42ext, + IrdaProtocolSamsung32, + IrdaProtocolRC6, + IrdaProtocolRC5, + IrdaProtocolRC5X, + IrdaProtocolSIRC, + IrdaProtocolSIRC15, + IrdaProtocolSIRC20, IrdaProtocolMAX, } IrdaProtocol; diff --git a/lib/irda/encoder_decoder/irda_i.h b/lib/irda/encoder_decoder/irda_i.h index c147b3db946..e90e3a3bd32 100644 --- a/lib/irda/encoder_decoder/irda_i.h +++ b/lib/irda/encoder_decoder/irda_i.h @@ -4,6 +4,7 @@ #include typedef struct { + uint32_t min_split_time; uint32_t silence_time; uint16_t preamble_mark; uint16_t preamble_space; diff --git a/lib/irda/encoder_decoder/irda_protocol_defs_i.h b/lib/irda/encoder_decoder/irda_protocol_defs_i.h index 15d9fea2bfd..4c38016069c 100644 --- a/lib/irda/encoder_decoder/irda_protocol_defs_i.h +++ b/lib/irda/encoder_decoder/irda_protocol_defs_i.h @@ -23,12 +23,13 @@ #define IRDA_NEC_PREAMBLE_MARK 9000 #define IRDA_NEC_PREAMBLE_SPACE 4500 #define IRDA_NEC_BIT1_MARK 560 -#define IRDA_NEC_BIT1_SPACE 1600 +#define IRDA_NEC_BIT1_SPACE 1690 #define IRDA_NEC_BIT0_MARK 560 #define IRDA_NEC_BIT0_SPACE 560 #define IRDA_NEC_REPEAT_PERIOD 110000 #define IRDA_NEC_SILENCE IRDA_NEC_REPEAT_PERIOD -#define IRDA_NEC_REPEAT_PAUSE_MIN 30000 +#define IRDA_NEC_MIN_SPLIT_TIME IRDA_NEC_REPEAT_PAUSE_MIN +#define IRDA_NEC_REPEAT_PAUSE_MIN 4000 #define IRDA_NEC_REPEAT_PAUSE_MAX 150000 #define IRDA_NEC_REPEAT_MARK 9000 #define IRDA_NEC_REPEAT_SPACE 2250 @@ -38,6 +39,7 @@ void* irda_decoder_nec_alloc(void); void irda_decoder_nec_reset(void* decoder); void irda_decoder_nec_free(void* decoder); +IrdaMessage* irda_decoder_nec_check_ready(void* decoder); IrdaMessage* irda_decoder_nec_decode(void* decoder, bool level, uint32_t duration); void* irda_encoder_nec_alloc(void); IrdaStatus irda_encoder_nec_encode(void* encoder_ptr, uint32_t* duration, bool* level); @@ -143,7 +145,7 @@ void irda_encoder_rc6_reset(void* encoder_ptr, const IrdaMessage* message); void irda_encoder_rc6_free(void* decoder); IrdaStatus irda_encoder_rc6_encode(void* encoder_ptr, uint32_t* duration, bool* polarity); bool irda_decoder_rc6_interpret(IrdaCommonDecoder* decoder); -IrdaStatus irda_decoder_rc6_decode_manchester(IrdaCommonDecoder* decoder); +IrdaStatus irda_decoder_rc6_decode_manchester(IrdaCommonDecoder* decoder, bool level, uint32_t timing); IrdaStatus irda_encoder_rc6_encode_manchester(IrdaCommonEncoder* encoder_ptr, uint32_t* duration, bool* polarity); const IrdaProtocolSpecification* irda_rc6_get_spec(IrdaProtocol protocol); @@ -229,7 +231,7 @@ extern const IrdaCommonProtocolSpec protocol_rc5; #define IRDA_SIRC_PREAMBLE_TOLERANCE 200 // us #define IRDA_SIRC_BIT_TOLERANCE 120 // us #define IRDA_SIRC_SILENCE 10000 -#define IRDA_SIRC_MIN_SILENCE (IRDA_SIRC_SILENCE - 1000) +#define IRDA_SIRC_MIN_SPLIT_TIME (IRDA_SIRC_SILENCE - 1000) #define IRDA_SIRC_REPEAT_PERIOD 45000 diff --git a/lib/irda/encoder_decoder/nec/irda_decoder_nec.c b/lib/irda/encoder_decoder/nec/irda_decoder_nec.c index 79a85d7689d..541e98f3175 100644 --- a/lib/irda/encoder_decoder/nec/irda_decoder_nec.c +++ b/lib/irda/encoder_decoder/nec/irda_decoder_nec.c @@ -1,3 +1,4 @@ +#include "common/irda_common_i.h" #include "irda.h" #include "irda_protocol_defs_i.h" #include @@ -6,26 +7,55 @@ #include "../irda_i.h" +IrdaMessage* irda_decoder_nec_check_ready(void* ctx) { + return irda_common_decoder_check_ready(ctx); +} + bool irda_decoder_nec_interpret(IrdaCommonDecoder* decoder) { furi_assert(decoder); bool result = false; - uint8_t address = decoder->data[0]; - uint8_t address_inverse = decoder->data[1]; - uint8_t command = decoder->data[2]; - uint8_t command_inverse = decoder->data[3]; - if (command == (uint8_t) ~command_inverse) { - if (address == (uint8_t) ~address_inverse) { + if (decoder->databit_cnt == 32) { + uint8_t address = decoder->data[0]; + uint8_t address_inverse = decoder->data[1]; + uint8_t command = decoder->data[2]; + uint8_t command_inverse = decoder->data[3]; + if ((command == (uint8_t) ~command_inverse) && (address == (uint8_t) ~address_inverse)) { decoder->message.protocol = IrdaProtocolNEC; decoder->message.address = address; + decoder->message.command = command; + decoder->message.repeat = false; + result = true; } else { decoder->message.protocol = IrdaProtocolNECext; decoder->message.address = decoder->data[0] | (decoder->data[1] << 8); + decoder->message.command = decoder->data[2] | (decoder->data[3] << 8); + decoder->message.repeat = false; + result = true; + } + } else if (decoder->databit_cnt == 42) { + uint32_t* data1 = (void*) decoder->data; + uint16_t* data2 = (void*) (data1 + 1); + uint16_t address = *data1 & 0x1FFF; + uint16_t address_inverse = (*data1 >> 13) & 0x1FFF; + uint16_t command = ((*data1 >> 26) & 0x3F) | ((*data2 & 0x3) << 6); + uint16_t command_inverse = (*data2 >> 2) & 0xFF; + + if ((address == (~address_inverse & 0x1FFF)) + && (command == (~command_inverse & 0xFF))) { + decoder->message.protocol = IrdaProtocolNEC42; + decoder->message.address = address; + decoder->message.command = command; + decoder->message.repeat = false; + result = true; + } else { + decoder->message.protocol = IrdaProtocolNEC42ext; + decoder->message.address = address | (address_inverse << 13); + decoder->message.command = command | (command_inverse << 8); + decoder->message.repeat = false; + result = true; } - decoder->message.command = command; - decoder->message.repeat = false; - result = true; } return result; diff --git a/lib/irda/encoder_decoder/nec/irda_encoder_nec.c b/lib/irda/encoder_decoder/nec/irda_encoder_nec.c index b6551b77341..137a3be6b7d 100644 --- a/lib/irda/encoder_decoder/nec/irda_encoder_nec.c +++ b/lib/irda/encoder_decoder/nec/irda_encoder_nec.c @@ -20,26 +20,45 @@ void irda_encoder_nec_reset(void* encoder_ptr, const IrdaMessage* message) { IrdaCommonEncoder* encoder = encoder_ptr; irda_common_encoder_reset(encoder); - uint8_t address = message->address; - uint8_t address_inverse = ~address; - uint8_t command = message->command; - uint8_t command_inverse = ~command; - - uint32_t* data = (void*) encoder->data; + uint32_t* data1 = (void*) encoder->data; + uint32_t* data2 = data1 + 1; if (message->protocol == IrdaProtocolNEC) { - *data = (address | (address_inverse << 8)); + uint8_t address = message->address; + uint8_t address_inverse = ~address; + uint8_t command = message->command; + uint8_t command_inverse = ~command; + *data1 = address; + *data1 |= address_inverse << 8; + *data1 |= command << 16; + *data1 |= command_inverse << 24; + encoder->bits_to_encode = 32; } else if (message->protocol == IrdaProtocolNECext) { - *data = (uint16_t) message->address; + *data1 = (uint16_t) message->address; + *data1 |= (message->command & 0xFFFF) << 16; + encoder->bits_to_encode = 32; + } else if (message->protocol == IrdaProtocolNEC42) { + /* 13 address + 13 inverse address + 8 command + 8 inv command */ + *data1 = message->address & 0x1FFFUL; + *data1 |= (~message->address & 0x1FFFUL) << 13; + *data1 |= ((message->command & 0x3FUL) << 26); + *data2 = (message->command & 0xC0UL) >> 6; + *data2 |= (~message->command & 0xFFUL) << 2; + encoder->bits_to_encode = 42; + } else if (message->protocol == IrdaProtocolNEC42ext) { + *data1 = message->address & 0x3FFFFFF; + *data1 |= ((message->command & 0x3F) << 26); + *data2 = (message->command & 0xFFC0) >> 6; + encoder->bits_to_encode = 42; + } else { + furi_assert(0); } - *data |= command << 16; - *data |= command_inverse << 24; } IrdaStatus irda_encoder_nec_encode_repeat(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { furi_assert(encoder); /* space + 2 timings preambule + payload + stop bit */ - uint32_t timings_encoded_up_to_repeat = 1 + 2 + encoder->protocol->databit_len * 2 + 1; + uint32_t timings_encoded_up_to_repeat = 1 + 2 + encoder->bits_to_encode * 2 + 1; uint32_t repeat_cnt = encoder->timings_encoded - timings_encoded_up_to_repeat; furi_assert(encoder->timings_encoded >= timings_encoded_up_to_repeat); diff --git a/lib/irda/encoder_decoder/nec/irda_nec_spec.c b/lib/irda/encoder_decoder/nec/irda_nec_spec.c index 9c27b69a0e5..0460caeccd2 100644 --- a/lib/irda/encoder_decoder/nec/irda_nec_spec.c +++ b/lib/irda/encoder_decoder/nec/irda_nec_spec.c @@ -12,16 +12,36 @@ static const IrdaProtocolSpecification irda_nec_protocol_specification = { static const IrdaProtocolSpecification irda_necext_protocol_specification = { .name = "NECext", .address_length = 16, + .command_length = 16, + .frequency = IRDA_COMMON_CARRIER_FREQUENCY, + .duty_cycle = IRDA_COMMON_DUTY_CYCLE, +}; + +static const IrdaProtocolSpecification irda_nec42_protocol_specification = { + .name = "NEC42", + .address_length = 13, .command_length = 8, .frequency = IRDA_COMMON_CARRIER_FREQUENCY, .duty_cycle = IRDA_COMMON_DUTY_CYCLE, }; +static const IrdaProtocolSpecification irda_nec42ext_protocol_specification = { + .name = "NEC42ext", + .address_length = 26, + .command_length = 16, + .frequency = IRDA_COMMON_CARRIER_FREQUENCY, + .duty_cycle = IRDA_COMMON_DUTY_CYCLE, +}; + const IrdaProtocolSpecification* irda_nec_get_spec(IrdaProtocol protocol) { if (protocol == IrdaProtocolNEC) return &irda_nec_protocol_specification; else if (protocol == IrdaProtocolNECext) return &irda_necext_protocol_specification; + else if (protocol == IrdaProtocolNEC42) + return &irda_nec42_protocol_specification; + else if (protocol == IrdaProtocolNEC42ext) + return &irda_nec42ext_protocol_specification; else return NULL; } diff --git a/lib/irda/encoder_decoder/rc5/irda_encoder_rc5.c b/lib/irda/encoder_decoder/rc5/irda_encoder_rc5.c index e6fa9f0d46f..fb55788e41e 100644 --- a/lib/irda/encoder_decoder/rc5/irda_encoder_rc5.c +++ b/lib/irda/encoder_decoder/rc5/irda_encoder_rc5.c @@ -30,6 +30,7 @@ void irda_encoder_rc5_reset(void* encoder_ptr, const IrdaMessage* message) { common_encoder->data[0] = ~common_encoder->data[0]; common_encoder->data[1] = ~common_encoder->data[1]; + common_encoder->bits_to_encode = common_encoder->protocol->databit_len[0]; encoder->toggle_bit ^= 1; } diff --git a/lib/irda/encoder_decoder/rc6/irda_decoder_rc6.c b/lib/irda/encoder_decoder/rc6/irda_decoder_rc6.c index 9bab9da050f..cedc617f305 100644 --- a/lib/irda/encoder_decoder/rc6/irda_decoder_rc6.c +++ b/lib/irda/encoder_decoder/rc6/irda_decoder_rc6.c @@ -50,39 +50,35 @@ bool irda_decoder_rc6_interpret(IrdaCommonDecoder* decoder) { * it separately and than pass decoding for other bits to * common manchester decode function. */ -IrdaStatus irda_decoder_rc6_decode_manchester(IrdaCommonDecoder* decoder) { +IrdaStatus irda_decoder_rc6_decode_manchester(IrdaCommonDecoder* decoder, bool level, uint32_t timing) { // 4th bit lasts 2x times more IrdaStatus status = IrdaStatusError; uint16_t bit = decoder->protocol->timings.bit1_mark; uint16_t tolerance = decoder->protocol->timings.bit_tolerance; - uint16_t timing = decoder->timings[0]; bool single_timing = MATCH_TIMING(timing, bit, tolerance); bool double_timing = MATCH_TIMING(timing, 2*bit, tolerance); bool triple_timing = MATCH_TIMING(timing, 3*bit, tolerance); if (decoder->databit_cnt == 4) { - furi_assert(decoder->timings_cnt == 1); furi_assert(decoder->switch_detect == true); if (single_timing ^ triple_timing) { - --decoder->timings_cnt; ++decoder->databit_cnt; - decoder->data[0] |= (single_timing ? !decoder->level : decoder->level) << 4; + decoder->data[0] |= (single_timing ? !level : level) << 4; status = IrdaStatusOk; } } else if (decoder->databit_cnt == 5) { if (single_timing || triple_timing) { if (triple_timing) - decoder->timings[0] = bit; + timing = bit; decoder->switch_detect = false; - status = irda_common_decode_manchester(decoder); + status = irda_common_decode_manchester(decoder, level, timing); } else if (double_timing) { - --decoder->timings_cnt; status = IrdaStatusOk; } } else { - status = irda_common_decode_manchester(decoder); + status = irda_common_decode_manchester(decoder, level, timing); } return status; diff --git a/lib/irda/encoder_decoder/rc6/irda_encoder_rc6.c b/lib/irda/encoder_decoder/rc6/irda_encoder_rc6.c index 2d099b7de85..23063c24629 100644 --- a/lib/irda/encoder_decoder/rc6/irda_encoder_rc6.c +++ b/lib/irda/encoder_decoder/rc6/irda_encoder_rc6.c @@ -24,6 +24,7 @@ void irda_encoder_rc6_reset(void* encoder_ptr, const IrdaMessage* message) { *data |= reverse(message->address) << 5; *data |= reverse(message->command) << 13; + common_encoder->bits_to_encode = common_encoder->protocol->databit_len[0]; encoder->toggle_bit ^= 1; } diff --git a/lib/irda/encoder_decoder/samsung/irda_encoder_samsung.c b/lib/irda/encoder_decoder/samsung/irda_encoder_samsung.c index 5a3c5f5069e..9ee17d4a4f2 100644 --- a/lib/irda/encoder_decoder/samsung/irda_encoder_samsung.c +++ b/lib/irda/encoder_decoder/samsung/irda_encoder_samsung.c @@ -29,13 +29,15 @@ void irda_encoder_samsung32_reset(void* encoder_ptr, const IrdaMessage* message) *data |= address << 8; *data |= command << 16; *data |= command_inverse << 24; + + encoder->bits_to_encode = encoder->protocol->databit_len[0]; } IrdaStatus irda_encoder_samsung32_encode_repeat(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { furi_assert(encoder); /* space + 2 timings preambule + payload + stop bit */ - uint32_t timings_encoded_up_to_repeat = 1 + 2 + encoder->protocol->databit_len * 2 + 1; + uint32_t timings_encoded_up_to_repeat = 1 + 2 + encoder->bits_encoded * 2 + 1; uint32_t repeat_cnt = encoder->timings_encoded - timings_encoded_up_to_repeat; furi_assert(encoder->timings_encoded >= timings_encoded_up_to_repeat); diff --git a/lib/irda/encoder_decoder/sirc/irda_decoder_sirc.c b/lib/irda/encoder_decoder/sirc/irda_decoder_sirc.c index 2ae768637b2..00b49eef634 100644 --- a/lib/irda/encoder_decoder/sirc/irda_decoder_sirc.c +++ b/lib/irda/encoder_decoder/sirc/irda_decoder_sirc.c @@ -8,16 +8,7 @@ IrdaMessage* irda_decoder_sirc_check_ready(void* ctx) { - IrdaMessage* message = NULL; - IrdaCommonDecoder* decoder = ctx; - - if (irda_decoder_sirc_interpret(decoder)) { - message = &decoder->message; - decoder->timings_cnt = 0; - decoder->databit_cnt = 0; - } - - return message; + return irda_common_decoder_check_ready(ctx); } bool irda_decoder_sirc_interpret(IrdaCommonDecoder* decoder) { @@ -57,29 +48,8 @@ void* irda_decoder_sirc_alloc(void) { return irda_common_decoder_alloc(&protocol_sirc); } -IrdaMessage* irda_decoder_sirc_decode(void* context, bool level, uint32_t duration) { - IrdaCommonDecoder* decoder = context; - IrdaMessage* message = NULL; - - if ((decoder->databit_cnt == 12) || (decoder->databit_cnt == 15)) { - if (!level && (duration >= IRDA_SIRC_MIN_SILENCE)) { - if (irda_decoder_sirc_interpret(decoder)) { - message = &decoder->message; - decoder->timings_cnt = 0; - decoder->databit_cnt = 0; - } - } - } - - if (!message) { - message = irda_common_decode(decoder, level, duration); - if (message) { /* 20 bit */ - decoder->timings_cnt = 0; - decoder->databit_cnt = 0; - } - } - - return message; +IrdaMessage* irda_decoder_sirc_decode(void* decoder, bool level, uint32_t duration) { + return irda_common_decode(decoder, level, duration); } void irda_decoder_sirc_free(void* decoder) { diff --git a/lib/irda/encoder_decoder/sirc/irda_encoder_sirc.c b/lib/irda/encoder_decoder/sirc/irda_encoder_sirc.c index d6cd54cfe99..ca98e8301f1 100644 --- a/lib/irda/encoder_decoder/sirc/irda_encoder_sirc.c +++ b/lib/irda/encoder_decoder/sirc/irda_encoder_sirc.c @@ -7,34 +7,27 @@ #include -typedef struct { - IrdaCommonEncoder* common_encoder; - uint8_t databits; -} IrdaSircEncoder; - - void irda_encoder_sirc_reset(void* encoder_ptr, const IrdaMessage* message) { furi_assert(encoder_ptr); furi_assert(message); IrdaCommonEncoder* encoder = encoder_ptr; - IrdaSircEncoder* encoder_sirc = encoder->context; irda_common_encoder_reset(encoder); uint32_t* data = (void*) encoder->data; if (message->protocol == IrdaProtocolSIRC) { - encoder_sirc->databits = 12; *data = (message->command & 0x7F); *data |= (message->address & 0x1F) << 7; + encoder->bits_to_encode = 12; } else if (message->protocol == IrdaProtocolSIRC15) { - encoder_sirc->databits = 15; *data = (message->command & 0x7F); *data |= (message->address & 0xFF) << 7; + encoder->bits_to_encode = 15; } else if (message->protocol == IrdaProtocolSIRC20) { - encoder_sirc->databits = 20; *data = (message->command & 0x7F); *data |= (message->address & 0x1FFF) << 7; + encoder->bits_to_encode = 20; } else { furi_assert(0); } @@ -43,9 +36,7 @@ void irda_encoder_sirc_reset(void* encoder_ptr, const IrdaMessage* message) { IrdaStatus irda_encoder_sirc_encode_repeat(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { furi_assert(encoder); - IrdaSircEncoder* encoder_sirc = encoder->context; - - uint32_t timings_in_message = 1 + 2 + encoder_sirc->databits * 2; + uint32_t timings_in_message = 1 + 2 + encoder->bits_to_encode * 2 - 1; furi_assert(encoder->timings_encoded == timings_in_message); furi_assert(encoder->timings_sum < IRDA_SIRC_REPEAT_PERIOD); @@ -61,28 +52,21 @@ IrdaStatus irda_encoder_sirc_encode_repeat(IrdaCommonEncoder* encoder, uint32_t* } void* irda_encoder_sirc_alloc(void) { - IrdaCommonEncoder* encoder_common = irda_common_encoder_alloc(&protocol_sirc); - IrdaSircEncoder* encoder_sirc = furi_alloc(sizeof(IrdaSircEncoder)); - encoder_sirc->common_encoder = encoder_common; - encoder_common->context = encoder_sirc; - return encoder_common; + return irda_common_encoder_alloc(&protocol_sirc); } void irda_encoder_sirc_free(void* encoder_ptr) { - IrdaCommonEncoder* encoder = encoder_ptr; - free(encoder->context); - irda_common_encoder_free(encoder); + irda_common_encoder_free(encoder_ptr); } IrdaStatus irda_encoder_sirc_encode(void* encoder_ptr, uint32_t* duration, bool* level) { - IrdaCommonEncoder* encoder_common = encoder_ptr; - IrdaSircEncoder* encoder_sirc = encoder_common->context; + IrdaCommonEncoder* encoder = encoder_ptr; - IrdaStatus status = irda_common_encode(encoder_ptr, duration, level); - if ((status == IrdaStatusOk) && (encoder_common->bits_encoded == encoder_sirc->databits)) { + IrdaStatus status = irda_common_encode(encoder, duration, level); + if ((status == IrdaStatusOk) && (encoder->bits_encoded == encoder->bits_to_encode)) { furi_assert(!*level); status = IrdaStatusDone; - encoder_common->state = IrdaCommonEncoderStateEncodeRepeat; + encoder->state = IrdaCommonEncoderStateEncodeRepeat; } return status; } diff --git a/lib/irda/worker/irda_transmit.c b/lib/irda/worker/irda_transmit.c index b27b18c074f..f1da2031313 100644 --- a/lib/irda/worker/irda_transmit.c +++ b/lib/irda/worker/irda_transmit.c @@ -75,7 +75,7 @@ FuriHalIrdaTxGetDataState irda_get_data_callback (void* context, uint32_t* durat state = FuriHalIrdaTxGetDataStateLastDone; } } else { - furi_check(0); + furi_crash(NULL); } return state; diff --git a/lib/subghz/protocols/subghz_protocol.h b/lib/subghz/protocols/subghz_protocol.h deleted file mode 100644 index f4a86c0b3b8..00000000000 --- a/lib/subghz/protocols/subghz_protocol.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once - -#include "subghz_protocol_common.h" - -typedef void (*SubGhzProtocolTextCallback)(string_t text, void* context); -typedef void (*SubGhzProtocolCommonCallbackDump)(SubGhzProtocolCommon *parser, void* context); - -typedef struct SubGhzProtocol SubGhzProtocol; - -/** Allocate SubGhzProtocol - * - * @return SubGhzProtocol* - */ -SubGhzProtocol* subghz_protocol_alloc(); - -/** Free SubGhzProtocol - * - * @param instance - */ -void subghz_protocol_free(SubGhzProtocol* instance); - -/** Get protocol by name - * - * @param instance - SubGhzProtocol instance - * @param name - name protocol - * @param SubGhzProtocolCommon - */ -SubGhzProtocolCommon* subghz_protocol_get_by_name(SubGhzProtocol* instance, const char* name); - -/** Outputting data text from all parsers - * - * @param instance - SubGhzProtocol instance - * @param callback - SubGhzProtocolTextCallback callback - * @param context - */ -void subghz_protocol_enable_dump_text(SubGhzProtocol* instance, SubGhzProtocolTextCallback callback, void* context); - -/** Outputting data SubGhzProtocol from all parsers - * - * @param instance - SubGhzProtocol instance - * @param callback - SubGhzProtocolTextCallback callback - * @param context - */ -void subghz_protocol_enable_dump(SubGhzProtocol* instance, SubGhzProtocolCommonCallbackDump 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 level - true is high, false if low - * @param duration - level duration in microseconds - */ -void subghz_protocol_parse(SubGhzProtocol* instance, bool level, uint32_t duration); diff --git a/lib/subghz/protocols/subghz_protocol_came.c b/lib/subghz/protocols/subghz_protocol_came.c index 5d3e5f4c6b5..edace771df3 100644 --- a/lib/subghz/protocols/subghz_protocol_came.c +++ b/lib/subghz/protocols/subghz_protocol_came.c @@ -11,6 +11,13 @@ struct SubGhzProtocolCame { SubGhzProtocolCommon common; }; +typedef enum { + CameDecoderStepReset = 0, + CameDecoderStepFoundStartBit, + CameDecoderStepSaveDuration, + CameDecoderStepCheckDuration, +} CameDecoderStep; + SubGhzProtocolCame* subghz_protocol_came_alloc() { SubGhzProtocolCame* instance = furi_alloc(sizeof(SubGhzProtocolCame)); @@ -19,11 +26,11 @@ SubGhzProtocolCame* subghz_protocol_came_alloc() { instance->common.te_short = 320; instance->common.te_long = 640; instance->common.te_delta = 150; - instance->common.type_protocol = TYPE_PROTOCOL_STATIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeStatic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_came_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_came_to_save_str; - instance->common.to_load_protocol_from_file= + instance->common.to_load_protocol_from_file = (SubGhzProtocolCommonLoadFromFile)subghz_protocol_came_to_load_protocol_from_file; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_came_to_load_protocol; @@ -38,97 +45,106 @@ void subghz_protocol_came_free(SubGhzProtocolCame* instance) { free(instance); } -bool subghz_protocol_came_send_key(SubGhzProtocolCame* instance, SubGhzProtocolCommonEncoder* encoder){ +bool subghz_protocol_came_send_key( + SubGhzProtocolCame* instance, + SubGhzProtocolCommonEncoder* encoder) { furi_assert(instance); furi_assert(encoder); size_t index = 0; - encoder->size_upload =(instance->common.code_last_count_bit * 2) + 2; + encoder->size_upload = (instance->common.code_last_count_bit * 2) + 2; if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false; //Send header - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short * 36); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short * 36); //Send start bit encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); //Send key data - for (uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { - if(bit_read(instance->common.code_last_found, i - 1)){ + for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { + if(bit_read(instance->common.code_last_found, i - 1)) { //send bit 1 - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long); - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); - }else{ + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_short); + } else { //send bit 0 - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short); + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_long); } } return true; } void subghz_protocol_came_reset(SubGhzProtocolCame* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = CameDecoderStepReset; } void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32_t duration) { - switch (instance->common.parser_step) { - case 0: - if ((!level) - && (DURATION_DIFF(duration, instance->common.te_short * 51)< instance->common.te_delta * 51)) { //Need protocol 36 te_short + switch(instance->common.parser_step) { + case CameDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 51) < + instance->common.te_delta * 51)) { //Need protocol 36 te_short //Found header CAME - instance->common.parser_step = 1; + instance->common.parser_step = CameDecoderStepFoundStartBit; } else { - instance->common.parser_step = 0; + instance->common.parser_step = CameDecoderStepReset; } break; - case 1: - if (!level) { + case CameDecoderStepFoundStartBit: + if(!level) { break; - } else if (DURATION_DIFF(duration, instance->common.te_short)< instance->common.te_delta) { + } else if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) { //Found start bit CAME - instance->common.parser_step = 2; + instance->common.parser_step = CameDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = CameDecoderStepReset; } break; - case 2: - if (!level) { //save interval - if (duration >= (instance->common.te_short * 4)) { - instance->common.parser_step = 1; - if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { - - + case CameDecoderStepSaveDuration: + if(!level) { //save interval + if(duration >= (instance->common.te_short * 4)) { + instance->common.parser_step = CameDecoderStepFoundStartBit; + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { instance->common.serial = 0x0; instance->common.btn = 0x0; instance->common.code_last_found = instance->common.code_found; instance->common.code_last_count_bit = instance->common.code_count_bit; - if (instance->common.callback) - instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); - + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } break; } instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = CameDecoderStepCheckDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = CameDecoderStepReset; } break; - case 3: - if (level) { - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short) < instance->common.te_delta) - && (DURATION_DIFF(duration, instance->common.te_long)< instance->common.te_delta)) { + case CameDecoderStepCheckDuration: + if(level) { + if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 2; - } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta) - && (DURATION_DIFF(duration, instance->common.te_short)< instance->common.te_delta)) { + instance->common.parser_step = CameDecoderStepSaveDuration; + } else if( + (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 2; + instance->common.parser_step = CameDecoderStepSaveDuration; } else - instance->common.parser_step = 0; + instance->common.parser_step = CameDecoderStepReset; } else { - instance->common.parser_step = 0; + instance->common.parser_step = CameDecoderStepReset; } break; } @@ -150,8 +166,7 @@ void subghz_protocol_came_to_str(SubGhzProtocolCame* instance, string_t output) instance->common.name, instance->common.code_last_count_bit, code_found_lo, - code_found_reverse_lo - ); + code_found_reverse_lo); } void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t output) { @@ -165,7 +180,9 @@ void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t out (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff)); } -bool subghz_protocol_came_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolCame* instance){ +bool subghz_protocol_came_to_load_protocol_from_file( + FileWorker* file_worker, + SubGhzProtocolCame* instance) { bool loaded = false; string_t temp_str; string_init(temp_str); @@ -202,9 +219,7 @@ bool subghz_protocol_came_to_load_protocol_from_file(FileWorker* file_worker, Su return loaded; } -void subghz_decoder_came_to_load_protocol( - SubGhzProtocolCame* instance, - void* context) { +void subghz_decoder_came_to_load_protocol(SubGhzProtocolCame* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_common.h b/lib/subghz/protocols/subghz_protocol_common.h index 277f89faef5..5e7e0633f87 100644 --- a/lib/subghz/protocols/subghz_protocol_common.h +++ b/lib/subghz/protocols/subghz_protocol_common.h @@ -19,12 +19,11 @@ #define SUBGHZ_APP_EXTENSION ".sub" #define SUBGHZ_ENCODER_UPLOAD_MAX_SIZE 512 -enum { - TYPE_PROTOCOL_UNKNOWN, - TYPE_PROTOCOL_STATIC, - TYPE_PROTOCOL_DYNAMIC, -}; - +typedef enum { + SubGhzProtocolCommonTypeUnknown, + SubGhzProtocolCommonTypeStatic, + SubGhzProtocolCommonTypeDynamic, +}SubGhzProtocolCommonType; typedef struct SubGhzProtocolCommon SubGhzProtocolCommon; typedef struct SubGhzProtocolCommonEncoder SubGhzProtocolCommonEncoder; @@ -38,7 +37,8 @@ typedef void (*SubGhzProtocolCommonToStr)(SubGhzProtocolCommon* instance, string typedef void (*SubGhzProtocolCommonGetStrSave)(SubGhzProtocolCommon* instance, string_t output); //Load protocol from file -typedef bool (*SubGhzProtocolCommonLoadFromFile)(FileWorker* file_worker, SubGhzProtocolCommon* instance); +typedef bool ( + *SubGhzProtocolCommonLoadFromFile)(FileWorker* file_worker, SubGhzProtocolCommon* instance); //Load protocol typedef void (*SubGhzProtocolCommonLoadFromRAW)(SubGhzProtocolCommon* instance, void* context); //Get upload encoder protocol @@ -56,13 +56,13 @@ struct SubGhzProtocolCommon { uint64_t code_found; uint64_t code_last_found; uint8_t code_min_count_bit_for_found; - uint8_t parser_step; - uint8_t type_protocol; - uint32_t te_last; + uint8_t btn; uint8_t header_count; - uint16_t cnt; + SubGhzProtocolCommonType type_protocol; + uint32_t te_last; uint32_t serial; - uint8_t btn; + uint32_t parser_step; + uint16_t cnt; /* Standard Callback for on rx complete event */ SubGhzProtocolCommonCallback callback; @@ -88,7 +88,7 @@ struct SubGhzProtocolCommonEncoder { LevelDuration* upload; }; -struct SubGhzProtocolCommonLoad{ +struct SubGhzProtocolCommonLoad { uint64_t code_found; uint8_t code_count_bit; uint32_t param1; diff --git a/lib/subghz/protocols/subghz_protocol_faac_slh.c b/lib/subghz/protocols/subghz_protocol_faac_slh.c index ee44ec76f87..8a558be9b34 100644 --- a/lib/subghz/protocols/subghz_protocol_faac_slh.c +++ b/lib/subghz/protocols/subghz_protocol_faac_slh.c @@ -1,19 +1,25 @@ #include "subghz_protocol_faac_slh.h" - struct SubGhzProtocolFaacSLH { SubGhzProtocolCommon common; }; +typedef enum { + FaacSLHDecoderStepReset = 0, + FaacSLHDecoderStepFoundPreambula, + FaacSLHDecoderStepSaveDuration, + FaacSLHDecoderStepCheckDuration, +} FaacSLHDecoderStep; + SubGhzProtocolFaacSLH* subghz_protocol_faac_slh_alloc(void) { SubGhzProtocolFaacSLH* instance = furi_alloc(sizeof(SubGhzProtocolFaacSLH)); - instance->common.name = "Faac SLH"; + instance->common.name = "Faac SLH"; instance->common.code_min_count_bit_for_found = 64; instance->common.te_short = 255; instance->common.te_long = 595; instance->common.te_delta = 100; - instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_faac_slh_to_str; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_faac_slh_to_load_protocol; @@ -32,7 +38,7 @@ void subghz_protocol_faac_slh_free(SubGhzProtocolFaacSLH* instance) { * @param bit - bit */ void subghz_protocol_faac_slh_send_bit(SubGhzProtocolFaacSLH* instance, uint8_t bit) { - if (bit) { + if(bit) { //send bit 1 SUBGHZ_TX_PIN_HIGH(); delay_us(instance->common.te_long); @@ -47,22 +53,26 @@ void subghz_protocol_faac_slh_send_bit(SubGhzProtocolFaacSLH* instance, uint8_t } } -void subghz_protocol_faac_slh_send_key(SubGhzProtocolFaacSLH* instance, uint64_t key, uint8_t bit,uint8_t repeat) { - while (repeat--) { +void subghz_protocol_faac_slh_send_key( + SubGhzProtocolFaacSLH* instance, + uint64_t key, + uint8_t bit, + uint8_t repeat) { + while(repeat--) { SUBGHZ_TX_PIN_HIGH(); //Send header delay_us(instance->common.te_long * 2); SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_long * 2); + delay_us(instance->common.te_long * 2); //Send key data - for (uint8_t i = bit; i > 0; i--) { + for(uint8_t i = bit; i > 0; i--) { subghz_protocol_faac_slh_send_bit(instance, bit_read(key, i - 1)); } } } void subghz_protocol_faac_slh_reset(SubGhzProtocolFaacSLH* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = FaacSLHDecoderStepReset; } /** Analysis of received data @@ -70,7 +80,8 @@ void subghz_protocol_faac_slh_reset(SubGhzProtocolFaacSLH* instance) { * @param instance SubGhzProtocolFaacSLH instance */ void subghz_protocol_faac_slh_check_remote_controller(SubGhzProtocolFaacSLH* instance) { - uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); + uint64_t code_found_reverse = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); uint32_t code_fix = code_found_reverse & 0xFFFFFFFF; //uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFF; @@ -79,62 +90,68 @@ void subghz_protocol_faac_slh_check_remote_controller(SubGhzProtocolFaacSLH* ins } void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, uint32_t duration) { - switch (instance->common.parser_step) { - case 0: - if ((level) - && (DURATION_DIFF(duration,instance->common.te_long * 2)< instance->common.te_delta * 3)) { - instance->common.parser_step = 1; + switch(instance->common.parser_step) { + case FaacSLHDecoderStepReset: + if((level) && (DURATION_DIFF(duration, instance->common.te_long * 2) < + instance->common.te_delta * 3)) { + instance->common.parser_step = FaacSLHDecoderStepFoundPreambula; } else { - instance->common.parser_step = 0; + instance->common.parser_step = FaacSLHDecoderStepReset; } break; - case 1: - if ((!level) - && (DURATION_DIFF(duration,instance->common.te_long * 2)< instance->common.te_delta * 3)) { + case FaacSLHDecoderStepFoundPreambula: + if((!level) && (DURATION_DIFF(duration, instance->common.te_long * 2) < + instance->common.te_delta * 3)) { //Found Preambula - instance->common.parser_step = 2; + instance->common.parser_step = FaacSLHDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = FaacSLHDecoderStepReset; } break; - case 2: - if (level) { - if (duration >= (instance->common.te_short * 3 + instance->common.te_delta)) { - instance->common.parser_step = 1; - if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { + case FaacSLHDecoderStepSaveDuration: + if(level) { + if(duration >= (instance->common.te_short * 3 + instance->common.te_delta)) { + instance->common.parser_step = FaacSLHDecoderStepFoundPreambula; + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { instance->common.code_last_found = instance->common.code_found; instance->common.code_last_count_bit = instance->common.code_count_bit; - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } instance->common.code_found = 0; instance->common.code_count_bit = 0; break; } else { instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = FaacSLHDecoderStepCheckDuration; } - }else{ - instance->common.parser_step = 0; + } else { + instance->common.parser_step = FaacSLHDecoderStepReset; } break; - case 3: - if(!level){ - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta)) { + case FaacSLHDecoderStepCheckDuration: + if(!level) { + if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 2; - } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long )< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) { + instance->common.parser_step = FaacSLHDecoderStepSaveDuration; + } else if( + (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 2; + instance->common.parser_step = FaacSLHDecoderStepSaveDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = FaacSLHDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = FaacSLHDecoderStepReset; } break; } @@ -142,28 +159,29 @@ void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, void subghz_protocol_faac_slh_to_str(SubGhzProtocolFaacSLH* instance, string_t output) { subghz_protocol_faac_slh_check_remote_controller(instance); - uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); + uint64_t code_found_reverse = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); uint32_t code_fix = code_found_reverse & 0xFFFFFFFF; - uint32_t code_hop = (code_found_reverse >>32) & 0xFFFFFFFF; - - string_cat_printf(output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Fix:%08lX \r\n" - "Hop:%08lX \r\n" - "Sn:%07lX Btn:%lX\r\n", - instance->common.name, - instance->common.code_last_count_bit, - (uint32_t)(instance->common.code_last_found >> 32), - (uint32_t)instance->common.code_last_found, - code_fix, code_hop, - instance->common.serial, - instance->common.btn); + uint32_t code_hop = (code_found_reverse >> 32) & 0xFFFFFFFF; + + string_cat_printf( + output, + "%s %dbit\r\n" + "Key:0x%lX%08lX\r\n" + "Fix:%08lX \r\n" + "Hop:%08lX \r\n" + "Sn:%07lX Btn:%lX\r\n", + instance->common.name, + instance->common.code_last_count_bit, + (uint32_t)(instance->common.code_last_found >> 32), + (uint32_t)instance->common.code_last_found, + code_fix, + code_hop, + instance->common.serial, + instance->common.btn); } -void subghz_decoder_faac_slh_to_load_protocol( - SubGhzProtocolFaacSLH* instance, - void* context) { +void subghz_decoder_faac_slh_to_load_protocol(SubGhzProtocolFaacSLH* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_gate_tx.c b/lib/subghz/protocols/subghz_protocol_gate_tx.c index 8e10d5f8b9a..3d13b61115d 100644 --- a/lib/subghz/protocols/subghz_protocol_gate_tx.c +++ b/lib/subghz/protocols/subghz_protocol_gate_tx.c @@ -1,10 +1,16 @@ #include "subghz_protocol_gate_tx.h" - struct SubGhzProtocolGateTX { SubGhzProtocolCommon common; }; +typedef enum { + GateTXDecoderStepReset = 0, + GateTXDecoderStepFoundStartBit, + GateTXDecoderStepSaveDuration, + GateTXDecoderStepCheckDuration, +} GateTXDecoderStep; + SubGhzProtocolGateTX* subghz_protocol_gate_tx_alloc(void) { SubGhzProtocolGateTX* instance = furi_alloc(sizeof(SubGhzProtocolGateTX)); @@ -13,11 +19,11 @@ SubGhzProtocolGateTX* subghz_protocol_gate_tx_alloc(void) { instance->common.te_short = 350; instance->common.te_long = 700; instance->common.te_delta = 100; - instance->common.type_protocol = TYPE_PROTOCOL_STATIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeStatic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_gate_tx_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_gate_tx_to_save_str; - instance->common.to_load_protocol_from_file= + instance->common.to_load_protocol_from_file = (SubGhzProtocolCommonLoadFromFile)subghz_protocol_gate_tx_to_load_protocol_from_file; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_gate_tx_to_load_protocol; @@ -31,33 +37,40 @@ void subghz_protocol_gate_tx_free(SubGhzProtocolGateTX* instance) { free(instance); } -bool subghz_protocol_gate_tx_send_key(SubGhzProtocolGateTX* instance, SubGhzProtocolCommonEncoder* encoder){ +bool subghz_protocol_gate_tx_send_key( + SubGhzProtocolGateTX* instance, + SubGhzProtocolCommonEncoder* encoder) { furi_assert(instance); furi_assert(encoder); size_t index = 0; - encoder->size_upload =(instance->common.code_last_count_bit * 2) + 2; + encoder->size_upload = (instance->common.code_last_count_bit * 2) + 2; if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false; //Send header - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short * 49); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short * 49); //Send start bit encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long); //Send key data - for (uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { - if(bit_read(instance->common.code_last_found, i - 1)){ + for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { + if(bit_read(instance->common.code_last_found, i - 1)) { //send bit 1 - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long); - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); - }else{ + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_short); + } else { //send bit 0 - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short); + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_long); } } return true; } void subghz_protocol_gate_tx_reset(SubGhzProtocolGateTX* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = GateTXDecoderStepReset; } /** Analysis of received data @@ -65,68 +78,78 @@ void subghz_protocol_gate_tx_reset(SubGhzProtocolGateTX* instance) { * @param instance SubGhzProtocolFaacSLH instance */ void subghz_protocol_gate_tx_check_remote_controller(SubGhzProtocolGateTX* instance) { - uint32_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); + uint32_t code_found_reverse = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); - instance->common.serial = (code_found_reverse & 0xFF) << 12 | ((code_found_reverse >>8) & 0xFF) << 4 | ((code_found_reverse >>20) & 0x0F) ; + instance->common.serial = (code_found_reverse & 0xFF) << 12 | + ((code_found_reverse >> 8) & 0xFF) << 4 | + ((code_found_reverse >> 20) & 0x0F); instance->common.btn = ((code_found_reverse >> 16) & 0x0F); } void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, uint32_t duration) { - switch (instance->common.parser_step) { - case 0: - if ((!level) - && (DURATION_DIFF(duration,instance->common.te_short * 47)< instance->common.te_delta * 47)) { + switch(instance->common.parser_step) { + case GateTXDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 47) < + instance->common.te_delta * 47)) { //Found Preambula - instance->common.parser_step = 1; + instance->common.parser_step = GateTXDecoderStepFoundStartBit; } else { - instance->common.parser_step = 0; + instance->common.parser_step = GateTXDecoderStepReset; } break; - case 1: - if (level && ((DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta*3))){ + case GateTXDecoderStepFoundStartBit: + if(level && + ((DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta * 3))) { //Found start bit - instance->common.parser_step = 2; + instance->common.parser_step = GateTXDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = GateTXDecoderStepReset; } break; - case 2: - if (!level) { - if (duration >= (instance->common.te_short * 10 + instance->common.te_delta)) { - instance->common.parser_step = 1; - if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { - + case GateTXDecoderStepSaveDuration: + if(!level) { + if(duration >= (instance->common.te_short * 10 + instance->common.te_delta)) { + instance->common.parser_step = GateTXDecoderStepFoundStartBit; + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { instance->common.code_last_found = instance->common.code_found; instance->common.code_last_count_bit = instance->common.code_count_bit; - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } instance->common.code_found = 0; instance->common.code_count_bit = 0; break; } else { instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = GateTXDecoderStepCheckDuration; } } - break; - case 3: - if(level){ - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta*3)) { + break; + case GateTXDecoderStepCheckDuration: + if(level) { + if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < + instance->common.te_delta * 3)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 2; - } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta*3) - && (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) { + instance->common.parser_step = GateTXDecoderStepSaveDuration; + } else if( + (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < + instance->common.te_delta * 3) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 2; + instance->common.parser_step = GateTXDecoderStepSaveDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = GateTXDecoderStepReset; } - }else{ - instance->common.parser_step = 0; + } else { + instance->common.parser_step = GateTXDecoderStepReset; } break; } @@ -134,16 +157,16 @@ void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, u void subghz_protocol_gate_tx_to_str(SubGhzProtocolGateTX* instance, string_t output) { subghz_protocol_gate_tx_check_remote_controller(instance); - string_cat_printf(output, - "%s %dbit\r\n" - "Key:%06lX\r\n" - "Sn:%05lX Btn:%lX\r\n", - instance->common.name, - instance->common.code_last_count_bit, - (uint32_t)(instance->common.code_last_found & 0xFFFFFF), - instance->common.serial, - instance->common.btn - ); + string_cat_printf( + output, + "%s %dbit\r\n" + "Key:%06lX\r\n" + "Sn:%05lX Btn:%lX\r\n", + instance->common.name, + instance->common.code_last_count_bit, + (uint32_t)(instance->common.code_last_found & 0xFFFFFF), + instance->common.serial, + instance->common.btn); } void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_t output) { @@ -157,7 +180,9 @@ void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_ (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff)); } -bool subghz_protocol_gate_tx_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolGateTX* instance){ +bool subghz_protocol_gate_tx_to_load_protocol_from_file( + FileWorker* file_worker, + SubGhzProtocolGateTX* instance) { bool loaded = false; string_t temp_str; string_init(temp_str); @@ -195,9 +220,7 @@ bool subghz_protocol_gate_tx_to_load_protocol_from_file(FileWorker* file_worker, return loaded; } -void subghz_decoder_gate_tx_to_load_protocol( - SubGhzProtocolGateTX* instance, - void* context) { +void subghz_decoder_gate_tx_to_load_protocol(SubGhzProtocolGateTX* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_ido.c b/lib/subghz/protocols/subghz_protocol_ido.c index a5d33f32478..8f7178db864 100644 --- a/lib/subghz/protocols/subghz_protocol_ido.c +++ b/lib/subghz/protocols/subghz_protocol_ido.c @@ -4,6 +4,13 @@ struct SubGhzProtocolIDo { SubGhzProtocolCommon common; }; +typedef enum { + IDoDecoderStepReset = 0, + IDoDecoderStepFoundPreambula, + IDoDecoderStepSaveDuration, + IDoDecoderStepCheckDuration, +} IDoDecoderStep; + SubGhzProtocolIDo* subghz_protocol_ido_alloc(void) { SubGhzProtocolIDo* instance = furi_alloc(sizeof(SubGhzProtocolIDo)); @@ -12,7 +19,7 @@ SubGhzProtocolIDo* subghz_protocol_ido_alloc(void) { instance->common.te_short = 450; instance->common.te_long = 1450; instance->common.te_delta = 150; - instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_ido_to_str; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_ido_to_load_protocol; @@ -65,7 +72,7 @@ void subghz_protocol_ido_send_key( } void subghz_protocol_ido_reset(SubGhzProtocolIDo* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = IDoDecoderStepReset; } /** Analysis of received data @@ -83,29 +90,29 @@ void subghz_protocol_ido_check_remote_controller(SubGhzProtocolIDo* instance) { void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t duration) { switch(instance->common.parser_step) { - case 0: + case IDoDecoderStepReset: if((level) && (DURATION_DIFF(duration, instance->common.te_short * 10) < instance->common.te_delta * 5)) { - instance->common.parser_step = 1; + instance->common.parser_step = IDoDecoderStepFoundPreambula; } else { - instance->common.parser_step = 0; + instance->common.parser_step = IDoDecoderStepReset; } break; - case 1: + case IDoDecoderStepFoundPreambula: if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 10) < instance->common.te_delta * 5)) { //Found Preambula - instance->common.parser_step = 2; + instance->common.parser_step = IDoDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = IDoDecoderStepReset; } break; - case 2: + case IDoDecoderStepSaveDuration: if(level) { if(duration >= (instance->common.te_short * 5 + instance->common.te_delta)) { - instance->common.parser_step = 1; + instance->common.parser_step = IDoDecoderStepFoundPreambula; if(instance->common.code_count_bit >= instance->common.code_min_count_bit_for_found) { instance->common.code_last_found = instance->common.code_found; @@ -119,32 +126,32 @@ void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t break; } else { instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = IDoDecoderStepCheckDuration; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = IDoDecoderStepReset; } break; - case 3: + case IDoDecoderStepCheckDuration: if(!level) { if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < instance->common.te_delta) && (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta * 3)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 2; + instance->common.parser_step = IDoDecoderStepSaveDuration; } else if( (DURATION_DIFF(instance->common.te_last, instance->common.te_short) < instance->common.te_delta * 3) && (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 2; + instance->common.parser_step = IDoDecoderStepSaveDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = IDoDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = IDoDecoderStepReset; } break; } @@ -174,9 +181,7 @@ void subghz_protocol_ido_to_str(SubGhzProtocolIDo* instance, string_t output) { instance->common.btn); } -void subghz_decoder_ido_to_load_protocol( - SubGhzProtocolIDo* instance, - void* context) { +void subghz_decoder_ido_to_load_protocol(SubGhzProtocolIDo* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_keeloq.c b/lib/subghz/protocols/subghz_protocol_keeloq.c index ccb2e1ae73b..e83042d9395 100644 --- a/lib/subghz/protocols/subghz_protocol_keeloq.c +++ b/lib/subghz/protocols/subghz_protocol_keeloq.c @@ -13,6 +13,13 @@ struct SubGhzProtocolKeeloq { const char* manufacture_name; }; +typedef enum { + KeeloqDecoderStepReset = 0, + KeeloqDecoderStepCheckPreambula, + KeeloqDecoderStepSaveDuration, + KeeloqDecoderStepCheckDuration, +} KeeloqDecoderStep; + SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc(SubGhzKeystore* keystore) { SubGhzProtocolKeeloq* instance = furi_alloc(sizeof(SubGhzProtocolKeeloq)); @@ -23,7 +30,7 @@ SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc(SubGhzKeystore* keystore) { instance->common.te_short = 400; instance->common.te_long = 800; instance->common.te_delta = 140; - instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_keeloq_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_keeloq_to_save_str; @@ -297,50 +304,50 @@ bool subghz_protocol_keeloq_send_key( } void subghz_protocol_keeloq_reset(SubGhzProtocolKeeloq* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = KeeloqDecoderStepReset; } void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, uint32_t duration) { switch(instance->common.parser_step) { - case 0: + case KeeloqDecoderStepReset: if((level) && DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) { - instance->common.parser_step = 1; + instance->common.parser_step = KeeloqDecoderStepCheckPreambula; instance->common.header_count++; } else { - instance->common.parser_step = 0; + instance->common.parser_step = KeeloqDecoderStepReset; } break; - case 1: + case KeeloqDecoderStepCheckPreambula: if((!level) && (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { - instance->common.parser_step = 0; + instance->common.parser_step = KeeloqDecoderStepReset; break; } if((instance->common.header_count > 2) && (DURATION_DIFF(duration, instance->common.te_short * 10) < instance->common.te_delta * 10)) { // Found header - instance->common.parser_step = 2; + instance->common.parser_step = KeeloqDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = KeeloqDecoderStepReset; instance->common.header_count = 0; } break; - case 2: + case KeeloqDecoderStepSaveDuration: if(level) { instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = KeeloqDecoderStepCheckDuration; } break; - case 3: + case KeeloqDecoderStepCheckDuration: if(!level) { if(duration >= (instance->common.te_short * 2 + instance->common.te_delta)) { // Found end TX - instance->common.parser_step = 0; + instance->common.parser_step = KeeloqDecoderStepReset; if(instance->common.code_count_bit >= instance->common.code_min_count_bit_for_found) { if(instance->common.code_last_found != instance->common.code_found) { @@ -363,7 +370,7 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui instance->common.code_min_count_bit_for_found) { subghz_protocol_common_add_bit(&instance->common, 1); } - instance->common.parser_step = 2; + instance->common.parser_step = KeeloqDecoderStepSaveDuration; } else if( (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta) && @@ -372,13 +379,13 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui instance->common.code_min_count_bit_for_found) { subghz_protocol_common_add_bit(&instance->common, 0); } - instance->common.parser_step = 2; + instance->common.parser_step = KeeloqDecoderStepSaveDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = KeeloqDecoderStepReset; instance->common.header_count = 0; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = KeeloqDecoderStepReset; instance->common.header_count = 0; } break; diff --git a/lib/subghz/protocols/subghz_protocol_nero_radio.c b/lib/subghz/protocols/subghz_protocol_nero_radio.c index 2a03d722c9f..7e5dd4fed01 100644 --- a/lib/subghz/protocols/subghz_protocol_nero_radio.c +++ b/lib/subghz/protocols/subghz_protocol_nero_radio.c @@ -4,6 +4,13 @@ struct SubGhzProtocolNeroRadio { SubGhzProtocolCommon common; }; +typedef enum { + NeroRadioDecoderStepReset = 0, + NeroRadioDecoderStepCheckPreambula, + NeroRadioDecoderStepSaveDuration, + NeroRadioDecoderStepCheckDuration, +} NeroRadioDecoderStep; + SubGhzProtocolNeroRadio* subghz_protocol_nero_radio_alloc(void) { SubGhzProtocolNeroRadio* instance = furi_alloc(sizeof(SubGhzProtocolNeroRadio)); @@ -12,7 +19,7 @@ SubGhzProtocolNeroRadio* subghz_protocol_nero_radio_alloc(void) { instance->common.te_short = 200; instance->common.te_long = 400; instance->common.te_delta = 80; - instance->common.type_protocol = TYPE_PROTOCOL_STATIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeStatic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nero_radio_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_nero_radio_to_save_str; @@ -74,7 +81,7 @@ bool subghz_protocol_nero_radio_send_key( } void subghz_protocol_nero_radio_reset(SubGhzProtocolNeroRadio* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } /** Analysis of received data @@ -99,24 +106,24 @@ void subghz_protocol_nero_radio_parse( bool level, uint32_t duration) { switch(instance->common.parser_step) { - case 0: + case NeroRadioDecoderStepReset: if((level) && (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { - instance->common.parser_step = 1; + instance->common.parser_step = NeroRadioDecoderStepCheckPreambula; instance->common.te_last = duration; instance->common.header_count = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } break; - case 1: + case NeroRadioDecoderStepCheckPreambula: if(level) { if((DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) || (DURATION_DIFF(duration, instance->common.te_short * 4) < instance->common.te_delta)) { instance->common.te_last = duration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } } else if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) { if(DURATION_DIFF(instance->common.te_last, instance->common.te_short) < @@ -129,32 +136,32 @@ void subghz_protocol_nero_radio_parse( instance->common.te_delta) { // Found start bit if(instance->common.header_count > 40) { - instance->common.parser_step = 2; + instance->common.parser_step = NeroRadioDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } break; - case 2: + case NeroRadioDecoderStepSaveDuration: if(level) { instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = NeroRadioDecoderStepCheckDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } break; - case 3: + case NeroRadioDecoderStepCheckDuration: if(!level) { if(duration >= (instance->common.te_short * 10 + instance->common.te_delta * 2)) { //Found stop bit - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; if(instance->common.code_count_bit >= instance->common.code_min_count_bit_for_found) { instance->common.code_last_found = instance->common.code_found; @@ -165,25 +172,25 @@ void subghz_protocol_nero_radio_parse( } instance->common.code_found = 0; instance->common.code_count_bit = 0; - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; break; } else if( (DURATION_DIFF(instance->common.te_last, instance->common.te_short) < instance->common.te_delta) && (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 2; + instance->common.parser_step = NeroRadioDecoderStepSaveDuration; } else if( (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta) && (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 2; + instance->common.parser_step = NeroRadioDecoderStepSaveDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } break; } diff --git a/lib/subghz/protocols/subghz_protocol_nero_sketch.c b/lib/subghz/protocols/subghz_protocol_nero_sketch.c index 4663bc05cc1..bbb487c8142 100644 --- a/lib/subghz/protocols/subghz_protocol_nero_sketch.c +++ b/lib/subghz/protocols/subghz_protocol_nero_sketch.c @@ -1,23 +1,29 @@ #include "subghz_protocol_nero_sketch.h" - struct SubGhzProtocolNeroSketch { SubGhzProtocolCommon common; }; +typedef enum { + NeroSketchDecoderStepReset = 0, + NeroSketchDecoderStepCheckPreambula, + NeroSketchDecoderStepSaveDuration, + NeroSketchDecoderStepCheckDuration, +} NeroSketchDecoderStep; + SubGhzProtocolNeroSketch* subghz_protocol_nero_sketch_alloc(void) { SubGhzProtocolNeroSketch* instance = furi_alloc(sizeof(SubGhzProtocolNeroSketch)); - instance->common.name = "Nero Sketch"; + instance->common.name = "Nero Sketch"; instance->common.code_min_count_bit_for_found = 40; instance->common.te_short = 330; instance->common.te_long = 660; instance->common.te_delta = 150; - instance->common.type_protocol = TYPE_PROTOCOL_STATIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeStatic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nero_sketch_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_nero_sketch_to_save_str; - instance->common.to_load_protocol_from_file= + instance->common.to_load_protocol_from_file = (SubGhzProtocolCommonLoadFromFile)subghz_protocol_nero_sketch_to_load_protocol_from_file; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_nero_sketch_to_load_protocol; @@ -32,45 +38,51 @@ void subghz_protocol_nero_sketch_free(SubGhzProtocolNeroSketch* instance) { free(instance); } -bool subghz_protocol_nero_sketch_send_key(SubGhzProtocolNeroSketch* instance, SubGhzProtocolCommonEncoder* encoder){ +bool subghz_protocol_nero_sketch_send_key( + SubGhzProtocolNeroSketch* instance, + SubGhzProtocolCommonEncoder* encoder) { furi_assert(instance); furi_assert(encoder); size_t index = 0; - encoder->size_upload = 47*2+2+(instance->common.code_last_count_bit * 2) + 2; + encoder->size_upload = 47 * 2 + 2 + (instance->common.code_last_count_bit * 2) + 2; if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false; - + //Send header - for(uint8_t i = 0; i < 47; i++){ + for(uint8_t i = 0; i < 47; i++) { encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); } - + //Send start bit - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short*4); + encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short * 4); encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); //Send key data - for (uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { - if(bit_read(instance->common.code_last_found, i - 1)){ + for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { + if(bit_read(instance->common.code_last_found, i - 1)) { //send bit 1 - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long); - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); - }else{ + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short); + } else { //send bit 0 - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_short); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_long); } } //Send stop bit - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short*3); + encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short * 3); encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); return true; } void subghz_protocol_nero_sketch_reset(SubGhzProtocolNeroSketch* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = NeroSketchDecoderStepReset; } /** Analysis of received data @@ -90,112 +102,123 @@ void subghz_protocol_nero_sketch_reset(SubGhzProtocolNeroSketch* instance) { // } -void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool level, uint32_t duration) { - switch (instance->common.parser_step) { - case 0: - if ((level) - && (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) { - instance->common.parser_step = 1; +void subghz_protocol_nero_sketch_parse( + SubGhzProtocolNeroSketch* instance, + bool level, + uint32_t duration) { + switch(instance->common.parser_step) { + case NeroSketchDecoderStepReset: + if((level) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { + instance->common.parser_step = NeroSketchDecoderStepCheckPreambula; instance->common.te_last = duration; instance->common.header_count = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroSketchDecoderStepReset; } break; - case 1: - if (level){ - if((DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta ) - || (DURATION_DIFF(duration,instance->common.te_short*4)< instance->common.te_delta)) { + case NeroSketchDecoderStepCheckPreambula: + if(level) { + if((DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) || + (DURATION_DIFF(duration, instance->common.te_short * 4) < + instance->common.te_delta)) { instance->common.te_last = duration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroSketchDecoderStepReset; } - } else if(DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta){ - if(DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta){ + } else if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) { + if(DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) { // Found header instance->common.header_count++; break; - }else if(DURATION_DIFF(instance->common.te_last,instance->common.te_short*4)< instance->common.te_delta){ - // Found start bit - if(instance->common.header_count>40) { - instance->common.parser_step = 2; + } else if( + DURATION_DIFF(instance->common.te_last, instance->common.te_short * 4) < + instance->common.te_delta) { + // Found start bit + if(instance->common.header_count > 40) { + instance->common.parser_step = NeroSketchDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; - }else { - instance->common.parser_step = 0; - } + } else { + instance->common.parser_step = NeroSketchDecoderStepReset; + } } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroSketchDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroSketchDecoderStepReset; } break; - case 2: - if (level) { - if (duration >= (instance->common.te_short * 2 + instance->common.te_delta*2)) { + case NeroSketchDecoderStepSaveDuration: + if(level) { + if(duration >= (instance->common.te_short * 2 + instance->common.te_delta * 2)) { //Found stop bit - instance->common.parser_step = 0; - if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { - + instance->common.parser_step = NeroSketchDecoderStepReset; + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { instance->common.code_last_found = instance->common.code_found; instance->common.code_last_count_bit = instance->common.code_count_bit; - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); - + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } instance->common.code_found = 0; instance->common.code_count_bit = 0; break; } else { instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = NeroSketchDecoderStepCheckDuration; } - }else{ - instance->common.parser_step = 0; + } else { + instance->common.parser_step = NeroSketchDecoderStepReset; } break; - case 3: - if(!level){ - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta)) { + case NeroSketchDecoderStepCheckDuration: + if(!level) { + if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 2; - } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long )< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) { + instance->common.parser_step = NeroSketchDecoderStepSaveDuration; + } else if( + (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 2; + instance->common.parser_step = NeroSketchDecoderStepSaveDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroSketchDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroSketchDecoderStepReset; } break; } } void subghz_protocol_nero_sketch_to_str(SubGhzProtocolNeroSketch* instance, string_t output) { - uint32_t code_found_hi = instance->common.code_last_found >> 32; uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff; - uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); - - uint32_t code_found_reverse_hi = code_found_reverse>>32; - uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff; - - string_cat_printf(output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Yek:0x%lX%08lX\r\n", - instance->common.name, - instance->common.code_last_count_bit, - code_found_hi, - code_found_lo, - code_found_reverse_hi, - code_found_reverse_lo - ); + uint64_t code_found_reverse = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); + + uint32_t code_found_reverse_hi = code_found_reverse >> 32; + uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; + + string_cat_printf( + output, + "%s %dbit\r\n" + "Key:0x%lX%08lX\r\n" + "Yek:0x%lX%08lX\r\n", + instance->common.name, + instance->common.code_last_count_bit, + code_found_hi, + code_found_lo, + code_found_reverse_hi, + code_found_reverse_lo); } void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, string_t output) { @@ -210,11 +233,12 @@ void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, instance->common.name, instance->common.code_last_count_bit, code_found_hi, - code_found_lo - ); + code_found_lo); } -bool subghz_protocol_nero_sketch_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolNeroSketch* instance){ +bool subghz_protocol_nero_sketch_to_load_protocol_from_file( + FileWorker* file_worker, + SubGhzProtocolNeroSketch* instance) { bool loaded = false; string_t temp_str; string_init(temp_str); @@ -242,7 +266,7 @@ bool subghz_protocol_nero_sketch_to_load_protocol_from_file(FileWorker* file_wor if(res != 2) { break; } - instance->common.code_last_found = (uint64_t)temp_key_hi<<32 | temp_key_lo; + instance->common.code_last_found = (uint64_t)temp_key_hi << 32 | temp_key_lo; loaded = true; } while(0); @@ -252,9 +276,7 @@ bool subghz_protocol_nero_sketch_to_load_protocol_from_file(FileWorker* file_wor return loaded; } -void subghz_decoder_nero_sketch_to_load_protocol( - SubGhzProtocolNeroSketch* instance, - void* context) { +void subghz_decoder_nero_sketch_to_load_protocol(SubGhzProtocolNeroSketch* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_nice_flo.c b/lib/subghz/protocols/subghz_protocol_nice_flo.c index af778543754..640eea25039 100644 --- a/lib/subghz/protocols/subghz_protocol_nice_flo.c +++ b/lib/subghz/protocols/subghz_protocol_nice_flo.c @@ -10,6 +10,13 @@ struct SubGhzProtocolNiceFlo { SubGhzProtocolCommon common; }; +typedef enum { + NiceFloDecoderStepReset = 0, + NiceFloDecoderStepFoundStartBit, + NiceFloDecoderStepSaveDuration, + NiceFloDecoderStepCheckDuration, +} NiceFloDecoderStep; + SubGhzProtocolNiceFlo* subghz_protocol_nice_flo_alloc() { SubGhzProtocolNiceFlo* instance = furi_alloc(sizeof(SubGhzProtocolNiceFlo)); @@ -18,11 +25,11 @@ SubGhzProtocolNiceFlo* subghz_protocol_nice_flo_alloc() { instance->common.te_short = 700; instance->common.te_long = 1400; instance->common.te_delta = 200; - instance->common.type_protocol = TYPE_PROTOCOL_STATIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeStatic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nice_flo_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_nice_flo_to_save_str; - instance->common.to_load_protocol_from_file= + instance->common.to_load_protocol_from_file = (SubGhzProtocolCommonLoadFromFile)subghz_protocol_nice_flo_to_load_protocol_from_file; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_nice_flo_to_load_protocol; @@ -36,94 +43,105 @@ void subghz_protocol_nice_flo_free(SubGhzProtocolNiceFlo* instance) { free(instance); } -bool subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, SubGhzProtocolCommonEncoder* encoder){ +bool subghz_protocol_nice_flo_send_key( + SubGhzProtocolNiceFlo* instance, + SubGhzProtocolCommonEncoder* encoder) { furi_assert(instance); furi_assert(encoder); size_t index = 0; - encoder->size_upload =(instance->common.code_last_count_bit * 2) + 2; + encoder->size_upload = (instance->common.code_last_count_bit * 2) + 2; if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false; //Send header - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short * 36); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short * 36); //Send start bit encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); //Send key data - for (uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { - if(bit_read(instance->common.code_last_found, i - 1)){ + for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { + if(bit_read(instance->common.code_last_found, i - 1)) { //send bit 1 - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long); - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); - }else{ + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_short); + } else { //send bit 0 - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short); + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_long); } } return true; } void subghz_protocol_nice_flo_reset(SubGhzProtocolNiceFlo* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFloDecoderStepReset; } void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, uint32_t duration) { - switch (instance->common.parser_step) { - case 0: - if ((!level) - && (DURATION_DIFF(duration, instance->common.te_short * 36)< instance->common.te_delta * 36)) { + switch(instance->common.parser_step) { + case NiceFloDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 36) < + instance->common.te_delta * 36)) { //Found header Nice Flo - instance->common.parser_step = 1; + instance->common.parser_step = NiceFloDecoderStepFoundStartBit; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFloDecoderStepReset; } break; - case 1: - if (!level) { + case NiceFloDecoderStepFoundStartBit: + if(!level) { break; - } else if (DURATION_DIFF(duration, instance->common.te_short)< instance->common.te_delta) { + } else if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) { //Found start bit Nice Flo - instance->common.parser_step = 2; + instance->common.parser_step = NiceFloDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFloDecoderStepReset; } break; - case 2: - if (!level) { //save interval - if (duration >= (instance->common.te_short * 4)) { - instance->common.parser_step = 1; - if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { - + case NiceFloDecoderStepSaveDuration: + if(!level) { //save interval + if(duration >= (instance->common.te_short * 4)) { + instance->common.parser_step = NiceFloDecoderStepFoundStartBit; + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { instance->common.serial = 0x0; instance->common.btn = 0x0; instance->common.code_last_found = instance->common.code_found; instance->common.code_last_count_bit = instance->common.code_count_bit; - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); - + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } break; } instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = NiceFloDecoderStepCheckDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFloDecoderStepReset; } break; - case 3: - if (level) { - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short) < instance->common.te_delta) - && (DURATION_DIFF(duration, instance->common.te_long)< instance->common.te_delta)) { + case NiceFloDecoderStepCheckDuration: + if(level) { + if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 2; - } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta) - && (DURATION_DIFF(duration, instance->common.te_short)< instance->common.te_delta)) { + instance->common.parser_step = NiceFloDecoderStepSaveDuration; + } else if( + (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 2; + instance->common.parser_step = NiceFloDecoderStepSaveDuration; } else - instance->common.parser_step = 0; + instance->common.parser_step = NiceFloDecoderStepReset; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFloDecoderStepReset; } break; } @@ -145,11 +163,9 @@ void subghz_protocol_nice_flo_to_str(SubGhzProtocolNiceFlo* instance, string_t o instance->common.name, instance->common.code_last_count_bit, code_found_lo, - code_found_reverse_lo - ); + code_found_reverse_lo); } - void subghz_protocol_nice_flo_to_save_str(SubGhzProtocolNiceFlo* instance, string_t output) { string_printf( output, @@ -161,7 +177,9 @@ void subghz_protocol_nice_flo_to_save_str(SubGhzProtocolNiceFlo* instance, strin (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff)); } -bool subghz_protocol_nice_flo_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolNiceFlo* instance){ +bool subghz_protocol_nice_flo_to_load_protocol_from_file( + FileWorker* file_worker, + SubGhzProtocolNiceFlo* instance) { bool loaded = false; string_t temp_str; string_init(temp_str); @@ -198,9 +216,7 @@ bool subghz_protocol_nice_flo_to_load_protocol_from_file(FileWorker* file_worker return loaded; } -void subghz_decoder_nice_flo_to_load_protocol( - SubGhzProtocolNiceFlo* instance, - void* context) { +void subghz_decoder_nice_flo_to_load_protocol(SubGhzProtocolNiceFlo* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_nice_flor_s.c b/lib/subghz/protocols/subghz_protocol_nice_flor_s.c index 84b813340eb..41da7373f4a 100644 --- a/lib/subghz/protocols/subghz_protocol_nice_flor_s.c +++ b/lib/subghz/protocols/subghz_protocol_nice_flor_s.c @@ -13,6 +13,14 @@ struct SubGhzProtocolNiceFlorS { const char* rainbow_table_file_name; }; +typedef enum { + NiceFlorSDecoderStepReset = 0, + NiceFlorSDecoderStepCheckHeader, + NiceFlorSDecoderStepFoundHeader, + NiceFlorSDecoderStepSaveDuration, + NiceFlorSDecoderStepCheckDuration, +} NiceFlorSDecoderStep; + SubGhzProtocolNiceFlorS* subghz_protocol_nice_flor_s_alloc() { SubGhzProtocolNiceFlorS* instance = furi_alloc(sizeof(SubGhzProtocolNiceFlorS)); @@ -21,7 +29,7 @@ SubGhzProtocolNiceFlorS* subghz_protocol_nice_flor_s_alloc() { instance->common.te_short = 500; instance->common.te_long = 1000; instance->common.te_delta = 300; - instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nice_flor_s_to_str; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_nice_flor_s_to_load_protocol; @@ -93,16 +101,14 @@ void subghz_protocol_nice_flor_s_send_key( * @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; + 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)) { + 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); @@ -134,8 +140,11 @@ void subghz_nice_flor_s_decoder_decrypt(SubGhzProtocolNiceFlorS* instance) { */ uint16_t p3p4 = (uint16_t)(instance->common.code_last_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); - uint8_t k =(uint8_t)(p3p4 & 0x00FF) ^subghz_nice_flor_s_get_byte_in_file(instance,(0x20000 |(instance->common.cnt &0x00ff))); + 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); + uint8_t k = + (uint8_t)(p3p4 & 0x00FF) ^ + subghz_nice_flor_s_get_byte_in_file(instance, (0x20000 | (instance->common.cnt & 0x00ff))); uint8_t s3 = ((uint8_t)(instance->common.code_last_found >> 40) ^ k) & 0x0f; uint8_t s2 = ((uint8_t)(instance->common.code_last_found >> 16) ^ k); @@ -147,73 +156,82 @@ void subghz_nice_flor_s_decoder_decrypt(SubGhzProtocolNiceFlorS* instance) { } void subghz_protocol_nice_flor_s_reset(SubGhzProtocolNiceFlorS* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFlorSDecoderStepReset; } -void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool level, uint32_t duration) { +void subghz_protocol_nice_flor_s_parse( + SubGhzProtocolNiceFlorS* instance, + bool level, + uint32_t duration) { switch(instance->common.parser_step) { - case 0: - if((!level) - && (DURATION_DIFF(duration, instance->common.te_short * 38) < instance->common.te_delta * 38)) { + case NiceFlorSDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 38) < + instance->common.te_delta * 38)) { //Found start header Nice Flor-S - instance->common.parser_step = 1; + instance->common.parser_step = NiceFlorSDecoderStepCheckHeader; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFlorSDecoderStepReset; } break; - case 1: - if((level) - && (DURATION_DIFF(duration, instance->common.te_short * 3) < instance->common.te_delta * 3)) { + case NiceFlorSDecoderStepCheckHeader: + if((level) && (DURATION_DIFF(duration, instance->common.te_short * 3) < + instance->common.te_delta * 3)) { //Found next header Nice Flor-S - instance->common.parser_step = 2; + instance->common.parser_step = NiceFlorSDecoderStepFoundHeader; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFlorSDecoderStepReset; } break; - case 2: - if((!level) - && (DURATION_DIFF(duration, instance->common.te_short * 3) < instance->common.te_delta * 3)) { + case NiceFlorSDecoderStepFoundHeader: + if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 3) < + instance->common.te_delta * 3)) { //Found header Nice Flor-S - instance->common.parser_step = 3; + instance->common.parser_step = NiceFlorSDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFlorSDecoderStepReset; } break; - case 3: + case NiceFlorSDecoderStepSaveDuration: if(level) { - if(DURATION_DIFF(duration, instance->common.te_short * 3) < instance->common.te_delta) { + if(DURATION_DIFF(duration, instance->common.te_short * 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) { + instance->common.parser_step = NiceFlorSDecoderStepReset; + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { instance->common.code_last_found = instance->common.code_found; instance->common.code_last_count_bit = instance->common.code_count_bit; - if(instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } break; } else { //save interval instance->common.te_last = duration; - instance->common.parser_step = 4; + instance->common.parser_step = NiceFlorSDecoderStepCheckDuration; } } break; - case 4: + case NiceFlorSDecoderStepCheckDuration: if(!level) { - if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < instance->common.te_delta) - &&(DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { + if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 3; + instance->common.parser_step = NiceFlorSDecoderStepSaveDuration; } else if( - (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta) - &&(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { + (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 3; + instance->common.parser_step = NiceFlorSDecoderStepSaveDuration; } else - instance->common.parser_step = 0; + instance->common.parser_step = NiceFlorSDecoderStepReset; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFlorSDecoderStepReset; } break; } @@ -236,13 +254,10 @@ void subghz_protocol_nice_flor_s_to_str(SubGhzProtocolNiceFlorS* instance, strin code_found_lo, instance->common.serial, instance->common.cnt, - instance->common.btn - ); + instance->common.btn); } -void subghz_decoder_nice_flor_s_to_load_protocol( - SubGhzProtocolNiceFlorS* instance, - void* context) { +void subghz_decoder_nice_flor_s_to_load_protocol(SubGhzProtocolNiceFlorS* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_princeton.c b/lib/subghz/protocols/subghz_protocol_princeton.c index 0cd60387c37..700d221f920 100644 --- a/lib/subghz/protocols/subghz_protocol_princeton.c +++ b/lib/subghz/protocols/subghz_protocol_princeton.c @@ -16,6 +16,12 @@ struct SubGhzEncoderPrinceton { size_t front; }; +typedef enum { + PrincetonDecoderStepReset = 0, + PrincetonDecoderStepSaveDuration, + PrincetonDecoderStepCheckDuration, +} PrincetonDecoderStep; + SubGhzEncoderPrinceton* subghz_encoder_princeton_alloc() { SubGhzEncoderPrinceton* instance = furi_alloc(sizeof(SubGhzEncoderPrinceton)); return instance; @@ -87,7 +93,7 @@ SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc(void) { instance->common.te_short = SUBGHZ_PT_SHORT; //150; instance->common.te_long = SUBGHZ_PT_LONG; //450; instance->common.te_delta = 250; //50; - instance->common.type_protocol = TYPE_PROTOCOL_STATIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeStatic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_decoder_princeton_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_decoder_princeton_to_save_str; @@ -142,7 +148,7 @@ bool subghz_protocol_princeton_send_key( } void subghz_decoder_princeton_reset(SubGhzDecoderPrinceton* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = PrincetonDecoderStepReset; } void subghz_decoder_princeton_parse( @@ -150,28 +156,28 @@ void subghz_decoder_princeton_parse( bool level, uint32_t duration) { switch(instance->common.parser_step) { - case 0: + case PrincetonDecoderStepReset: if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 36) < instance->common.te_delta * 36)) { //Found Preambula - instance->common.parser_step = 1; + instance->common.parser_step = PrincetonDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = PrincetonDecoderStepReset; } break; - case 1: + case PrincetonDecoderStepSaveDuration: //save duration if(level) { instance->common.te_last = duration; - instance->common.parser_step = 2; + instance->common.parser_step = PrincetonDecoderStepCheckDuration; } break; - case 2: + case PrincetonDecoderStepCheckDuration: if(!level) { if(duration >= (instance->common.te_short * 10 + instance->common.te_delta)) { - instance->common.parser_step = 1; + instance->common.parser_step = PrincetonDecoderStepSaveDuration; if(instance->common.code_count_bit == instance->common.code_min_count_bit_for_found) { if(instance->common.code_last_found == instance->common.code_found) { @@ -201,18 +207,18 @@ void subghz_decoder_princeton_parse( (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta * 3)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 1; + instance->common.parser_step = PrincetonDecoderStepSaveDuration; } else if( (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta * 3) && (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 1; + instance->common.parser_step = PrincetonDecoderStepSaveDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = PrincetonDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = PrincetonDecoderStepReset; } break; } @@ -306,9 +312,7 @@ bool subghz_decoder_princeton_to_load_protocol_from_file( return loaded; } -void subghz_decoder_princeton_to_load_protocol( - SubGhzDecoderPrinceton* instance, - void* context) { +void subghz_decoder_princeton_to_load_protocol(SubGhzDecoderPrinceton* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_star_line.c b/lib/subghz/protocols/subghz_protocol_star_line.c index 001285f32bf..3aae60871f3 100644 --- a/lib/subghz/protocols/subghz_protocol_star_line.c +++ b/lib/subghz/protocols/subghz_protocol_star_line.c @@ -8,24 +8,30 @@ #include #include - struct SubGhzProtocolStarLine { SubGhzProtocolCommon common; SubGhzKeystore* keystore; const char* manufacture_name; }; +typedef enum { + StarLineDecoderStepReset = 0, + StarLineDecoderStepCheckPreambula, + StarLineDecoderStepSaveDuration, + StarLineDecoderStepCheckDuration, +} StarLineDecoderStep; + SubGhzProtocolStarLine* subghz_protocol_star_line_alloc(SubGhzKeystore* keystore) { SubGhzProtocolStarLine* instance = furi_alloc(sizeof(SubGhzProtocolStarLine)); instance->keystore = keystore; - instance->common.name = "Star Line"; + instance->common.name = "Star Line"; instance->common.code_min_count_bit_for_found = 64; instance->common.te_short = 250; instance->common.te_long = 500; instance->common.te_delta = 120; - instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_star_line_to_str; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_star_line_to_load_protocol; @@ -38,13 +44,13 @@ void subghz_protocol_star_line_free(SubGhzProtocolStarLine* instance) { free(instance); } -const char* subghz_protocol_star_line_find_and_get_manufacture_name (void* context){ +const char* subghz_protocol_star_line_find_and_get_manufacture_name(void* context) { SubGhzProtocolStarLine* instance = context; subghz_protocol_star_line_check_remote_controller(instance); return instance->manufacture_name; } -const char* subghz_protocol_star_line_get_manufacture_name (void* context){ +const char* subghz_protocol_star_line_get_manufacture_name(void* context) { SubGhzProtocolStarLine* instance = context; return instance->manufacture_name; } @@ -55,7 +61,7 @@ const char* subghz_protocol_star_line_get_manufacture_name (void* context){ * @param bit - bit */ void subghz_protocol_star_line_send_bit(SubGhzProtocolStarLine* instance, uint8_t bit) { - if (bit) { + if(bit) { //send bit 1 SUBGHZ_TX_PIN_HIGH(); delay_us(instance->common.te_long); @@ -70,18 +76,22 @@ void subghz_protocol_star_line_send_bit(SubGhzProtocolStarLine* instance, uint8_ } } -void subghz_protocol_star_line_send_key(SubGhzProtocolStarLine* instance, uint64_t key, uint8_t bit,uint8_t repeat) { - while (repeat--) { +void subghz_protocol_star_line_send_key( + SubGhzProtocolStarLine* instance, + uint64_t key, + uint8_t bit, + uint8_t repeat) { + while(repeat--) { //Send header - for(uint8_t i = 0; i < 6; i++){ + for(uint8_t i = 0; i < 6; i++) { SUBGHZ_TX_PIN_HIGH(); delay_us(instance->common.te_long * 2); SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_long * 2); - } + delay_us(instance->common.te_long * 2); + } //Send Start bit ?????????? //Send key data - for (uint8_t i = bit; i > 0; i--) { + for(uint8_t i = bit; i > 0; i--) { subghz_protocol_star_line_send_bit(instance, bit_read(key, i - 1)); } //Send Stop bit ?????????? @@ -89,7 +99,7 @@ void subghz_protocol_star_line_send_key(SubGhzProtocolStarLine* instance, uint64 } void subghz_protocol_star_line_reset(SubGhzProtocolStarLine* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = StarLineDecoderStepReset; } /** Checking the accepted code against the database manafacture key @@ -99,86 +109,97 @@ void subghz_protocol_star_line_reset(SubGhzProtocolStarLine* instance) { * @param hop hop encrypted part of the parcel * @return true on successful search */ -uint8_t subghz_protocol_star_line_check_remote_controller_selector(SubGhzProtocolStarLine* instance, uint32_t fix , uint32_t hop) { - uint16_t end_serial = (uint16_t)(fix&0xFF); - uint8_t btn = (uint8_t)(fix>>24); +uint8_t subghz_protocol_star_line_check_remote_controller_selector( + SubGhzProtocolStarLine* instance, + uint32_t fix, + uint32_t hop) { + uint16_t end_serial = (uint16_t)(fix & 0xFF); + uint8_t btn = (uint8_t)(fix >> 24); uint32_t decrypt = 0; uint64_t man_normal_learning; for M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) { - switch (manufacture_code->type){ - case KEELOQ_LEARNING_SIMPLE: - //Simple Learning - decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); - if((decrypt>>24 == btn) && ((((uint16_t)(decrypt>>16)) & 0x00FF) == end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt = decrypt & 0x0000FFFF; - return 1; - } + switch(manufacture_code->type) { + case KEELOQ_LEARNING_SIMPLE: + //Simple Learning + decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); + if((decrypt >> 24 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x00FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } break; - case KEELOQ_LEARNING_NORMAL: - // Normal_Learning - // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 - man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - decrypt=subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); - if( (decrypt>>24 ==btn)&& ((((uint16_t)(decrypt>>16))&0x00FF)==end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt = decrypt & 0x0000FFFF; - return 1; - } + case KEELOQ_LEARNING_NORMAL: + // Normal_Learning + // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 + man_normal_learning = + subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); + decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); + if((decrypt >> 24 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x00FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } break; - case KEELOQ_LEARNING_UNKNOWN: - // Simple Learning - decrypt=subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); - if( (decrypt>>24 ==btn) && ((((uint16_t)(decrypt>>16))&0x00FF)==end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt = decrypt & 0x0000FFFF; - return 1; - } - // Check for mirrored man - uint64_t man_rev=0; - uint64_t man_rev_byte=0; - for(uint8_t i=0; i<64; i+=8){ - man_rev_byte=(uint8_t)(manufacture_code->key >> i); - man_rev = man_rev | man_rev_byte << (56-i); - } - decrypt=subghz_protocol_keeloq_common_decrypt(hop, man_rev); - if( (decrypt>>24 ==btn) && ((((uint16_t)(decrypt>>16))&0x00FF)==end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt= decrypt&0x0000FFFF; - return 1; - } - //########################### - // Normal_Learning - // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 - man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - decrypt=subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); - if( (decrypt>>24 ==btn)&& ((((uint16_t)(decrypt>>16))&0x00FF)==end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt= decrypt&0x0000FFFF; - return 1; - } - // Check for mirrored man - man_rev=0; - man_rev_byte=0; - for(uint8_t i=0; i<64; i+=8){ - man_rev_byte = (uint8_t)(manufacture_code->key >> i); - man_rev = man_rev | man_rev_byte << (56-i); - } - man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev); - decrypt=subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); - if( (decrypt>>24 ==btn) && ((((uint16_t)(decrypt>>16))&0x00FF)==end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt= decrypt&0x0000FFFF; - return 1; - } + case KEELOQ_LEARNING_UNKNOWN: + // Simple Learning + decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); + if((decrypt >> 24 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x00FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } + // Check for mirrored man + uint64_t man_rev = 0; + uint64_t man_rev_byte = 0; + for(uint8_t i = 0; i < 64; i += 8) { + man_rev_byte = (uint8_t)(manufacture_code->key >> i); + man_rev = man_rev | man_rev_byte << (56 - i); + } + decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev); + if((decrypt >> 24 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x00FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } + //########################### + // Normal_Learning + // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 + man_normal_learning = + subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); + decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); + if((decrypt >> 24 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x00FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } + // Check for mirrored man + man_rev = 0; + man_rev_byte = 0; + for(uint8_t i = 0; i < 64; i += 8) { + man_rev_byte = (uint8_t)(manufacture_code->key >> i); + man_rev = man_rev | man_rev_byte << (56 - i); + } + man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev); + decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); + if((decrypt >> 24 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x00FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } break; } } instance->manufacture_name = "Unknown"; - instance->common.cnt=0; + instance->common.cnt = 0; return 0; } @@ -188,53 +209,61 @@ uint8_t subghz_protocol_star_line_check_remote_controller_selector(SubGhzProtoco * @param instance SubGhzProtocolStarLine instance */ void subghz_protocol_star_line_check_remote_controller(SubGhzProtocolStarLine* instance) { - uint64_t key = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); + uint64_t key = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); uint32_t key_fix = key >> 32; uint32_t key_hop = key & 0x00000000ffffffff; subghz_protocol_star_line_check_remote_controller_selector(instance, key_fix, key_hop); - instance ->common.serial= key_fix&0x00FFFFFF; + instance->common.serial = key_fix & 0x00FFFFFF; instance->common.btn = key_fix >> 24; } -void subghz_protocol_star_line_parse(SubGhzProtocolStarLine* instance, bool level, uint32_t duration) { - switch (instance->common.parser_step) { - case 0: - if (level){ - if(DURATION_DIFF(duration,instance->common.te_long * 2)< instance->common.te_delta * 2) { - instance->common.parser_step = 1; +void subghz_protocol_star_line_parse( + SubGhzProtocolStarLine* instance, + bool level, + uint32_t duration) { + switch(instance->common.parser_step) { + case StarLineDecoderStepReset: + if(level) { + if(DURATION_DIFF(duration, instance->common.te_long * 2) < + instance->common.te_delta * 2) { + instance->common.parser_step = StarLineDecoderStepCheckPreambula; instance->common.header_count++; - } else if(instance->common.header_count>4){ + } else if(instance->common.header_count > 4) { instance->common.code_found = 0; instance->common.code_count_bit = 0; instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = StarLineDecoderStepCheckDuration; } - }else{ - instance->common.parser_step = 0; + } else { + instance->common.parser_step = StarLineDecoderStepReset; instance->common.header_count = 0; } break; - case 1: - if ((!level) - && (DURATION_DIFF(duration,instance->common.te_long * 2)< instance->common.te_delta * 2)) { + case StarLineDecoderStepCheckPreambula: + if((!level) && (DURATION_DIFF(duration, instance->common.te_long * 2) < + instance->common.te_delta * 2)) { //Found Preambula - instance->common.parser_step = 0; + instance->common.parser_step = StarLineDecoderStepReset; } else { instance->common.header_count = 0; - instance->common.parser_step = 0; + instance->common.parser_step = StarLineDecoderStepReset; } break; - case 2: - if (level) { - if (duration >= (instance->common.te_long + instance->common.te_delta)) { - instance->common.parser_step = 0; - if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { - if(instance->common.code_last_found != instance->common.code_found){ + case StarLineDecoderStepSaveDuration: + if(level) { + if(duration >= (instance->common.te_long + instance->common.te_delta)) { + instance->common.parser_step = StarLineDecoderStepReset; + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { + if(instance->common.code_last_found != instance->common.code_found) { instance->common.code_last_found = instance->common.code_found; instance->common.code_last_count_bit = instance->common.code_count_bit; - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } } instance->common.code_found = 0; @@ -243,28 +272,31 @@ void subghz_protocol_star_line_parse(SubGhzProtocolStarLine* instance, bool leve break; } else { instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = StarLineDecoderStepCheckDuration; } - }else{ - instance->common.parser_step = 0; + } else { + instance->common.parser_step = StarLineDecoderStepReset; } break; - case 3: - if(!level){ - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) { + case StarLineDecoderStepCheckDuration: + if(!level) { + if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 2; - } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long )< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta)) { + instance->common.parser_step = StarLineDecoderStepSaveDuration; + } else if( + (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 2; + instance->common.parser_step = StarLineDecoderStepSaveDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = StarLineDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = StarLineDecoderStepReset; } break; } @@ -275,10 +307,11 @@ void subghz_protocol_star_line_to_str(SubGhzProtocolStarLine* instance, string_t uint32_t code_found_hi = instance->common.code_last_found >> 32; uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff; - uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); + uint64_t code_found_reverse = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); - uint32_t code_found_reverse_hi = code_found_reverse>>32; - uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff; + uint32_t code_found_reverse_hi = code_found_reverse >> 32; + uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; string_cat_printf( output, "%s %dbit\r\n" @@ -296,13 +329,10 @@ void subghz_protocol_star_line_to_str(SubGhzProtocolStarLine* instance, string_t code_found_reverse_lo, instance->common.btn, instance->manufacture_name, - instance->common.serial - ); + instance->common.serial); } -void subghz_decoder_star_line_to_load_protocol( - SubGhzProtocolStarLine* instance, - void* context) { +void subghz_decoder_star_line_to_load_protocol(SubGhzProtocolStarLine* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol.c b/lib/subghz/subghz_parser.c similarity index 82% rename from lib/subghz/protocols/subghz_protocol.c rename to lib/subghz/subghz_parser.c index 616139a2d4f..6fc8f1f48fb 100644 --- a/lib/subghz/protocols/subghz_protocol.c +++ b/lib/subghz/subghz_parser.c @@ -1,18 +1,19 @@ -#include "subghz_protocol.h" -#include "subghz_protocol_came.h" -#include "subghz_protocol_cfm.h" -#include "subghz_protocol_keeloq.h" -#include "subghz_protocol_nice_flo.h" -#include "subghz_protocol_nice_flor_s.h" -#include "subghz_protocol_princeton.h" -#include "subghz_protocol_gate_tx.h" -#include "subghz_protocol_ido.h" -#include "subghz_protocol_faac_slh.h" -#include "subghz_protocol_nero_sketch.h" -#include "subghz_protocol_star_line.h" -#include "subghz_protocol_nero_radio.h" - -#include "../subghz_keystore.h" + +#include "subghz_parser.h" +#include "protocols/subghz_protocol_came.h" +#include "protocols/subghz_protocol_cfm.h" +#include "protocols/subghz_protocol_keeloq.h" +#include "protocols/subghz_protocol_nice_flo.h" +#include "protocols/subghz_protocol_nice_flor_s.h" +#include "protocols/subghz_protocol_princeton.h" +#include "protocols/subghz_protocol_gate_tx.h" +#include "protocols/subghz_protocol_ido.h" +#include "protocols/subghz_protocol_faac_slh.h" +#include "protocols/subghz_protocol_nero_sketch.h" +#include "protocols/subghz_protocol_star_line.h" +#include "protocols/subghz_protocol_nero_radio.h" + +#include "subghz_keystore.h" #include #include @@ -33,7 +34,7 @@ typedef enum { SubGhzProtocolTypeMax, } SubGhzProtocolType; -struct SubGhzProtocol { +struct SubGhzParser { SubGhzKeystore* keystore; SubGhzProtocolCommon* protocols[SubGhzProtocolTypeMax]; @@ -44,8 +45,8 @@ struct SubGhzProtocol { void* parser_callback_context; }; -static void subghz_protocol_text_rx_callback(SubGhzProtocolCommon* parser, void* context) { - SubGhzProtocol* instance = context; +static void subghz_parser_text_rx_callback(SubGhzProtocolCommon* parser, void* context) { + SubGhzParser* instance = context; string_t output; string_init(output); @@ -58,15 +59,15 @@ static void subghz_protocol_text_rx_callback(SubGhzProtocolCommon* parser, void* string_clear(output); } -static void subghz_protocol_parser_rx_callback(SubGhzProtocolCommon* parser, void* context) { - SubGhzProtocol* instance = context; +static void subghz_parser_parser_rx_callback(SubGhzProtocolCommon* parser, void* context) { + SubGhzParser* instance = context; if(instance->parser_callback) { instance->parser_callback(parser, instance->parser_callback_context); } } -SubGhzProtocol* subghz_protocol_alloc() { - SubGhzProtocol* instance = furi_alloc(sizeof(SubGhzProtocol)); +SubGhzParser* subghz_parser_alloc() { + SubGhzParser* instance = furi_alloc(sizeof(SubGhzParser)); instance->keystore = subghz_keystore_alloc(); @@ -96,7 +97,7 @@ SubGhzProtocol* subghz_protocol_alloc() { return instance; } -void subghz_protocol_free(SubGhzProtocol* instance) { +void subghz_parser_free(SubGhzParser* instance) { furi_assert(instance); subghz_protocol_came_free((SubGhzProtocolCame*)instance->protocols[SubGhzProtocolTypeCame]); @@ -125,7 +126,7 @@ void subghz_protocol_free(SubGhzProtocol* instance) { free(instance); } -SubGhzProtocolCommon* subghz_protocol_get_by_name(SubGhzProtocol* instance, const char* name) { +SubGhzProtocolCommon* subghz_parser_get_by_name(SubGhzParser* instance, const char* name) { SubGhzProtocolCommon* result = NULL; for(size_t i = 0; i < SubGhzProtocolTypeMax; i++) { @@ -138,46 +139,46 @@ SubGhzProtocolCommon* subghz_protocol_get_by_name(SubGhzProtocol* instance, cons return result; } -void subghz_protocol_enable_dump_text( - SubGhzProtocol* instance, +void subghz_parser_enable_dump_text( + SubGhzParser* instance, SubGhzProtocolTextCallback callback, void* context) { furi_assert(instance); for(size_t i = 0; i < SubGhzProtocolTypeMax; i++) { subghz_protocol_common_set_callback( - instance->protocols[i], subghz_protocol_text_rx_callback, instance); + instance->protocols[i], subghz_parser_text_rx_callback, instance); } instance->text_callback = callback; instance->text_callback_context = context; } -void subghz_protocol_enable_dump( - SubGhzProtocol* instance, +void subghz_parser_enable_dump( + SubGhzParser* instance, SubGhzProtocolCommonCallbackDump callback, void* context) { furi_assert(instance); for(size_t i = 0; i < SubGhzProtocolTypeMax; i++) { subghz_protocol_common_set_callback( - instance->protocols[i], subghz_protocol_parser_rx_callback, instance); + instance->protocols[i], subghz_parser_parser_rx_callback, instance); } instance->parser_callback = callback; instance->parser_callback_context = context; } -void subghz_protocol_load_nice_flor_s_file(SubGhzProtocol* instance, const char* file_name) { +void subghz_parser_load_nice_flor_s_file(SubGhzParser* instance, const char* file_name) { subghz_protocol_nice_flor_s_name_file( (SubGhzProtocolNiceFlorS*)instance->protocols[SubGhzProtocolTypeNiceFlorS], file_name); } -void subghz_protocol_load_keeloq_file(SubGhzProtocol* instance, const char* file_name) { +void subghz_parser_load_keeloq_file(SubGhzParser* instance, const char* file_name) { subghz_keystore_load(instance->keystore, file_name); } -void subghz_protocol_reset(SubGhzProtocol* instance) { +void subghz_parser_reset(SubGhzParser* instance) { subghz_protocol_came_reset((SubGhzProtocolCame*)instance->protocols[SubGhzProtocolTypeCame]); subghz_protocol_keeloq_reset( (SubGhzProtocolKeeloq*)instance->protocols[SubGhzProtocolTypeKeeloq]); @@ -200,7 +201,7 @@ void subghz_protocol_reset(SubGhzProtocol* instance) { (SubGhzProtocolNeroRadio*)instance->protocols[SubGhzProtocolTypeNeroRadio]); } -void subghz_protocol_parse(SubGhzProtocol* instance, bool level, uint32_t duration) { +void subghz_parser_parse(SubGhzParser* instance, bool level, uint32_t duration) { subghz_protocol_came_parse( (SubGhzProtocolCame*)instance->protocols[SubGhzProtocolTypeCame], level, duration); subghz_protocol_keeloq_parse( diff --git a/lib/subghz/subghz_parser.h b/lib/subghz/subghz_parser.h new file mode 100644 index 00000000000..69341c18748 --- /dev/null +++ b/lib/subghz/subghz_parser.h @@ -0,0 +1,72 @@ +#pragma once + +#include "protocols/subghz_protocol_common.h" + +typedef void (*SubGhzProtocolTextCallback)(string_t text, void* context); +typedef void (*SubGhzProtocolCommonCallbackDump)(SubGhzProtocolCommon *parser, void* context); + +typedef struct SubGhzParser SubGhzParser; + +/** Allocate SubGhzParser + * + * @return SubGhzParser* + */ +SubGhzParser* subghz_parser_alloc(); + +/** Free SubGhzParser + * + * @param instance + */ +void subghz_parser_free(SubGhzParser* instance); + +/** Get protocol by name + * + * @param instance - SubGhzParser instance + * @param name - name protocol + * @param SubGhzProtocolCommon + */ +SubGhzProtocolCommon* subghz_parser_get_by_name(SubGhzParser* instance, const char* name); + +/** Outputting data text from all parsers + * + * @param instance - SubGhzParser instance + * @param callback - SubGhzProtocolTextCallback callback + * @param context + */ +void subghz_parser_enable_dump_text(SubGhzParser* instance, SubGhzProtocolTextCallback callback, void* context); + +/** Outputting data SubGhzParser from all parsers + * + * @param instance - SubGhzParser instance + * @param callback - SubGhzProtocolTextCallback callback + * @param context + */ +void subghz_parser_enable_dump(SubGhzParser* instance, SubGhzProtocolCommonCallbackDump callback, void* context); + +/** File name rainbow table Nice Flor-S + * + * @param instance - SubGhzParser instance + * @param file_name - "path/file_name" + */ +void subghz_parser_load_nice_flor_s_file(SubGhzParser* instance, const char* file_name); + +/** File upload manufacture keys + * + * @param instance - SubGhzParser instance + * @param file_name - "path/file_name" + */ +void subghz_parser_load_keeloq_file(SubGhzParser* instance, const char* file_name); + +/** Restarting all parsers + * + * @param instance - SubGhzParser instance + */ +void subghz_parser_reset(SubGhzParser* instance); + +/** Loading data into all parsers + * + * @param instance - SubGhzParser instance + * @param level - true is high, false if low + * @param duration - level duration in microseconds + */ +void subghz_parser_parse(SubGhzParser* instance, bool level, uint32_t duration); diff --git a/lib/toolbox/args.c b/lib/toolbox/args.c index b5f248784b5..b347b42ec55 100644 --- a/lib/toolbox/args.c +++ b/lib/toolbox/args.c @@ -14,6 +14,22 @@ size_t args_length(string_t args) { return string_size(args); } +bool args_read_int_and_trim(string_t args, int* value) { + size_t cmd_length = args_get_first_word_length(args); + + if(cmd_length == 0) { + return false; + } + + if (sscanf(string_get_cstr(args), "%d", value) == 1) { + string_right(args, cmd_length); + string_strim(args); + return true; + } + + return false; +} + bool args_read_string_and_trim(string_t args, string_t word) { size_t cmd_length = args_get_first_word_length(args); @@ -60,12 +76,12 @@ bool args_char_to_hex(char hi_nibble, char low_nibble, uint8_t* byte) { return result; } -bool args_read_hex_bytes(string_t args, uint8_t* bytes, uint8_t bytes_count) { +bool args_read_hex_bytes(string_t args, uint8_t* bytes, size_t bytes_count) { bool result = true; const char* str_pointer = string_get_cstr(args); if(args_get_first_word_length(args) == (bytes_count * 2)) { - for(uint8_t i = 0; i < bytes_count; i++) { + for(size_t i = 0; i < bytes_count; i++) { if(!args_char_to_hex(str_pointer[i * 2], str_pointer[i * 2 + 1], &(bytes[i]))) { result = false; break; diff --git a/lib/toolbox/args.h b/lib/toolbox/args.h index e6c35e5695b..4ae1e1db889 100644 --- a/lib/toolbox/args.h +++ b/lib/toolbox/args.h @@ -8,6 +8,15 @@ extern "C" { #endif +/** Extract int value and trim arguments string + * + * @param args - arguments string + * @param word first argument, output + * @return true - success + * @return false - arguments string does not contain int + */ +bool args_read_int_and_trim(string_t args, int* value); + /** * @brief Extract first argument from arguments string and trim arguments string * @@ -37,7 +46,7 @@ bool args_read_probably_quoted_string_and_trim(string_t args, string_t word); * @return true - success * @return false - arguments string does not contain enough values, or contain non-hex ASCII values */ -bool args_read_hex_bytes(string_t args, uint8_t* bytes, uint8_t bytes_count); +bool args_read_hex_bytes(string_t args, uint8_t* bytes, size_t bytes_count); /************************************ HELPERS ***************************************/ diff --git a/scripts/storage.py b/scripts/storage.py index 739686b693c..a56dcd8b9b9 100755 --- a/scripts/storage.py +++ b/scripts/storage.py @@ -1,12 +1,15 @@ #!/usr/bin/env python3 from flipper.storage import FlipperStorage + import logging import argparse import os import sys import binascii import posixpath +import filecmp +import tempfile class Main: @@ -56,6 +59,16 @@ def __init__(self): self.parser_list.add_argument("flipper_path", help="Flipper path", default="/") self.parser_list.set_defaults(func=self.list) + self.parser_stress = self.subparsers.add_parser("stress", help="Stress test") + self.parser.add_argument( + "-c", "--count", type=int, default=10, help="Iteration count" + ) + self.parser_stress.add_argument("flipper_path", help="Flipper path") + self.parser_stress.add_argument( + "file_size", type=int, help="Test file size in bytes" + ) + self.parser_stress.set_defaults(func=self.stress) + # logging self.logger = logging.getLogger() @@ -262,6 +275,41 @@ def list(self): storage.list_tree(self.args.flipper_path) storage.stop() + def stress(self): + self.logger.error("This test is wearing out flash memory.") + self.logger.error("Never use it with internal storage(/int)") + + if self.args.flipper_path.startswith( + "/int" + ) or self.args.flipper_path.startswith("/any"): + self.logger.error("Stop at this point or device warranty will be void") + say = input("Anything to say? ").strip().lower() + if say != "void": + return + say = input("Why, Mr. Anderson? ").strip().lower() + if say != "because": + return + + with tempfile.TemporaryDirectory() as tmpdirname: + send_file_name = os.path.join(tmpdirname, "send") + receive_file_name = os.path.join(tmpdirname, "receive") + open(send_file_name, "w").write("A" * self.args.file_size) + storage = FlipperStorage(self.args.port) + storage.start() + if storage.exist_file(self.args.flipper_path): + self.logger.error("File exists, remove it first") + return + while self.args.count > 0: + storage.send_file(send_file_name, self.args.flipper_path) + storage.receive_file(self.args.flipper_path, receive_file_name) + if not filecmp.cmp(receive_file_name, send_file_name): + self.logger.error("Files mismatch") + break + storage.remove(self.args.flipper_path) + os.unlink(receive_file_name) + self.args.count -= 1 + storage.stop() + if __name__ == "__main__": Main()()