mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2024-11-26 14:30:25 +00:00
[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
82 changed files with 471 additions and 116 deletions
|
@ -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;
|
||||
}
|
||||
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,8 +143,8 @@ 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
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -226,4 +226,20 @@ 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
|
||||
*
|
||||
|
@ -84,4 +84,4 @@ void text_input_set_header_text(TextInput* text_input, const char* text);
|
|||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -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) {
|
||||
|
@ -63,4 +63,4 @@ void iButtonSceneAddType::submenu_callback(void* context, uint32_t index) {
|
|||
event.payload.menu_index = index;
|
||||
|
||||
app->get_view_manager()->send_event(&event);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
@ -68,4 +68,4 @@ void iButtonSceneReadedKeyMenu::submenu_callback(void* context, uint32_t index)
|
|||
event.payload.menu_index = index;
|
||||
|
||||
app->get_view_manager()->send_event(&event);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
@ -58,4 +58,4 @@ void iButtonSceneSaveName::text_input_callback(void* context) {
|
|||
event.type = iButtonEvent::Type::EventTypeTextEditResult;
|
||||
|
||||
app->get_view_manager()->send_event(&event);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
@ -70,4 +70,4 @@ void iButtonSceneSavedKeyMenu::submenu_callback(void* context, uint32_t index) {
|
|||
event.payload.menu_index = index;
|
||||
|
||||
app->get_view_manager()->send_event(&event);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
@ -60,4 +60,4 @@ void iButtonSceneStart::submenu_callback(void* context, uint32_t index) {
|
|||
event.payload.menu_index = index;
|
||||
|
||||
app->get_view_manager()->send_event(&event);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -168,4 +168,4 @@ bool subghz_history_add_to_history(
|
|||
|
||||
instance->last_index_write++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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…
Reference in a new issue