[FL-2204] Bluetooth forget devices (#967)
* bt: update connection parameters * bt: set correct connection latency and timeout * gui popup: add clean method * furi_hal_bt: add connection parameters request, clear database * bt: add forget bonded devices API * bt_settings: add forget bonded devices GUI * bt: rework pin code show with view port to hide view * bt: support conn parameters for different profiles * furi_hal_bt: sync f6 target * target f6: fix build * bt: format sources * furi_hal_bt: update connection parameters * bt: update connection params, fix GUI * FuriHal: fix spelling * Refactoring: rename _clean to _reset Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									d4787e859e
								
							
						
					
					
						commit
						23ff6723cf
					
				| @ -75,5 +75,5 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) { | ||||
| void archive_scene_rename_on_exit(void* context) { | ||||
|     ArchiveApp* archive = (ArchiveApp*)context; | ||||
|     // Clear view
 | ||||
|     text_input_clean(archive->text_input); | ||||
|     text_input_reset(archive->text_input); | ||||
| } | ||||
|  | ||||
| @ -2,7 +2,8 @@ | ||||
| #include "battery_service.h" | ||||
| #include "bt_keys_storage.h" | ||||
| 
 | ||||
| #include <applications/notification/notification_messages.h> | ||||
| #include <notification/notification_messages.h> | ||||
| #include <gui/elements.h> | ||||
| 
 | ||||
| #define TAG "BtSrv" | ||||
| 
 | ||||
| @ -29,17 +30,46 @@ static ViewPort* bt_statusbar_view_port_alloc(Bt* bt) { | ||||
|     return statusbar_view_port; | ||||
| } | ||||
| 
 | ||||
| static void bt_pin_code_show_event_handler(Bt* bt, uint32_t pin) { | ||||
|     furi_assert(bt); | ||||
| static void bt_pin_code_view_port_draw_callback(Canvas* canvas, void* context) { | ||||
|     furi_assert(context); | ||||
|     Bt* bt = context; | ||||
|     char pin_code_info[24]; | ||||
|     canvas_draw_icon(canvas, 0, 0, &I_BLE_Pairing_128x64); | ||||
|     snprintf(pin_code_info, sizeof(pin_code_info), "Pairing code\n%06ld", bt->pin_code); | ||||
|     elements_multiline_text_aligned(canvas, 64, 4, AlignCenter, AlignTop, pin_code_info); | ||||
|     elements_button_left(canvas, "Quit"); | ||||
| } | ||||
| 
 | ||||
| static void bt_pin_code_view_port_input_callback(InputEvent* event, void* context) { | ||||
|     furi_assert(context); | ||||
|     Bt* bt = context; | ||||
|     if(event->type == InputTypeShort) { | ||||
|         if(event->key == InputKeyLeft || event->key == InputKeyBack) { | ||||
|             view_port_enabled_set(bt->pin_code_view_port, false); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static ViewPort* bt_pin_code_view_port_alloc(Bt* bt) { | ||||
|     ViewPort* view_port = view_port_alloc(); | ||||
|     view_port_draw_callback_set(view_port, bt_pin_code_view_port_draw_callback, bt); | ||||
|     view_port_input_callback_set(view_port, bt_pin_code_view_port_input_callback, bt); | ||||
|     view_port_enabled_set(view_port, false); | ||||
|     return view_port; | ||||
| } | ||||
| 
 | ||||
| static void bt_pin_code_show(Bt* bt, uint32_t pin_code) { | ||||
|     bt->pin_code = pin_code; | ||||
|     notification_message(bt->notification, &sequence_display_on); | ||||
|     string_t pin_str; | ||||
|     dialog_message_set_icon(bt->dialog_message, &I_BLE_Pairing_128x64, 0, 0); | ||||
|     string_init_printf(pin_str, "Pairing code\n%06d", pin); | ||||
|     dialog_message_set_text( | ||||
|         bt->dialog_message, string_get_cstr(pin_str), 64, 4, AlignCenter, AlignTop); | ||||
|     dialog_message_set_buttons(bt->dialog_message, "Quit", NULL, NULL); | ||||
|     dialog_message_show(bt->dialogs, bt->dialog_message); | ||||
|     string_clear(pin_str); | ||||
|     gui_view_port_send_to_front(bt->gui, bt->pin_code_view_port); | ||||
|     view_port_enabled_set(bt->pin_code_view_port, true); | ||||
| } | ||||
| 
 | ||||
| static void bt_pin_code_hide(Bt* bt) { | ||||
|     bt->pin_code = 0; | ||||
|     if(view_port_is_enabled(bt->pin_code_view_port)) { | ||||
|         view_port_enabled_set(bt->pin_code_view_port, false); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static bool bt_pin_code_verify_event_handler(Bt* bt, uint32_t pin) { | ||||
| @ -84,11 +114,14 @@ Bt* bt_alloc() { | ||||
| 
 | ||||
|     // Setup statusbar view port
 | ||||
|     bt->statusbar_view_port = bt_statusbar_view_port_alloc(bt); | ||||
|     // Pin code view port
 | ||||
|     bt->pin_code_view_port = bt_pin_code_view_port_alloc(bt); | ||||
|     // Notification
 | ||||
|     bt->notification = furi_record_open("notification"); | ||||
|     // Gui
 | ||||
|     bt->gui = furi_record_open("gui"); | ||||
|     gui_add_view_port(bt->gui, bt->statusbar_view_port, GuiLayerStatusBarLeft); | ||||
|     gui_add_view_port(bt->gui, bt->pin_code_view_port, GuiLayerFullscreen); | ||||
| 
 | ||||
|     // Dialogs
 | ||||
|     bt->dialogs = furi_record_open("dialogs"); | ||||
| @ -162,7 +195,7 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) { | ||||
|     if(event.type == GapEventTypeConnected) { | ||||
|         // Update status bar
 | ||||
|         bt->status = BtStatusConnected; | ||||
|         BtMessage message = {.type = BtMessageTypeUpdateStatusbar}; | ||||
|         BtMessage message = {.type = BtMessageTypeUpdateStatus}; | ||||
|         furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); | ||||
|         if(bt->profile == BtProfileSerial) { | ||||
|             // Open RPC session
 | ||||
| @ -192,12 +225,12 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) { | ||||
|         ret = true; | ||||
|     } else if(event.type == GapEventTypeStartAdvertising) { | ||||
|         bt->status = BtStatusAdvertising; | ||||
|         BtMessage message = {.type = BtMessageTypeUpdateStatusbar}; | ||||
|         BtMessage message = {.type = BtMessageTypeUpdateStatus}; | ||||
|         furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); | ||||
|         ret = true; | ||||
|     } else if(event.type == GapEventTypeStopAdvertising) { | ||||
|         bt->status = BtStatusOff; | ||||
|         BtMessage message = {.type = BtMessageTypeUpdateStatusbar}; | ||||
|         BtMessage message = {.type = BtMessageTypeUpdateStatus}; | ||||
|         furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); | ||||
|         ret = true; | ||||
|     } else if(event.type == GapEventTypePinCodeShow) { | ||||
| @ -313,9 +346,10 @@ int32_t bt_srv() { | ||||
|     BtMessage message; | ||||
|     while(1) { | ||||
|         furi_check(osMessageQueueGet(bt->message_queue, &message, NULL, osWaitForever) == osOK); | ||||
|         if(message.type == BtMessageTypeUpdateStatusbar) { | ||||
|             // Update statusbar
 | ||||
|         if(message.type == BtMessageTypeUpdateStatus) { | ||||
|             // Update view ports
 | ||||
|             bt_statusbar_update(bt); | ||||
|             bt_pin_code_hide(bt); | ||||
|             if(bt->status_changed_cb) { | ||||
|                 bt->status_changed_cb(bt->status, bt->status_changed_ctx); | ||||
|             } | ||||
| @ -324,11 +358,13 @@ int32_t bt_srv() { | ||||
|             furi_hal_bt_update_battery_level(message.data.battery_level); | ||||
|         } else if(message.type == BtMessageTypePinCodeShow) { | ||||
|             // Display PIN code
 | ||||
|             bt_pin_code_show_event_handler(bt, message.data.pin_code); | ||||
|             bt_pin_code_show(bt, message.data.pin_code); | ||||
|         } else if(message.type == BtMessageTypeKeysStorageUpdated) { | ||||
|             bt_save_key_storage(bt); | ||||
|         } else if(message.type == BtMessageTypeSetProfile) { | ||||
|             bt_change_profile(bt, &message); | ||||
|         } else if(message.type == BtMessageTypeForgetBondedDevices) { | ||||
|             bt_delete_key_storage(bt); | ||||
|         } | ||||
|     } | ||||
|     return 0; | ||||
|  | ||||
| @ -41,6 +41,13 @@ bool bt_set_profile(Bt* bt, BtProfile profile); | ||||
|  */ | ||||
| void bt_set_status_changed_callback(Bt* bt, BtStatusChangedCallback callback, void* context); | ||||
| 
 | ||||
| /** Forget bonded devices
 | ||||
|  * @note Leads to wipe ble key storage and deleting bt.keys | ||||
|  * | ||||
|  * @param bt        Bt instance | ||||
|  */ | ||||
| void bt_forget_bonded_devices(Bt* bt); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
| @ -20,3 +20,9 @@ void bt_set_status_changed_callback(Bt* bt, BtStatusChangedCallback callback, vo | ||||
|     bt->status_changed_cb = callback; | ||||
|     bt->status_changed_ctx = context; | ||||
| } | ||||
| 
 | ||||
| void bt_forget_bonded_devices(Bt* bt) { | ||||
|     furi_assert(bt); | ||||
|     BtMessage message = {.type = BtMessageTypeForgetBondedDevices}; | ||||
|     furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); | ||||
| } | ||||
|  | ||||
| @ -19,11 +19,12 @@ | ||||
| #define BT_API_UNLOCK_EVENT (1UL << 0) | ||||
| 
 | ||||
| typedef enum { | ||||
|     BtMessageTypeUpdateStatusbar, | ||||
|     BtMessageTypeUpdateStatus, | ||||
|     BtMessageTypeUpdateBatteryLevel, | ||||
|     BtMessageTypePinCodeShow, | ||||
|     BtMessageTypeKeysStorageUpdated, | ||||
|     BtMessageTypeSetProfile, | ||||
|     BtMessageTypeForgetBondedDevices, | ||||
| } BtMessageType; | ||||
| 
 | ||||
| typedef union { | ||||
| @ -49,6 +50,8 @@ struct Bt { | ||||
|     NotificationApp* notification; | ||||
|     Gui* gui; | ||||
|     ViewPort* statusbar_view_port; | ||||
|     ViewPort* pin_code_view_port; | ||||
|     uint32_t pin_code; | ||||
|     DialogsApp* dialogs; | ||||
|     DialogMessage* dialog_message; | ||||
|     Power* power; | ||||
|  | ||||
| @ -39,3 +39,16 @@ bool bt_save_key_storage(Bt* bt) { | ||||
|     file_worker_free(file_worker); | ||||
|     return file_saved; | ||||
| } | ||||
| 
 | ||||
| bool bt_delete_key_storage(Bt* bt) { | ||||
|     furi_assert(bt); | ||||
|     bool delete_succeed = false; | ||||
| 
 | ||||
|     furi_hal_bt_stop_advertising(); | ||||
|     delete_succeed = furi_hal_bt_clear_white_list(); | ||||
|     if(bt->bt_settings.enabled) { | ||||
|         furi_hal_bt_start_advertising(); | ||||
|     } | ||||
| 
 | ||||
|     return delete_succeed; | ||||
| } | ||||
|  | ||||
| @ -5,3 +5,5 @@ | ||||
| bool bt_load_key_storage(Bt* bt); | ||||
| 
 | ||||
| bool bt_save_key_storage(Bt* bt); | ||||
| 
 | ||||
| bool bt_delete_key_storage(Bt* bt); | ||||
|  | ||||
| @ -18,7 +18,9 @@ BtSettingsApp* bt_settings_app_alloc() { | ||||
|     // Load settings
 | ||||
|     bt_settings_load(&app->settings); | ||||
|     app->gui = furi_record_open("gui"); | ||||
|     app->bt = furi_record_open("bt"); | ||||
| 
 | ||||
|     // View Dispatcher and Scene Manager
 | ||||
|     app->view_dispatcher = view_dispatcher_alloc(); | ||||
|     app->scene_manager = scene_manager_alloc(&bt_settings_scene_handlers, app); | ||||
|     view_dispatcher_enable_queue(app->view_dispatcher); | ||||
| @ -31,26 +33,45 @@ BtSettingsApp* bt_settings_app_alloc() { | ||||
| 
 | ||||
|     view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); | ||||
| 
 | ||||
|     // Gui Modules
 | ||||
|     app->var_item_list = variable_item_list_alloc(); | ||||
|     view_dispatcher_add_view( | ||||
|         app->view_dispatcher, | ||||
|         BtSettingsAppViewVarItemList, | ||||
|         variable_item_list_get_view(app->var_item_list)); | ||||
| 
 | ||||
|     app->dialog = dialog_ex_alloc(); | ||||
|     view_dispatcher_add_view( | ||||
|         app->view_dispatcher, BtSettingsAppViewDialog, dialog_ex_get_view(app->dialog)); | ||||
| 
 | ||||
|     app->popup = popup_alloc(); | ||||
|     view_dispatcher_add_view( | ||||
|         app->view_dispatcher, BtSettingsAppViewPopup, popup_get_view(app->popup)); | ||||
| 
 | ||||
|     // Set first scene
 | ||||
|     scene_manager_next_scene(app->scene_manager, BtSettingsAppSceneStart); | ||||
|     return app; | ||||
| } | ||||
| 
 | ||||
| void bt_settings_app_free(BtSettingsApp* app) { | ||||
|     furi_assert(app); | ||||
|     // Variable item list
 | ||||
|     // Gui modules
 | ||||
|     view_dispatcher_remove_view(app->view_dispatcher, BtSettingsAppViewVarItemList); | ||||
|     variable_item_list_free(app->var_item_list); | ||||
|     // View dispatcher
 | ||||
| 
 | ||||
|     view_dispatcher_remove_view(app->view_dispatcher, BtSettingsAppViewDialog); | ||||
|     dialog_ex_free(app->dialog); | ||||
| 
 | ||||
|     view_dispatcher_remove_view(app->view_dispatcher, BtSettingsAppViewPopup); | ||||
|     popup_free(app->popup); | ||||
| 
 | ||||
|     // View Dispatcher and Scene Manager
 | ||||
|     view_dispatcher_free(app->view_dispatcher); | ||||
|     scene_manager_free(app->scene_manager); | ||||
| 
 | ||||
|     // Records
 | ||||
|     furi_record_close("gui"); | ||||
|     furi_record_close("bt"); | ||||
|     free(app); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,22 +1,33 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <furi.h> | ||||
| #include <bt/bt_service/bt.h> | ||||
| #include <gui/gui.h> | ||||
| #include <gui/view.h> | ||||
| #include <gui/view_dispatcher.h> | ||||
| #include <gui/scene_manager.h> | ||||
| 
 | ||||
| #include <gui/modules/variable_item_list.h> | ||||
| #include <gui/modules/dialog_ex.h> | ||||
| #include <gui/modules/popup.h> | ||||
| 
 | ||||
| #include "../bt_settings.h" | ||||
| #include "scenes/bt_settings_scene.h" | ||||
| 
 | ||||
| typedef struct { | ||||
|     BtSettings settings; | ||||
|     Bt* bt; | ||||
|     Gui* gui; | ||||
|     SceneManager* scene_manager; | ||||
|     ViewDispatcher* view_dispatcher; | ||||
| 
 | ||||
|     VariableItemList* var_item_list; | ||||
|     DialogEx* dialog; | ||||
|     Popup* popup; | ||||
| } BtSettingsApp; | ||||
| 
 | ||||
| typedef enum { BtSettingsAppViewVarItemList } BtSettingsAppView; | ||||
| typedef enum { | ||||
|     BtSettingsAppViewVarItemList, | ||||
|     BtSettingsAppViewDialog, | ||||
|     BtSettingsAppViewPopup, | ||||
| } BtSettingsAppView; | ||||
|  | ||||
							
								
								
									
										2
									
								
								applications/bt/bt_settings_app/scenes/bt_settings_scene_config.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										2
									
								
								applications/bt/bt_settings_app/scenes/bt_settings_scene_config.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @ -1 +1,3 @@ | ||||
| ADD_SCENE(bt_settings, start, Start) | ||||
| ADD_SCENE(bt_settings, forget_dev_confirm, ForgetDevConfirm) | ||||
| ADD_SCENE(bt_settings, forget_dev_success, ForgetDevSuccess) | ||||
|  | ||||
| @ -0,0 +1,44 @@ | ||||
| #include "../bt_settings_app.h" | ||||
| #include "furi_hal_bt.h" | ||||
| 
 | ||||
| void bt_settings_scene_forget_dev_confirm_dialog_callback(DialogExResult result, void* context) { | ||||
|     furi_assert(context); | ||||
|     BtSettingsApp* app = context; | ||||
|     view_dispatcher_send_custom_event(app->view_dispatcher, result); | ||||
| } | ||||
| 
 | ||||
| void bt_settings_scene_forget_dev_confirm_on_enter(void* context) { | ||||
|     BtSettingsApp* app = context; | ||||
|     DialogEx* dialog = app->dialog; | ||||
|     dialog_ex_set_header(dialog, "Unpair all devices?", 64, 3, AlignCenter, AlignTop); | ||||
|     dialog_ex_set_text( | ||||
|         dialog, "All previous pairings\nwill be lost.", 64, 22, AlignCenter, AlignTop); | ||||
|     dialog_ex_set_left_button_text(dialog, "Back"); | ||||
|     dialog_ex_set_right_button_text(dialog, "Unpair"); | ||||
|     dialog_ex_set_context(dialog, app); | ||||
|     dialog_ex_set_result_callback(dialog, bt_settings_scene_forget_dev_confirm_dialog_callback); | ||||
| 
 | ||||
|     view_dispatcher_switch_to_view(app->view_dispatcher, BtSettingsAppViewDialog); | ||||
| } | ||||
| 
 | ||||
| bool bt_settings_scene_forget_dev_confirm_on_event(void* context, SceneManagerEvent event) { | ||||
|     BtSettingsApp* app = context; | ||||
|     bool consumed = false; | ||||
| 
 | ||||
|     if(event.type == SceneManagerEventTypeCustom) { | ||||
|         if(event.event == DialogExResultLeft) { | ||||
|             consumed = scene_manager_previous_scene(app->scene_manager); | ||||
|         } else if(event.event == DialogExResultRight) { | ||||
|             bt_forget_bonded_devices(app->bt); | ||||
|             scene_manager_next_scene(app->scene_manager, BtSettingsAppSceneForgetDevSuccess); | ||||
|             consumed = true; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return consumed; | ||||
| } | ||||
| 
 | ||||
| void bt_settings_scene_forget_dev_confirm_on_exit(void* context) { | ||||
|     BtSettingsApp* app = context; | ||||
|     dialog_ex_reset(app->dialog); | ||||
| } | ||||
| @ -0,0 +1,43 @@ | ||||
| #include "../bt_settings_app.h" | ||||
| #include "furi_hal_bt.h" | ||||
| 
 | ||||
| #define SCENE_FORGET_DEV_SUCCESS_CUSTOM_EVENT (0UL) | ||||
| 
 | ||||
| void bt_settings_app_scene_forget_dev_success_popup_callback(void* context) { | ||||
|     BtSettingsApp* app = context; | ||||
|     view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_FORGET_DEV_SUCCESS_CUSTOM_EVENT); | ||||
| } | ||||
| 
 | ||||
| void bt_settings_scene_forget_dev_success_on_enter(void* context) { | ||||
|     BtSettingsApp* app = context; | ||||
|     Popup* popup = app->popup; | ||||
| 
 | ||||
|     popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); | ||||
|     popup_set_header(popup, "Done", 14, 15, AlignLeft, AlignTop); | ||||
|     popup_set_timeout(popup, 1500); | ||||
|     popup_set_context(popup, app); | ||||
|     popup_set_callback(popup, bt_settings_app_scene_forget_dev_success_popup_callback); | ||||
|     popup_enable_timeout(popup); | ||||
|     view_dispatcher_switch_to_view(app->view_dispatcher, BtSettingsAppViewPopup); | ||||
| } | ||||
| 
 | ||||
| bool bt_settings_scene_forget_dev_success_on_event(void* context, SceneManagerEvent event) { | ||||
|     BtSettingsApp* app = context; | ||||
|     bool consumed = false; | ||||
| 
 | ||||
|     if(event.type == SceneManagerEventTypeCustom) { | ||||
|         if(event.event == SCENE_FORGET_DEV_SUCCESS_CUSTOM_EVENT) { | ||||
|             if(scene_manager_has_previous_scene(app->scene_manager, BtSettingsAppSceneStart)) { | ||||
|                 consumed = scene_manager_search_and_switch_to_previous_scene( | ||||
|                     app->scene_manager, BtSettingsAppSceneStart); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return consumed; | ||||
| } | ||||
| 
 | ||||
| void bt_settings_scene_forget_dev_success_on_exit(void* context) { | ||||
|     BtSettingsApp* app = context; | ||||
|     popup_reset(app->popup); | ||||
| } | ||||
| @ -1,6 +1,8 @@ | ||||
| #include "../bt_settings_app.h" | ||||
| #include "furi_hal_bt.h" | ||||
| 
 | ||||
| #define SCENE_START_FORGET_DEV_SELECTED_EVENT (10UL) | ||||
| 
 | ||||
| enum BtSetting { | ||||
|     BtSettingOff, | ||||
|     BtSettingOn, | ||||
| @ -8,8 +10,8 @@ enum BtSetting { | ||||
| }; | ||||
| 
 | ||||
| const char* const bt_settings_text[BtSettingNum] = { | ||||
|     "Off", | ||||
|     "On", | ||||
|     "OFF", | ||||
|     "ON", | ||||
| }; | ||||
| 
 | ||||
| static void bt_settings_scene_start_var_list_change_callback(VariableItem* item) { | ||||
| @ -20,6 +22,12 @@ static void bt_settings_scene_start_var_list_change_callback(VariableItem* item) | ||||
|     view_dispatcher_send_custom_event(app->view_dispatcher, index); | ||||
| } | ||||
| 
 | ||||
| static void bt_settings_scene_start_var_list_enter_callback(void* context, uint32_t index) { | ||||
|     furi_assert(context); | ||||
|     BtSettingsApp* app = context; | ||||
|     view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_START_FORGET_DEV_SELECTED_EVENT); | ||||
| } | ||||
| 
 | ||||
| void bt_settings_scene_start_on_enter(void* context) { | ||||
|     BtSettingsApp* app = context; | ||||
|     VariableItemList* var_item_list = app->var_item_list; | ||||
| @ -40,6 +48,9 @@ void bt_settings_scene_start_on_enter(void* context) { | ||||
|             variable_item_set_current_value_index(item, BtSettingOff); | ||||
|             variable_item_set_current_value_text(item, bt_settings_text[BtSettingOff]); | ||||
|         } | ||||
|         variable_item_list_add(var_item_list, "Forget all paired devices", 1, NULL, NULL); | ||||
|         variable_item_list_set_enter_callback( | ||||
|             var_item_list, bt_settings_scene_start_var_list_enter_callback, app); | ||||
|     } else { | ||||
|         item = variable_item_list_add(var_item_list, "Bluetooth", 1, NULL, NULL); | ||||
|         variable_item_set_current_value_text(item, "Broken"); | ||||
| @ -56,16 +67,20 @@ bool bt_settings_scene_start_on_event(void* context, SceneManagerEvent event) { | ||||
|         if(event.event == BtSettingOn) { | ||||
|             furi_hal_bt_start_advertising(); | ||||
|             app->settings.enabled = true; | ||||
|             consumed = true; | ||||
|         } else if(event.event == BtSettingOff) { | ||||
|             app->settings.enabled = false; | ||||
|             furi_hal_bt_stop_advertising(); | ||||
|         } | ||||
|             consumed = true; | ||||
|         } else if(event.event == SCENE_START_FORGET_DEV_SELECTED_EVENT) { | ||||
|             scene_manager_next_scene(app->scene_manager, BtSettingsAppSceneForgetDevConfirm); | ||||
|             consumed = true; | ||||
|         } | ||||
|     } | ||||
|     return consumed; | ||||
| } | ||||
| 
 | ||||
| void bt_settings_scene_start_on_exit(void* context) { | ||||
|     BtSettingsApp* app = context; | ||||
|     variable_item_list_clean(app->var_item_list); | ||||
|     variable_item_list_reset(app->var_item_list); | ||||
| } | ||||
|  | ||||
| @ -10,7 +10,7 @@ static void desktop_settings_scene_favorite_submenu_callback(void* context, uint | ||||
| void desktop_settings_scene_favorite_on_enter(void* context) { | ||||
|     DesktopSettingsApp* app = context; | ||||
|     Submenu* submenu = app->submenu; | ||||
|     submenu_clean(submenu); | ||||
|     submenu_reset(submenu); | ||||
| 
 | ||||
|     for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) { | ||||
|         submenu_add_item( | ||||
| @ -45,5 +45,5 @@ bool desktop_settings_scene_favorite_on_event(void* context, SceneManagerEvent e | ||||
| void desktop_settings_scene_favorite_on_exit(void* context) { | ||||
|     DesktopSettingsApp* app = context; | ||||
|     SAVE_DESKTOP_SETTINGS(&app->settings); | ||||
|     submenu_clean(app->submenu); | ||||
|     submenu_reset(app->submenu); | ||||
| } | ||||
|  | ||||
| @ -9,7 +9,7 @@ static void desktop_settings_scene_pincode_menu_submenu_callback(void* context, | ||||
| void desktop_settings_scene_pincode_menu_on_enter(void* context) { | ||||
|     DesktopSettingsApp* app = context; | ||||
|     Submenu* submenu = app->submenu; | ||||
|     submenu_clean(submenu); | ||||
|     submenu_reset(submenu); | ||||
| 
 | ||||
|     if(!app->settings.pincode.length) { | ||||
|         submenu_add_item( | ||||
| @ -74,5 +74,5 @@ bool desktop_settings_scene_pincode_menu_on_event(void* context, SceneManagerEve | ||||
| 
 | ||||
| void desktop_settings_scene_pincode_menu_on_exit(void* context) { | ||||
|     DesktopSettingsApp* app = context; | ||||
|     submenu_clean(app->submenu); | ||||
|     submenu_reset(app->submenu); | ||||
| } | ||||
|  | ||||
| @ -53,5 +53,5 @@ bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent even | ||||
| 
 | ||||
| void desktop_settings_scene_start_on_exit(void* context) { | ||||
|     DesktopSettingsApp* app = context; | ||||
|     submenu_clean(app->submenu); | ||||
|     submenu_reset(app->submenu); | ||||
| } | ||||
|  | ||||
| @ -95,5 +95,5 @@ bool gpio_scene_start_on_event(void* context, SceneManagerEvent event) { | ||||
| 
 | ||||
| void gpio_scene_start_on_exit(void* context) { | ||||
|     GpioApp* app = context; | ||||
|     variable_item_list_clean(app->var_item_list); | ||||
|     variable_item_list_reset(app->var_item_list); | ||||
| } | ||||
|  | ||||
| @ -135,6 +135,6 @@ void gpio_scene_usb_uart_cfg_on_exit(void* context) { | ||||
|         app->scene_manager, | ||||
|         GpioAppViewUsbUartCfg, | ||||
|         variable_item_list_get_selected_item_index(app->var_item_list)); | ||||
|     variable_item_list_clean(app->var_item_list); | ||||
|     variable_item_list_reset(app->var_item_list); | ||||
|     free(cfg_set); | ||||
| } | ||||
|  | ||||
| @ -241,7 +241,7 @@ View* button_menu_get_view(ButtonMenu* button_menu) { | ||||
|     return button_menu->view; | ||||
| } | ||||
| 
 | ||||
| void button_menu_clean(ButtonMenu* button_menu) { | ||||
| void button_menu_reset(ButtonMenu* button_menu) { | ||||
|     furi_assert(button_menu); | ||||
| 
 | ||||
|     with_view_model( | ||||
|  | ||||
| @ -39,7 +39,7 @@ View* button_menu_get_view(ButtonMenu* button_menu); | ||||
|  * | ||||
|  * @param      button_menu  ButtonMenu instance | ||||
|  */ | ||||
| void button_menu_clean(ButtonMenu* button_menu); | ||||
| void button_menu_reset(ButtonMenu* button_menu); | ||||
| 
 | ||||
| /** Add item to button menu instance
 | ||||
|  * | ||||
|  | ||||
| @ -112,7 +112,7 @@ void button_panel_reserve(ButtonPanel* button_panel, size_t reserve_x, size_t re | ||||
| void button_panel_free(ButtonPanel* button_panel) { | ||||
|     furi_assert(button_panel); | ||||
| 
 | ||||
|     button_panel_clean(button_panel); | ||||
|     button_panel_reset(button_panel); | ||||
| 
 | ||||
|     with_view_model( | ||||
|         button_panel->view, (ButtonPanelModel * model) { | ||||
| @ -125,7 +125,7 @@ void button_panel_free(ButtonPanel* button_panel) { | ||||
|     free(button_panel); | ||||
| } | ||||
| 
 | ||||
| void button_panel_clean(ButtonPanel* button_panel) { | ||||
| void button_panel_reset(ButtonPanel* button_panel) { | ||||
|     furi_assert(button_panel); | ||||
| 
 | ||||
|     with_view_model( | ||||
|  | ||||
| @ -39,7 +39,7 @@ void button_panel_free(ButtonPanel* button_panel); | ||||
|  * | ||||
|  * @param      button_panel  ButtonPanel instance | ||||
|  */ | ||||
| void button_panel_clean(ButtonPanel* button_panel); | ||||
| void button_panel_reset(ButtonPanel* button_panel); | ||||
| 
 | ||||
| /** Reserve space for adding items.
 | ||||
|  * | ||||
|  | ||||
| @ -244,7 +244,7 @@ void dialog_ex_set_right_button_text(DialogEx* dialog_ex, const char* text) { | ||||
|         }); | ||||
| } | ||||
| 
 | ||||
| void dialog_ex_clean(DialogEx* dialog_ex) { | ||||
| void dialog_ex_reset(DialogEx* dialog_ex) { | ||||
|     furi_assert(dialog_ex); | ||||
|     TextElement clean_text_el = { | ||||
|         .text = NULL, .x = 0, .y = 0, .horizontal = AlignLeft, .vertical = AlignLeft}; | ||||
|  | ||||
| @ -143,7 +143,7 @@ void dialog_ex_set_right_button_text(DialogEx* dialog_ex, const char* text); | ||||
|  * | ||||
|  * @param      dialog_ex  DialogEx instance | ||||
|  */ | ||||
| void dialog_ex_clean(DialogEx* dialog_ex); | ||||
| void dialog_ex_reset(DialogEx* dialog_ex); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
|  | ||||
| @ -146,7 +146,7 @@ Menu* menu_alloc() { | ||||
| 
 | ||||
| void menu_free(Menu* menu) { | ||||
|     furi_assert(menu); | ||||
|     menu_clean(menu); | ||||
|     menu_reset(menu); | ||||
|     view_free(menu->view); | ||||
|     free(menu); | ||||
| } | ||||
| @ -180,7 +180,7 @@ void menu_add_item( | ||||
|         }); | ||||
| } | ||||
| 
 | ||||
| void menu_clean(Menu* menu) { | ||||
| void menu_reset(Menu* menu) { | ||||
|     furi_assert(menu); | ||||
|     with_view_model( | ||||
|         menu->view, (MenuModel * model) { | ||||
|  | ||||
| @ -59,7 +59,7 @@ void menu_add_item( | ||||
|  * | ||||
|  * @param      menu  Menu instance | ||||
|  */ | ||||
| void menu_clean(Menu* menu); | ||||
| void menu_reset(Menu* menu); | ||||
| 
 | ||||
| /** Set current menu item
 | ||||
|  * | ||||
|  | ||||
| @ -227,3 +227,19 @@ void popup_enable_timeout(Popup* popup) { | ||||
| void popup_disable_timeout(Popup* popup) { | ||||
|     popup->timer_enabled = false; | ||||
| } | ||||
| 
 | ||||
| void popup_reset(Popup* popup) { | ||||
|     furi_assert(popup); | ||||
| 
 | ||||
|     with_view_model( | ||||
|         popup->view, (PopupModel * model) { | ||||
|             memset(&model->header, 0, sizeof(model->header)); | ||||
|             memset(&model->text, 0, sizeof(model->text)); | ||||
|             memset(&model->icon, 0, sizeof(model->icon)); | ||||
|             return false; | ||||
|         }); | ||||
|     popup->callback = NULL; | ||||
|     popup->context = NULL; | ||||
|     popup->timer_enabled = false; | ||||
|     popup->timer_period_in_ms = 0; | ||||
| } | ||||
|  | ||||
| @ -123,6 +123,12 @@ void popup_enable_timeout(Popup* popup); | ||||
|  */ | ||||
| void popup_disable_timeout(Popup* popup); | ||||
| 
 | ||||
| /** Reset popup instance state
 | ||||
|  * | ||||
|  * @param       popup Popup instance | ||||
|  */ | ||||
| void popup_reset(Popup* popup); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
| @ -177,7 +177,7 @@ void submenu_add_item( | ||||
|         }); | ||||
| } | ||||
| 
 | ||||
| void submenu_clean(Submenu* submenu) { | ||||
| void submenu_reset(Submenu* submenu) { | ||||
|     furi_assert(submenu); | ||||
| 
 | ||||
|     with_view_model( | ||||
|  | ||||
| @ -57,7 +57,7 @@ void submenu_add_item( | ||||
|  * | ||||
|  * @param      submenu  Submenu instance | ||||
|  */ | ||||
| void submenu_clean(Submenu* submenu); | ||||
| void submenu_reset(Submenu* submenu); | ||||
| 
 | ||||
| /** Set submenu item selector
 | ||||
|  * | ||||
|  | ||||
| @ -164,7 +164,7 @@ View* text_box_get_view(TextBox* text_box) { | ||||
|     return text_box->view; | ||||
| } | ||||
| 
 | ||||
| void text_box_clean(TextBox* text_box) { | ||||
| void text_box_reset(TextBox* text_box) { | ||||
|     furi_assert(text_box); | ||||
| 
 | ||||
|     with_view_model( | ||||
|  | ||||
| @ -44,7 +44,7 @@ View* text_box_get_view(TextBox* text_box); | ||||
|  * | ||||
|  * @param      text_box  TextBox instance | ||||
|  */ | ||||
| void text_box_clean(TextBox* text_box); | ||||
| void text_box_reset(TextBox* text_box); | ||||
| 
 | ||||
| /** Set text for text_box
 | ||||
|  * | ||||
|  | ||||
| @ -425,7 +425,7 @@ TextInput* text_input_alloc() { | ||||
|             return false; | ||||
|         }); | ||||
| 
 | ||||
|     text_input_clean(text_input); | ||||
|     text_input_reset(text_input); | ||||
| 
 | ||||
|     return text_input; | ||||
| } | ||||
| @ -450,7 +450,7 @@ void text_input_free(TextInput* text_input) { | ||||
|     free(text_input); | ||||
| } | ||||
| 
 | ||||
| void text_input_clean(TextInput* text_input) { | ||||
| void text_input_reset(TextInput* text_input) { | ||||
|     furi_assert(text_input); | ||||
|     with_view_model( | ||||
|         text_input->view, (TextInputModel * model) { | ||||
|  | ||||
| @ -36,7 +36,7 @@ void text_input_free(TextInput* text_input); | ||||
|  * | ||||
|  * @param      text_input  Text input instance | ||||
|  */ | ||||
| void text_input_clean(TextInput* text_input); | ||||
| void text_input_reset(TextInput* text_input); | ||||
| 
 | ||||
| /** Get text input view
 | ||||
|  * | ||||
|  | ||||
| @ -312,7 +312,7 @@ void variable_item_list_free(VariableItemList* variable_item_list) { | ||||
|     free(variable_item_list); | ||||
| } | ||||
| 
 | ||||
| void variable_item_list_clean(VariableItemList* variable_item_list) { | ||||
| void variable_item_list_reset(VariableItemList* variable_item_list) { | ||||
|     furi_assert(variable_item_list); | ||||
| 
 | ||||
|     with_view_model( | ||||
|  | ||||
| @ -32,7 +32,7 @@ void variable_item_list_free(VariableItemList* variable_item_list); | ||||
|  * | ||||
|  * @param      variable_item_list  VariableItemList instance | ||||
|  */ | ||||
| void variable_item_list_clean(VariableItemList* variable_item_list); | ||||
| void variable_item_list_reset(VariableItemList* variable_item_list); | ||||
| 
 | ||||
| /** Get VariableItemList View instance
 | ||||
|  * | ||||
|  | ||||
| @ -52,7 +52,7 @@ void iButtonSceneAddType::on_exit(iButtonApp* app) { | ||||
|     iButtonAppViewManager* view = app->get_view_manager(); | ||||
|     Submenu* submenu = view->get_submenu(); | ||||
| 
 | ||||
|     submenu_clean(submenu); | ||||
|     submenu_reset(submenu); | ||||
| } | ||||
| 
 | ||||
| void iButtonSceneAddType::submenu_callback(void* context, uint32_t index) { | ||||
|  | ||||
| @ -57,7 +57,7 @@ void iButtonSceneReadedKeyMenu::on_exit(iButtonApp* app) { | ||||
|     iButtonAppViewManager* view = app->get_view_manager(); | ||||
|     Submenu* submenu = view->get_submenu(); | ||||
| 
 | ||||
|     submenu_clean(submenu); | ||||
|     submenu_reset(submenu); | ||||
| } | ||||
| 
 | ||||
| void iButtonSceneReadedKeyMenu::submenu_callback(void* context, uint32_t index) { | ||||
|  | ||||
| @ -48,7 +48,7 @@ bool iButtonSceneSaveName::on_event(iButtonApp* app, iButtonEvent* event) { | ||||
| 
 | ||||
| void iButtonSceneSaveName::on_exit(iButtonApp* app) { | ||||
|     TextInput* text_input = app->get_view_manager()->get_text_input(); | ||||
|     text_input_clean(text_input); | ||||
|     text_input_reset(text_input); | ||||
| } | ||||
| 
 | ||||
| void iButtonSceneSaveName::text_input_callback(void* context) { | ||||
|  | ||||
| @ -59,7 +59,7 @@ void iButtonSceneSavedKeyMenu::on_exit(iButtonApp* app) { | ||||
|     iButtonAppViewManager* view = app->get_view_manager(); | ||||
|     Submenu* submenu = view->get_submenu(); | ||||
| 
 | ||||
|     submenu_clean(submenu); | ||||
|     submenu_reset(submenu); | ||||
| } | ||||
| 
 | ||||
| void iButtonSceneSavedKeyMenu::submenu_callback(void* context, uint32_t index) { | ||||
|  | ||||
| @ -49,7 +49,7 @@ void iButtonSceneStart::on_exit(iButtonApp* app) { | ||||
|     iButtonAppViewManager* view = app->get_view_manager(); | ||||
|     Submenu* submenu = view->get_submenu(); | ||||
| 
 | ||||
|     submenu_clean(submenu); | ||||
|     submenu_reset(submenu); | ||||
| } | ||||
| 
 | ||||
| void iButtonSceneStart::submenu_callback(void* context, uint32_t index) { | ||||
|  | ||||
| @ -75,5 +75,5 @@ void IrdaAppSceneEdit::on_exit(IrdaApp* app) { | ||||
|     IrdaAppViewManager* view_manager = app->get_view_manager(); | ||||
|     Submenu* submenu = view_manager->get_submenu(); | ||||
| 
 | ||||
|     submenu_clean(submenu); | ||||
|     submenu_reset(submenu); | ||||
| } | ||||
|  | ||||
| @ -53,5 +53,5 @@ void IrdaAppSceneEditKeySelect::on_exit(IrdaApp* app) { | ||||
|     IrdaAppViewManager* view_manager = app->get_view_manager(); | ||||
|     Submenu* submenu = view_manager->get_submenu(); | ||||
| 
 | ||||
|     submenu_clean(submenu); | ||||
|     submenu_reset(submenu); | ||||
| } | ||||
|  | ||||
| @ -132,5 +132,5 @@ void IrdaAppSceneRemote::on_exit(IrdaApp* app) { | ||||
|     IrdaAppViewManager* view_manager = app->get_view_manager(); | ||||
|     ButtonMenu* button_menu = view_manager->get_button_menu(); | ||||
| 
 | ||||
|     button_menu_clean(button_menu); | ||||
|     button_menu_reset(button_menu); | ||||
| } | ||||
|  | ||||
| @ -62,5 +62,5 @@ void IrdaAppSceneStart::on_exit(IrdaApp* app) { | ||||
|     Submenu* submenu = view_manager->get_submenu(); | ||||
| 
 | ||||
|     app->get_remote_manager()->reset_remote(); | ||||
|     submenu_clean(submenu); | ||||
|     submenu_reset(submenu); | ||||
| } | ||||
|  | ||||
| @ -53,5 +53,5 @@ void IrdaAppSceneUniversal::on_exit(IrdaApp* app) { | ||||
|     IrdaAppViewManager* view_manager = app->get_view_manager(); | ||||
|     Submenu* submenu = view_manager->get_submenu(); | ||||
| 
 | ||||
|     submenu_clean(submenu); | ||||
|     submenu_reset(submenu); | ||||
| } | ||||
|  | ||||
| @ -102,5 +102,5 @@ bool IrdaAppSceneUniversalCommon::on_event(IrdaApp* app, IrdaAppEvent* event) { | ||||
| void IrdaAppSceneUniversalCommon::on_exit(IrdaApp* app) { | ||||
|     IrdaAppViewManager* view_manager = app->get_view_manager(); | ||||
|     ButtonPanel* button_panel = view_manager->get_button_panel(); | ||||
|     button_panel_clean(button_panel); | ||||
|     button_panel_reset(button_panel); | ||||
| } | ||||
|  | ||||
| @ -429,7 +429,7 @@ void loader_show_menu() { | ||||
| } | ||||
| 
 | ||||
| void loader_update_menu() { | ||||
|     menu_clean(loader_instance->primary_menu); | ||||
|     menu_reset(loader_instance->primary_menu); | ||||
|     loader_build_menu(); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -81,5 +81,5 @@ bool nfc_scene_card_menu_on_event(void* context, SceneManagerEvent event) { | ||||
| void nfc_scene_card_menu_on_exit(void* context) { | ||||
|     Nfc* nfc = (Nfc*)context; | ||||
| 
 | ||||
|     submenu_clean(nfc->submenu); | ||||
|     submenu_reset(nfc->submenu); | ||||
| } | ||||
|  | ||||
| @ -199,7 +199,7 @@ void nfc_scene_device_info_on_exit(void* context) { | ||||
|         dialog_ex_set_context(dialog_ex, NULL); | ||||
|     } else if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) { | ||||
|         // Clear TextBox
 | ||||
|         text_box_clean(nfc->text_box); | ||||
|         text_box_reset(nfc->text_box); | ||||
|         string_reset(nfc->text_box_store); | ||||
|     } else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) { | ||||
|         // Clear Bank Card
 | ||||
|  | ||||
| @ -54,5 +54,5 @@ bool nfc_scene_mifare_ul_menu_on_event(void* context, SceneManagerEvent event) { | ||||
| void nfc_scene_mifare_ul_menu_on_exit(void* context) { | ||||
|     Nfc* nfc = (Nfc*)context; | ||||
| 
 | ||||
|     submenu_clean(nfc->submenu); | ||||
|     submenu_reset(nfc->submenu); | ||||
| } | ||||
|  | ||||
| @ -126,6 +126,6 @@ void nfc_scene_read_mifare_ul_success_on_exit(void* context) { | ||||
| 
 | ||||
|     // Clean TextBox
 | ||||
|     TextBox* text_box = nfc->text_box; | ||||
|     text_box_clean(text_box); | ||||
|     text_box_reset(text_box); | ||||
|     string_reset(nfc->text_box_store); | ||||
| } | ||||
|  | ||||
| @ -60,5 +60,5 @@ void nfc_scene_save_name_on_exit(void* context) { | ||||
|     Nfc* nfc = (Nfc*)context; | ||||
| 
 | ||||
|     // Clear view
 | ||||
|     text_input_clean(nfc->text_input); | ||||
|     text_input_reset(nfc->text_input); | ||||
| } | ||||
|  | ||||
| @ -81,5 +81,5 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { | ||||
| void nfc_scene_saved_menu_on_exit(void* context) { | ||||
|     Nfc* nfc = (Nfc*)context; | ||||
| 
 | ||||
|     submenu_clean(nfc->submenu); | ||||
|     submenu_reset(nfc->submenu); | ||||
| } | ||||
|  | ||||
| @ -55,5 +55,5 @@ bool nfc_scene_scripts_menu_on_event(void* context, SceneManagerEvent event) { | ||||
| void nfc_scene_scripts_menu_on_exit(void* context) { | ||||
|     Nfc* nfc = (Nfc*)context; | ||||
| 
 | ||||
|     submenu_clean(nfc->submenu); | ||||
|     submenu_reset(nfc->submenu); | ||||
| } | ||||
|  | ||||
| @ -45,5 +45,5 @@ bool nfc_scene_set_type_on_event(void* context, SceneManagerEvent event) { | ||||
| void nfc_scene_set_type_on_exit(void* context) { | ||||
|     Nfc* nfc = (Nfc*)context; | ||||
| 
 | ||||
|     submenu_clean(nfc->submenu); | ||||
|     submenu_reset(nfc->submenu); | ||||
| } | ||||
|  | ||||
| @ -78,5 +78,5 @@ bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) { | ||||
| void nfc_scene_start_on_exit(void* context) { | ||||
|     Nfc* nfc = (Nfc*)context; | ||||
| 
 | ||||
|     submenu_clean(nfc->submenu); | ||||
|     submenu_reset(nfc->submenu); | ||||
| } | ||||
|  | ||||
| @ -39,5 +39,5 @@ bool power_settings_scene_power_off_on_event(void* context, SceneManagerEvent ev | ||||
| 
 | ||||
| void power_settings_scene_power_off_on_exit(void* context) { | ||||
|     PowerSettingsApp* app = context; | ||||
|     dialog_ex_clean(app->dialog); | ||||
|     dialog_ex_reset(app->dialog); | ||||
| } | ||||
|  | ||||
| @ -48,5 +48,5 @@ bool power_settings_scene_reboot_on_event(void* context, SceneManagerEvent event | ||||
| 
 | ||||
| void power_settings_scene_reboot_on_exit(void* context) { | ||||
|     PowerSettingsApp* app = context; | ||||
|     submenu_clean(app->submenu); | ||||
|     submenu_reset(app->submenu); | ||||
| } | ||||
|  | ||||
| @ -60,5 +60,5 @@ bool power_settings_scene_start_on_event(void* context, SceneManagerEvent event) | ||||
| 
 | ||||
| void power_settings_scene_start_on_exit(void* context) { | ||||
|     PowerSettingsApp* app = context; | ||||
|     submenu_clean(app->submenu); | ||||
|     submenu_reset(app->submenu); | ||||
| } | ||||
|  | ||||
| @ -115,5 +115,5 @@ bool storage_settings_scene_start_on_event(void* context, SceneManagerEvent even | ||||
| 
 | ||||
| void storage_settings_scene_start_on_exit(void* context) { | ||||
|     StorageSettings* app = context; | ||||
|     submenu_clean(app->submenu); | ||||
|     submenu_reset(app->submenu); | ||||
| } | ||||
|  | ||||
| @ -56,5 +56,5 @@ bool subghz_scene_more_raw_on_event(void* context, SceneManagerEvent event) { | ||||
| 
 | ||||
| void subghz_scene_more_raw_on_exit(void* context) { | ||||
|     SubGhz* subghz = context; | ||||
|     submenu_clean(subghz->submenu); | ||||
|     submenu_reset(subghz->submenu); | ||||
| } | ||||
|  | ||||
| @ -66,7 +66,7 @@ void subghz_scene_receiver_on_enter(void* context) { | ||||
|     string_init(str_buff); | ||||
| 
 | ||||
|     if(subghz->txrx->rx_key_state == SubGhzRxKeyStateIDLE) { | ||||
|         subghz_history_clean(subghz->txrx->history); | ||||
|         subghz_history_reset(subghz->txrx->history); | ||||
|     } | ||||
| 
 | ||||
|     //Load history to receiver
 | ||||
|  | ||||
| @ -161,7 +161,7 @@ bool subghz_scene_receiver_config_on_event(void* context, SceneManagerEvent even | ||||
| 
 | ||||
| void subghz_scene_receiver_config_on_exit(void* context) { | ||||
|     SubGhz* subghz = context; | ||||
|     variable_item_list_clean(subghz->variable_item_list); | ||||
|     variable_item_list_reset(subghz->variable_item_list); | ||||
|     scene_manager_set_scene_state( | ||||
|         subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerNoSet); | ||||
| } | ||||
|  | ||||
| @ -91,7 +91,7 @@ void subghz_scene_save_name_on_exit(void* context) { | ||||
|     text_input_set_validator(subghz->text_input, NULL, NULL); | ||||
|     validator_is_file_free(validator_context); | ||||
| 
 | ||||
|     text_input_clean(subghz->text_input); | ||||
|     text_input_reset(subghz->text_input); | ||||
|     scene_manager_set_scene_state( | ||||
|         subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerNoSet); | ||||
| } | ||||
|  | ||||
| @ -67,5 +67,5 @@ bool subghz_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { | ||||
| 
 | ||||
| void subghz_scene_saved_menu_on_exit(void* context) { | ||||
|     SubGhz* subghz = context; | ||||
|     submenu_clean(subghz->submenu); | ||||
|     submenu_reset(subghz->submenu); | ||||
| } | ||||
|  | ||||
| @ -202,5 +202,5 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { | ||||
| 
 | ||||
| void subghz_scene_set_type_on_exit(void* context) { | ||||
|     SubGhz* subghz = context; | ||||
|     submenu_clean(subghz->submenu); | ||||
|     submenu_reset(subghz->submenu); | ||||
| } | ||||
|  | ||||
| @ -97,5 +97,5 @@ bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) { | ||||
| 
 | ||||
| void subghz_scene_start_on_exit(void* context) { | ||||
|     SubGhz* subghz = context; | ||||
|     submenu_clean(subghz->submenu); | ||||
|     submenu_reset(subghz->submenu); | ||||
| } | ||||
|  | ||||
| @ -57,5 +57,5 @@ bool subghz_scene_test_on_event(void* context, SceneManagerEvent event) { | ||||
| 
 | ||||
| void subghz_scene_test_on_exit(void* context) { | ||||
|     SubGhz* subghz = context; | ||||
|     submenu_clean(subghz->submenu); | ||||
|     submenu_reset(subghz->submenu); | ||||
| } | ||||
|  | ||||
| @ -60,7 +60,7 @@ FuriHalSubGhzPreset subghz_history_get_preset(SubGhzHistory* instance, uint16_t | ||||
|     return instance->history[idx].preset; | ||||
| } | ||||
| 
 | ||||
| void subghz_history_clean(SubGhzHistory* instance) { | ||||
| void subghz_history_reset(SubGhzHistory* instance) { | ||||
|     furi_assert(instance); | ||||
|     instance->last_index_write = 0; | ||||
|     instance->code_last_found = 0; | ||||
|  | ||||
| @ -21,7 +21,7 @@ void subghz_history_free(SubGhzHistory* instance); | ||||
|  *  | ||||
|  * @param instance - SubGhzHistory instance | ||||
|  */ | ||||
| void subghz_history_clean(SubGhzHistory* instance); | ||||
| void subghz_history_reset(SubGhzHistory* instance); | ||||
| 
 | ||||
| /** Set frequency and preset to history[idx]
 | ||||
|  *  | ||||
|  | ||||
							
								
								
									
										46
									
								
								firmware/targets/f6/ble_glue/gap.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										46
									
								
								firmware/targets/f6/ble_glue/gap.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @ -94,9 +94,17 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { | ||||
|     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(TAG, "Connection update event"); | ||||
|         case EVT_LE_CONN_UPDATE_COMPLETE: { | ||||
|             hci_le_connection_update_complete_event_rp0* event = | ||||
|                 (hci_le_connection_update_complete_event_rp0*)meta_evt->data; | ||||
|             FURI_LOG_I( | ||||
|                 TAG, | ||||
|                 "Connection interval: %d, latency: %d, supervision timeout: %d", | ||||
|                 event->Conn_Interval, | ||||
|                 event->Conn_Latency, | ||||
|                 event->Supervision_Timeout); | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         case EVT_LE_PHY_UPDATE_COMPLETE: | ||||
|             evt_le_phy_update_complete = (hci_le_phy_update_complete_event_rp0*)meta_evt->data; | ||||
| @ -129,6 +137,15 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { | ||||
|             // Update connection status and handle
 | ||||
|             gap->state = GapStateConnected; | ||||
|             gap->service.connection_handle = connection_complete_event->Connection_Handle; | ||||
|             GapConnectionParams* params = &gap->config->conn_param; | ||||
|             if(aci_l2cap_connection_parameter_update_req( | ||||
|                    gap->service.connection_handle, | ||||
|                    params->conn_int_min, | ||||
|                    params->conn_int_max, | ||||
|                    params->slave_latency, | ||||
|                    params->supervisor_timeout)) { | ||||
|                 FURI_LOG_W(TAG, "Failed to request connection parameters update"); | ||||
|             } | ||||
| 
 | ||||
|             // Start pairing by sending security request
 | ||||
|             aci_gap_slave_security_req(connection_complete_event->Connection_Handle); | ||||
| @ -184,28 +201,28 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { | ||||
|         } break; | ||||
| 
 | ||||
|         case EVT_BLUE_GAP_AUTHORIZATION_REQUEST: | ||||
|             FURI_LOG_I(TAG, "Authorization request event"); | ||||
|             FURI_LOG_D(TAG, "Authorization request event"); | ||||
|             break; | ||||
| 
 | ||||
|         case EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED: | ||||
|             FURI_LOG_I(TAG, "Slave security initiated"); | ||||
|             FURI_LOG_D(TAG, "Slave security initiated"); | ||||
|             break; | ||||
| 
 | ||||
|         case EVT_BLUE_GAP_BOND_LOST: | ||||
|             FURI_LOG_I(TAG, "Bond lost event. Start rebonding"); | ||||
|             FURI_LOG_D(TAG, "Bond lost event. Start rebonding"); | ||||
|             aci_gap_allow_rebond(gap->service.connection_handle); | ||||
|             break; | ||||
| 
 | ||||
|         case EVT_BLUE_GAP_DEVICE_FOUND: | ||||
|             FURI_LOG_I(TAG, "Device found event"); | ||||
|             FURI_LOG_D(TAG, "Device found event"); | ||||
|             break; | ||||
| 
 | ||||
|         case EVT_BLUE_GAP_ADDR_NOT_RESOLVED: | ||||
|             FURI_LOG_I(TAG, "Address not resolved event"); | ||||
|             FURI_LOG_D(TAG, "Address not resolved event"); | ||||
|             break; | ||||
| 
 | ||||
|         case EVT_BLUE_GAP_KEYPRESS_NOTIFICATION: | ||||
|             FURI_LOG_I(TAG, "Key press notification event"); | ||||
|             FURI_LOG_D(TAG, "Key press notification event"); | ||||
|             break; | ||||
| 
 | ||||
|         case EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE: { | ||||
| @ -234,8 +251,19 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { | ||||
|             break; | ||||
| 
 | ||||
|         case EVT_BLUE_GAP_PROCEDURE_COMPLETE: | ||||
|             FURI_LOG_I(TAG, "Procedure complete event"); | ||||
|             FURI_LOG_D(TAG, "Procedure complete event"); | ||||
|             break; | ||||
| 
 | ||||
|         case EVT_BLUE_L2CAP_CONNECTION_UPDATE_RESP: { | ||||
|             uint16_t result = | ||||
|                 ((aci_l2cap_connection_update_resp_event_rp0*)(blue_evt->data))->Result; | ||||
|             if(result == 0) { | ||||
|                 FURI_LOG_D(TAG, "Connection parameters accepted"); | ||||
|             } else if(result == 1) { | ||||
|                 FURI_LOG_D(TAG, "Connection parameters denied"); | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|         } | ||||
|     default: | ||||
|         break; | ||||
|  | ||||
| @ -55,6 +55,13 @@ typedef enum { | ||||
|     GapPairingPinCodeVerifyYesNo, | ||||
| } GapPairing; | ||||
| 
 | ||||
| typedef struct { | ||||
|     uint16_t conn_int_min; | ||||
|     uint16_t conn_int_max; | ||||
|     uint16_t slave_latency; | ||||
|     uint16_t supervisor_timeout; | ||||
| } GapConnectionParams; | ||||
| 
 | ||||
| typedef struct { | ||||
|     uint16_t adv_service_uuid; | ||||
|     uint16_t appearance_char; | ||||
| @ -62,6 +69,7 @@ typedef struct { | ||||
|     GapPairing pairing_method; | ||||
|     uint8_t mac_address[GAP_MAC_ADDR_SIZE]; | ||||
|     char adv_name[FURI_HAL_VERSION_DEVICE_NAME_LENGTH]; | ||||
|     GapConnectionParams conn_param; | ||||
| } GapConfig; | ||||
| 
 | ||||
| bool gap_init(GapConfig* config, GapEventCallback on_event_cb, void* context); | ||||
|  | ||||
							
								
								
									
										25
									
								
								firmware/targets/f6/furi_hal/furi_hal_bt.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										25
									
								
								firmware/targets/f6/furi_hal/furi_hal_bt.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @ -42,6 +42,13 @@ FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = { | ||||
|                     .bonding_mode = true, | ||||
|                     .pairing_method = GapPairingPinCodeShow, | ||||
|                     .mac_address = FURI_HAL_BT_DEFAULT_MAC_ADDR, | ||||
|                     .conn_param = | ||||
|                         { | ||||
|                             .conn_int_min = 0x08, | ||||
|                             .conn_int_max = 0x18, | ||||
|                             .slave_latency = 0, | ||||
|                             .supervisor_timeout = 50, | ||||
|                         }, | ||||
|                 }, | ||||
|         }, | ||||
|     [FuriHalBtProfileHidKeyboard] = | ||||
| @ -55,6 +62,14 @@ FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = { | ||||
|                     .bonding_mode = true, | ||||
|                     .pairing_method = GapPairingPinCodeVerifyYesNo, | ||||
|                     .mac_address = FURI_HAL_BT_DEFAULT_MAC_ADDR, | ||||
|                     // TODO optimize
 | ||||
|                     .conn_param = | ||||
|                         { | ||||
|                             .conn_int_min = 0x12, | ||||
|                             .conn_int_max = 0x1e, | ||||
|                             .slave_latency = 6, | ||||
|                             .supervisor_timeout = 700, | ||||
|                         }, | ||||
|                 }, | ||||
|         }, | ||||
| }; | ||||
| @ -277,6 +292,16 @@ void furi_hal_bt_nvm_sram_sem_release() { | ||||
|     HAL_HSEM_Release(CFG_HW_BLE_NVM_SRAM_SEMID, 0); | ||||
| } | ||||
| 
 | ||||
| bool furi_hal_bt_clear_white_list() { | ||||
|     furi_hal_bt_nvm_sram_sem_acquire(); | ||||
|     tBleStatus status = aci_gap_clear_security_db(); | ||||
|     if(status) { | ||||
|         FURI_LOG_E(TAG, "Clear while list failed with status %d", status); | ||||
|     } | ||||
|     furi_hal_bt_nvm_sram_sem_release(); | ||||
|     return status != BLE_STATUS_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| void furi_hal_bt_dump_state(string_t buffer) { | ||||
|     if(furi_hal_bt_is_alive()) { | ||||
|         uint8_t HCI_Version; | ||||
|  | ||||
| @ -112,6 +112,7 @@ C_SOURCES += \ | ||||
| 	$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_gap_aci.c \
 | ||||
| 	$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_gatt_aci.c \
 | ||||
| 	$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_hal_aci.c \
 | ||||
| 	$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_l2cap_aci.c \
 | ||||
| 	$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/tl_mbox.c \
 | ||||
| 	$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/hci_tl.c \
 | ||||
| 	$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/hci_tl_if.c \
 | ||||
|  | ||||
							
								
								
									
										46
									
								
								firmware/targets/f7/ble_glue/gap.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										46
									
								
								firmware/targets/f7/ble_glue/gap.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @ -94,9 +94,17 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { | ||||
|     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(TAG, "Connection update event"); | ||||
|         case EVT_LE_CONN_UPDATE_COMPLETE: { | ||||
|             hci_le_connection_update_complete_event_rp0* event = | ||||
|                 (hci_le_connection_update_complete_event_rp0*)meta_evt->data; | ||||
|             FURI_LOG_I( | ||||
|                 TAG, | ||||
|                 "Connection interval: %d, latency: %d, supervision timeout: %d", | ||||
|                 event->Conn_Interval, | ||||
|                 event->Conn_Latency, | ||||
|                 event->Supervision_Timeout); | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         case EVT_LE_PHY_UPDATE_COMPLETE: | ||||
|             evt_le_phy_update_complete = (hci_le_phy_update_complete_event_rp0*)meta_evt->data; | ||||
| @ -129,6 +137,15 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { | ||||
|             // Update connection status and handle
 | ||||
|             gap->state = GapStateConnected; | ||||
|             gap->service.connection_handle = connection_complete_event->Connection_Handle; | ||||
|             GapConnectionParams* params = &gap->config->conn_param; | ||||
|             if(aci_l2cap_connection_parameter_update_req( | ||||
|                    gap->service.connection_handle, | ||||
|                    params->conn_int_min, | ||||
|                    params->conn_int_max, | ||||
|                    params->slave_latency, | ||||
|                    params->supervisor_timeout)) { | ||||
|                 FURI_LOG_W(TAG, "Failed to request connection parameters update"); | ||||
|             } | ||||
| 
 | ||||
|             // Start pairing by sending security request
 | ||||
|             aci_gap_slave_security_req(connection_complete_event->Connection_Handle); | ||||
| @ -184,28 +201,28 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { | ||||
|         } break; | ||||
| 
 | ||||
|         case EVT_BLUE_GAP_AUTHORIZATION_REQUEST: | ||||
|             FURI_LOG_I(TAG, "Authorization request event"); | ||||
|             FURI_LOG_D(TAG, "Authorization request event"); | ||||
|             break; | ||||
| 
 | ||||
|         case EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED: | ||||
|             FURI_LOG_I(TAG, "Slave security initiated"); | ||||
|             FURI_LOG_D(TAG, "Slave security initiated"); | ||||
|             break; | ||||
| 
 | ||||
|         case EVT_BLUE_GAP_BOND_LOST: | ||||
|             FURI_LOG_I(TAG, "Bond lost event. Start rebonding"); | ||||
|             FURI_LOG_D(TAG, "Bond lost event. Start rebonding"); | ||||
|             aci_gap_allow_rebond(gap->service.connection_handle); | ||||
|             break; | ||||
| 
 | ||||
|         case EVT_BLUE_GAP_DEVICE_FOUND: | ||||
|             FURI_LOG_I(TAG, "Device found event"); | ||||
|             FURI_LOG_D(TAG, "Device found event"); | ||||
|             break; | ||||
| 
 | ||||
|         case EVT_BLUE_GAP_ADDR_NOT_RESOLVED: | ||||
|             FURI_LOG_I(TAG, "Address not resolved event"); | ||||
|             FURI_LOG_D(TAG, "Address not resolved event"); | ||||
|             break; | ||||
| 
 | ||||
|         case EVT_BLUE_GAP_KEYPRESS_NOTIFICATION: | ||||
|             FURI_LOG_I(TAG, "Key press notification event"); | ||||
|             FURI_LOG_D(TAG, "Key press notification event"); | ||||
|             break; | ||||
| 
 | ||||
|         case EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE: { | ||||
| @ -234,8 +251,19 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { | ||||
|             break; | ||||
| 
 | ||||
|         case EVT_BLUE_GAP_PROCEDURE_COMPLETE: | ||||
|             FURI_LOG_I(TAG, "Procedure complete event"); | ||||
|             FURI_LOG_D(TAG, "Procedure complete event"); | ||||
|             break; | ||||
| 
 | ||||
|         case EVT_BLUE_L2CAP_CONNECTION_UPDATE_RESP: { | ||||
|             uint16_t result = | ||||
|                 ((aci_l2cap_connection_update_resp_event_rp0*)(blue_evt->data))->Result; | ||||
|             if(result == 0) { | ||||
|                 FURI_LOG_D(TAG, "Connection parameters accepted"); | ||||
|             } else if(result == 1) { | ||||
|                 FURI_LOG_D(TAG, "Connection parameters denied"); | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|         } | ||||
|     default: | ||||
|         break; | ||||
|  | ||||
| @ -55,6 +55,13 @@ typedef enum { | ||||
|     GapPairingPinCodeVerifyYesNo, | ||||
| } GapPairing; | ||||
| 
 | ||||
| typedef struct { | ||||
|     uint16_t conn_int_min; | ||||
|     uint16_t conn_int_max; | ||||
|     uint16_t slave_latency; | ||||
|     uint16_t supervisor_timeout; | ||||
| } GapConnectionParams; | ||||
| 
 | ||||
| typedef struct { | ||||
|     uint16_t adv_service_uuid; | ||||
|     uint16_t appearance_char; | ||||
| @ -62,6 +69,7 @@ typedef struct { | ||||
|     GapPairing pairing_method; | ||||
|     uint8_t mac_address[GAP_MAC_ADDR_SIZE]; | ||||
|     char adv_name[FURI_HAL_VERSION_DEVICE_NAME_LENGTH]; | ||||
|     GapConnectionParams conn_param; | ||||
| } GapConfig; | ||||
| 
 | ||||
| bool gap_init(GapConfig* config, GapEventCallback on_event_cb, void* context); | ||||
|  | ||||
							
								
								
									
										25
									
								
								firmware/targets/f7/furi_hal/furi_hal_bt.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										25
									
								
								firmware/targets/f7/furi_hal/furi_hal_bt.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @ -42,6 +42,13 @@ FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = { | ||||
|                     .bonding_mode = true, | ||||
|                     .pairing_method = GapPairingPinCodeShow, | ||||
|                     .mac_address = FURI_HAL_BT_DEFAULT_MAC_ADDR, | ||||
|                     .conn_param = | ||||
|                         { | ||||
|                             .conn_int_min = 0x08, | ||||
|                             .conn_int_max = 0x18, | ||||
|                             .slave_latency = 0, | ||||
|                             .supervisor_timeout = 50, | ||||
|                         }, | ||||
|                 }, | ||||
|         }, | ||||
|     [FuriHalBtProfileHidKeyboard] = | ||||
| @ -55,6 +62,14 @@ FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = { | ||||
|                     .bonding_mode = true, | ||||
|                     .pairing_method = GapPairingPinCodeVerifyYesNo, | ||||
|                     .mac_address = FURI_HAL_BT_DEFAULT_MAC_ADDR, | ||||
|                     // TODO optimize
 | ||||
|                     .conn_param = | ||||
|                         { | ||||
|                             .conn_int_min = 0x12, | ||||
|                             .conn_int_max = 0x1e, | ||||
|                             .slave_latency = 6, | ||||
|                             .supervisor_timeout = 700, | ||||
|                         }, | ||||
|                 }, | ||||
|         }, | ||||
| }; | ||||
| @ -277,6 +292,16 @@ void furi_hal_bt_nvm_sram_sem_release() { | ||||
|     HAL_HSEM_Release(CFG_HW_BLE_NVM_SRAM_SEMID, 0); | ||||
| } | ||||
| 
 | ||||
| bool furi_hal_bt_clear_white_list() { | ||||
|     furi_hal_bt_nvm_sram_sem_acquire(); | ||||
|     tBleStatus status = aci_gap_clear_security_db(); | ||||
|     if(status) { | ||||
|         FURI_LOG_E(TAG, "Clear while list failed with status %d", status); | ||||
|     } | ||||
|     furi_hal_bt_nvm_sram_sem_release(); | ||||
|     return status != BLE_STATUS_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| void furi_hal_bt_dump_state(string_t buffer) { | ||||
|     if(furi_hal_bt_is_alive()) { | ||||
|         uint8_t HCI_Version; | ||||
|  | ||||
| @ -112,6 +112,7 @@ C_SOURCES += \ | ||||
| 	$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_gap_aci.c \
 | ||||
| 	$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_gatt_aci.c \
 | ||||
| 	$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_hal_aci.c \
 | ||||
| 	$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/ble/core/auto/ble_l2cap_aci.c \
 | ||||
| 	$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/tl_mbox.c \
 | ||||
| 	$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/hci_tl.c \
 | ||||
| 	$(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/hci_tl_if.c \
 | ||||
|  | ||||
| @ -121,6 +121,12 @@ void furi_hal_bt_nvm_sram_sem_acquire(); | ||||
|  */ | ||||
| void furi_hal_bt_nvm_sram_sem_release(); | ||||
| 
 | ||||
| /** Clear key storage
 | ||||
|  * | ||||
|  * @return      true on success | ||||
| */ | ||||
| bool furi_hal_bt_clear_white_list(); | ||||
| 
 | ||||
| /** Set key storage change callback
 | ||||
|  * | ||||
|  * @param       callback    BleGlueKeyStorageChangedCallback instance | ||||
|  | ||||
| @ -13,7 +13,7 @@ View* SubmenuVM::get_view() { | ||||
| } | ||||
| 
 | ||||
| void SubmenuVM::clean() { | ||||
|     submenu_clean(submenu); | ||||
|     submenu_reset(submenu); | ||||
| } | ||||
| 
 | ||||
| void SubmenuVM::add_item( | ||||
|  | ||||
| @ -13,7 +13,7 @@ View* TextInputVM::get_view() { | ||||
| } | ||||
| 
 | ||||
| void TextInputVM::clean() { | ||||
|     text_input_clean(text_input); | ||||
|     text_input_reset(text_input); | ||||
| } | ||||
| 
 | ||||
| void TextInputVM::set_result_callback( | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 gornekich
						gornekich