Skip to content

Commit a15308e

Browse files
nminaylovskotopes
andauthored
Air Mouse app: new BLE profile support (#115)
Co-authored-by: あく <[email protected]>
1 parent afe8e63 commit a15308e

File tree

6 files changed

+101
-43
lines changed

6 files changed

+101
-43
lines changed

air_mouse/air_mouse_app.c

Lines changed: 79 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#include <furi.h>
22
#include <furi_hal.h>
3-
#include <furi_hal_bt_hid.h>
3+
#include <furi_hal_bt.h>
4+
#include <extra_profiles/hid_profile.h>
45
#include <bt/bt_service/bt.h>
6+
57
#include <gui/gui.h>
68
#include <gui/view_dispatcher.h>
79
#include <gui/modules/submenu.h>
@@ -13,7 +15,7 @@
1315

1416
#define TAG "SensorModule"
1517

16-
#define BLE_HID_KEYS_PATH "/ext/apps_data/hid_ble/.bt_hid.keys"
18+
#define HID_BT_KEYS_STORAGE_NAME ".bt_hid.keys"
1719

1820
typedef struct {
1921
Gui* gui;
@@ -25,6 +27,7 @@ typedef struct {
2527
ICM42688P* icm42688p;
2628
FuriHalUsbInterface* usb_mode_prev;
2729
Bt* bt;
30+
FuriHalBleProfileBase* ble_hid_profile;
2831
} AirMouseApp;
2932

3033
typedef enum {
@@ -39,19 +42,60 @@ enum StertSubmenuIndex {
3942
StartSubmenuIndexBleReset,
4043
};
4144

45+
static const BleProfileHidParams ble_hid_params = {
46+
.device_name_prefix = "AirMouse",
47+
.mac_xor = 0x0001,
48+
};
49+
50+
static bool usb_hid_mouse_move(void* inst, int8_t dx, int8_t dy) {
51+
UNUSED(inst);
52+
return furi_hal_hid_mouse_move(dx, dy);
53+
}
54+
55+
static bool usb_hid_mouse_key_press(void* inst, uint8_t button) {
56+
UNUSED(inst);
57+
return furi_hal_hid_mouse_press(button);
58+
}
59+
60+
static bool usb_hid_mouse_key_release(void* inst, uint8_t button) {
61+
UNUSED(inst);
62+
return furi_hal_hid_mouse_release(button);
63+
}
64+
65+
static bool usb_hid_mouse_scroll(void* inst, int8_t value) {
66+
UNUSED(inst);
67+
return furi_hal_hid_mouse_scroll(value);
68+
}
69+
4270
static const ImuHidApi hid_api_usb = {
43-
.mouse_move = furi_hal_hid_mouse_move,
44-
.mouse_key_press = furi_hal_hid_mouse_press,
45-
.mouse_key_release = furi_hal_hid_mouse_release,
46-
.mouse_scroll = furi_hal_hid_mouse_scroll,
71+
.mouse_move = usb_hid_mouse_move,
72+
.mouse_key_press = usb_hid_mouse_key_press,
73+
.mouse_key_release = usb_hid_mouse_key_release,
74+
.mouse_scroll = usb_hid_mouse_scroll,
4775
.report_rate_max = 200,
4876
};
4977

78+
static bool ble_hid_mouse_move(void* inst, int8_t dx, int8_t dy) {
79+
return ble_profile_hid_mouse_move(inst, dx, dy);
80+
}
81+
82+
static bool ble_hid_mouse_key_press(void* inst, uint8_t button) {
83+
return ble_profile_hid_mouse_press(inst, button);
84+
}
85+
86+
static bool ble_hid_mouse_key_release(void* inst, uint8_t button) {
87+
return ble_profile_hid_mouse_release(inst, button);
88+
}
89+
90+
static bool ble_hid_mouse_scroll(void* inst, int8_t value) {
91+
return ble_profile_hid_mouse_scroll(inst, value);
92+
}
93+
5094
static const ImuHidApi hid_api_ble = {
51-
.mouse_move = furi_hal_bt_hid_mouse_move,
52-
.mouse_key_press = furi_hal_bt_hid_mouse_press,
53-
.mouse_key_release = furi_hal_bt_hid_mouse_release,
54-
.mouse_scroll = furi_hal_bt_hid_mouse_scroll,
95+
.mouse_move = ble_hid_mouse_move,
96+
.mouse_key_press = ble_hid_mouse_key_press,
97+
.mouse_key_release = ble_hid_mouse_key_release,
98+
.mouse_scroll = ble_hid_mouse_scroll,
5599
.report_rate_max = 30,
56100
};
57101

@@ -62,14 +106,16 @@ static void ble_hid_remove_pairing(void) {
62106
// Wait 2nd core to update nvm storage
63107
furi_delay_ms(200);
64108

65-
bt_keys_storage_set_storage_path(bt, BLE_HID_KEYS_PATH);
109+
furi_hal_bt_stop_advertising();
110+
111+
bt_keys_storage_set_storage_path(bt, APP_DATA_PATH(HID_BT_KEYS_STORAGE_NAME));
66112
bt_forget_bonded_devices(bt);
67113

68114
// Wait 2nd core to update nvm storage
69115
furi_delay_ms(200);
70116
bt_keys_storage_set_default_path(bt);
71117

72-
furi_check(bt_set_profile(bt, BtProfileSerial));
118+
furi_check(bt_profile_restore_default(bt));
73119
furi_record_close(RECORD_BT);
74120
}
75121

@@ -80,32 +126,36 @@ static void ble_hid_connection_status_callback(BtStatus status, void* context) {
80126
air_mouse_view_set_connected_status(app->air_mouse_view, connected);
81127
}
82128

83-
static Bt* ble_hid_init(AirMouseApp* app) {
84-
Bt* bt = furi_record_open(RECORD_BT);
85-
bt_disconnect(bt);
129+
static FuriHalBleProfileBase* ble_hid_init(AirMouseApp* app) {
130+
app->bt = furi_record_open(RECORD_BT);
131+
bt_disconnect(app->bt);
86132

87133
// Wait 2nd core to update nvm storage
88134
furi_delay_ms(200);
89135

90-
bt_keys_storage_set_storage_path(bt, BLE_HID_KEYS_PATH);
136+
bt_keys_storage_set_storage_path(app->bt, APP_DATA_PATH(HID_BT_KEYS_STORAGE_NAME));
91137

92-
furi_check(bt_set_profile(bt, BtProfileHidKeyboard));
138+
FuriHalBleProfileBase* ble_hid_profile =
139+
bt_profile_start(app->bt, ble_profile_hid, (void*)&ble_hid_params);
140+
furi_check(ble_hid_profile);
93141

94142
furi_hal_bt_start_advertising();
95-
bt_set_status_changed_callback(bt, ble_hid_connection_status_callback, app);
96-
return bt;
143+
bt_set_status_changed_callback(app->bt, ble_hid_connection_status_callback, app);
144+
145+
return ble_hid_profile;
97146
}
98147

99-
static void ble_hid_deinit(Bt* bt) {
100-
bt_set_status_changed_callback(bt, NULL, NULL);
101-
bt_disconnect(bt);
148+
static void ble_hid_deinit(AirMouseApp* app) {
149+
bt_set_status_changed_callback(app->bt, NULL, NULL);
150+
bt_disconnect(app->bt);
102151

103152
// Wait 2nd core to update nvm storage
104153
furi_delay_ms(200);
105-
bt_keys_storage_set_default_path(bt);
154+
bt_keys_storage_set_default_path(app->bt);
106155

107-
furi_check(bt_set_profile(bt, BtProfileSerial));
156+
furi_check(bt_profile_restore_default(app->bt));
108157
furi_record_close(RECORD_BT);
158+
app->bt = NULL;
109159
}
110160

111161
static uint32_t air_mouse_exit(void* context) {
@@ -123,8 +173,8 @@ static void air_mouse_hid_deinit(void* context) {
123173
AirMouseApp* app = context;
124174

125175
if(app->bt) {
126-
ble_hid_deinit(app->bt);
127-
app->bt = NULL;
176+
ble_hid_deinit(app);
177+
app->ble_hid_profile = NULL;
128178
} else if(app->usb_mode_prev) {
129179
furi_hal_usb_set_config(app->usb_mode_prev, NULL);
130180
app->usb_mode_prev = NULL;
@@ -139,12 +189,12 @@ static void air_mouse_submenu_callback(void* context, uint32_t index) {
139189
furi_hal_usb_unlock();
140190
furi_hal_usb_set_config(&usb_hid, NULL);
141191

142-
air_mouse_view_set_hid_api(app->air_mouse_view, &hid_api_usb, false);
192+
air_mouse_view_set_hid_api(app->air_mouse_view, &hid_api_usb, NULL, false);
143193
view_dispatcher_switch_to_view(app->view_dispatcher, AirMouseViewMain);
144194
} else if(index == StartSubmenuIndexBle) {
145-
app->bt = ble_hid_init(app);
195+
app->ble_hid_profile = ble_hid_init(app);
146196

147-
air_mouse_view_set_hid_api(app->air_mouse_view, &hid_api_ble, true);
197+
air_mouse_view_set_hid_api(app->air_mouse_view, &hid_api_ble, app->ble_hid_profile, true);
148198
view_dispatcher_switch_to_view(app->view_dispatcher, AirMouseViewMain);
149199
} else if(index == StartSubmenuIndexBleReset) {
150200
ble_hid_remove_pairing();

air_mouse/application.fam

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ App(
99
fap_icon="airmouse_10x10.png",
1010
fap_icon_assets="assets",
1111
fap_category="GPIO",
12+
fap_libs=["ble_profile"],
1213
)

air_mouse/imu_mouse.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ struct ImuThread {
4646
FuriThread* thread;
4747
ICM42688P* icm42688p;
4848
const ImuHidApi* hid;
49+
void* hid_inst;
4950
ImuProcessedData processed_data;
5051
};
5152

@@ -173,16 +174,16 @@ static int32_t imu_thread(void* context) {
173174
}
174175

175176
if(events & ImuMouseRightPress) {
176-
imu->hid->mouse_key_press(HID_MOUSE_BTN_RIGHT);
177+
imu->hid->mouse_key_press(imu->hid_inst, HID_MOUSE_BTN_RIGHT);
177178
}
178179
if(events & ImuMouseRightRelease) {
179-
imu->hid->mouse_key_release(HID_MOUSE_BTN_RIGHT);
180+
imu->hid->mouse_key_release(imu->hid_inst, HID_MOUSE_BTN_RIGHT);
180181
}
181182
if(events & ImuMouseLeftPress) {
182-
imu->hid->mouse_key_press(HID_MOUSE_BTN_LEFT);
183+
imu->hid->mouse_key_press(imu->hid_inst, HID_MOUSE_BTN_LEFT);
183184
}
184185
if(events & ImuMouseLeftRelease) {
185-
imu->hid->mouse_key_release(HID_MOUSE_BTN_LEFT);
186+
imu->hid->mouse_key_release(imu->hid_inst, HID_MOUSE_BTN_LEFT);
186187
}
187188
if(events & ImuMouseScrollOn) {
188189
scroll_pitch = pitch_last;
@@ -217,7 +218,7 @@ static int32_t imu_thread(void* context) {
217218
SCROLL_SENSITIVITY_K;
218219
scroll_speed = CLAMP(scroll_speed, 127.f, -127.f);
219220

220-
imu->hid->mouse_scroll(scroll_speed);
221+
imu->hid->mouse_scroll(imu->hid_inst, scroll_speed);
221222
}
222223
} else {
223224
diff_x +=
@@ -235,7 +236,8 @@ static int32_t imu_thread(void* context) {
235236
float mouse_x = CLAMP(diff_x, 127.f, -127.f);
236237
float mouse_y = CLAMP(diff_y, 127.f, -127.f);
237238

238-
imu->hid->mouse_move(mouse_exp_rate(mouse_x), mouse_exp_rate(mouse_y));
239+
imu->hid->mouse_move(
240+
imu->hid_inst, mouse_exp_rate(mouse_x), mouse_exp_rate(mouse_y));
239241

240242
diff_x -= (float)(int8_t)mouse_x;
241243
diff_y -= (float)(int8_t)mouse_y;
@@ -245,7 +247,7 @@ static int32_t imu_thread(void* context) {
245247
}
246248
}
247249

248-
imu->hid->mouse_key_release(HID_MOUSE_BTN_RIGHT | HID_MOUSE_BTN_LEFT);
250+
imu->hid->mouse_key_release(imu->hid_inst, HID_MOUSE_BTN_RIGHT | HID_MOUSE_BTN_LEFT);
249251

250252
icm42688_fifo_disable(imu->icm42688p);
251253

@@ -270,10 +272,11 @@ void imu_mouse_scroll_mode(ImuThread* imu, bool enable) {
270272
furi_thread_flags_set(furi_thread_get_id(imu->thread), flag);
271273
}
272274

273-
ImuThread* imu_start(ICM42688P* icm42688p, const ImuHidApi* hid) {
275+
ImuThread* imu_start(ICM42688P* icm42688p, const ImuHidApi* hid, void* hid_inst) {
274276
ImuThread* imu = malloc(sizeof(ImuThread));
275277
imu->icm42688p = icm42688p;
276278
imu->hid = hid;
279+
imu->hid_inst = hid_inst;
277280
imu->thread = furi_thread_alloc_ex("ImuThread", 4096, imu_thread, imu);
278281
furi_thread_start(imu->thread);
279282

air_mouse/imu_mouse.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
#include "sensors/ICM42688P.h"
44

55
typedef struct {
6-
bool (*mouse_move)(int8_t dx, int8_t dy);
7-
bool (*mouse_key_press)(uint8_t button);
8-
bool (*mouse_key_release)(uint8_t button);
9-
bool (*mouse_scroll)(int8_t value);
6+
bool (*mouse_move)(void* inst, int8_t dx, int8_t dy);
7+
bool (*mouse_key_press)(void* inst, uint8_t button);
8+
bool (*mouse_key_release)(void* inst, uint8_t button);
9+
bool (*mouse_scroll)(void* inst, int8_t value);
1010
uint32_t report_rate_max;
1111
} ImuHidApi;
1212

@@ -17,7 +17,7 @@ typedef enum {
1717

1818
typedef struct ImuThread ImuThread;
1919

20-
ImuThread* imu_start(ICM42688P* icm42688p, const ImuHidApi* hid);
20+
ImuThread* imu_start(ICM42688P* icm42688p, const ImuHidApi* hid, void* hid_inst);
2121

2222
void imu_stop(ImuThread* imu);
2323

air_mouse/views/air_mouse_view.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ struct AirMouseView {
88
void* imu_device;
99
ImuThread* imu;
1010
const ImuHidApi* hid_api;
11+
void* hid_inst;
1112
AirMouseViewExit exit_callback;
1213
void* context;
1314
};
@@ -107,7 +108,7 @@ static void air_mouse_view_enter(void* context) {
107108
furi_assert(context);
108109
AirMouseView* air_mouse = context;
109110
furi_assert(air_mouse->imu == NULL);
110-
air_mouse->imu = imu_start(air_mouse->imu_device, air_mouse->hid_api);
111+
air_mouse->imu = imu_start(air_mouse->imu_device, air_mouse->hid_api, air_mouse->hid_inst);
111112
}
112113

113114
static void air_mouse_view_exit(void* context) {
@@ -157,9 +158,11 @@ void air_mouse_view_set_device(AirMouseView* air_mouse, void* imu_device) {
157158
void air_mouse_view_set_hid_api(
158159
AirMouseView* air_mouse,
159160
const ImuHidApi* hid,
161+
void* hid_inst,
160162
bool is_ble_interface) {
161163
furi_assert(air_mouse);
162164
air_mouse->hid_api = hid;
165+
air_mouse->hid_inst = hid_inst;
163166
with_view_model(
164167
air_mouse->view,
165168
AirMouseModel * model,

air_mouse/views/air_mouse_view.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ View* air_mouse_view_get_view(AirMouseView* air_mouse);
1616
void air_mouse_view_set_hid_api(
1717
AirMouseView* air_mouse,
1818
const ImuHidApi* hid,
19+
void* hid_inst,
1920
bool is_ble_interface);
2021

2122
void air_mouse_view_set_device(AirMouseView* air_mouse, void* imu_device);

0 commit comments

Comments
 (0)