Bluetooth timeout is now dynamic thanks to rssi analyzing

This commit is contained in:
yocvito
2023-01-26 22:54:15 +01:00
parent a14f5446e4
commit a88053964e
11 changed files with 3325 additions and 73 deletions

View File

@@ -38,14 +38,15 @@ typedef enum {
LevelRssi59_40, LevelRssi59_40,
LevelRssi39_0, LevelRssi39_0,
LevelRssiNum, LevelRssiNum,
} LevelRssiDelays; LevelRssiError = 0xFF,
} LevelRssiRange;
const uint8_t bt_hid_delays[LevelRssiNum] = { const uint8_t bt_hid_delays[LevelRssiNum] = {
45, // LevelRssi122_100 30, // LevelRssi122_100
41, // LevelRssi99_80 25, // LevelRssi99_80
37, // LevelRssi79_60 20, // LevelRssi79_60
33, // LevelRssi59_40 17, // LevelRssi59_40
30, // LevelRssi39_0 14, // LevelRssi39_0
}; };
struct BadBleScript { struct BadBleScript {
@@ -158,6 +159,37 @@ static const uint8_t numpad_keys[10] = {
HID_KEYPAD_9, HID_KEYPAD_9,
}; };
uint8_t bt_timeout = 0;
static LevelRssiRange bt_remote_rssi_range(Bt *bt) {
BtRssi rssi_data = { 0 };
if (!bt_remote_rssi(bt, &rssi_data))
return LevelRssiError;
if (rssi_data.rssi <= 39)
return LevelRssi39_0;
else if (rssi_data.rssi <= 59)
return LevelRssi59_40;
else if (rssi_data.rssi <= 79)
return LevelRssi79_60;
else if (rssi_data.rssi <= 99)
return LevelRssi99_80;
else if (rssi_data.rssi <= 122)
return LevelRssi122_100;
return LevelRssiError;
}
static inline void update_bt_timeout(Bt *bt) {
LevelRssiRange r = bt_remote_rssi_range(bt);
if (r < LevelRssiNum) {
bt_timeout = bt_hid_delays[r];
}
}
/** /**
* @brief Wait until there are enough free slots in the keyboard buffer * @brief Wait until there are enough free slots in the keyboard buffer
* *
@@ -200,8 +232,8 @@ static void ducky_numlock_on() {
if((furi_hal_hid_get_led_state() & HID_KB_LED_NUM) == 0) { if((furi_hal_hid_get_led_state() & HID_KB_LED_NUM) == 0) {
bt_hid_hold_while_keyboard_buffer_full(1, -1); bt_hid_hold_while_keyboard_buffer_full(1, -1);
furi_hal_bt_hid_kb_press(HID_KEYBOARD_LOCK_NUM_LOCK); furi_hal_bt_hid_kb_press(HID_KEYBOARD_LOCK_NUM_LOCK);
FURI_LOG_I(WORKER_TAG, "BT RSSI: %f\r", (double)furi_hal_bt_get_rssi());
furi_delay_ms(25); furi_delay_ms(bt_timeout);
furi_hal_bt_hid_kb_release(HID_KEYBOARD_LOCK_NUM_LOCK); furi_hal_bt_hid_kb_release(HID_KEYBOARD_LOCK_NUM_LOCK);
} }
} }
@@ -212,10 +244,8 @@ static bool ducky_numpad_press(const char num) {
uint16_t key = numpad_keys[num - '0']; uint16_t key = numpad_keys[num - '0'];
bt_hid_hold_while_keyboard_buffer_full(1, -1); bt_hid_hold_while_keyboard_buffer_full(1, -1);
FURI_LOG_I(WORKER_TAG, "Pressing %c\r\n", num); FURI_LOG_I(WORKER_TAG, "Pressing %c\r\n", num);
furi_hal_bt_hid_kb_press(key); furi_hal_bt_hid_kb_press(key);
FURI_LOG_I(WORKER_TAG, "BT RSSI: %f\r", (double)furi_hal_bt_get_rssi()); furi_delay_ms(bt_timeout);
furi_delay_ms(25);
furi_hal_bt_hid_kb_release(key); furi_hal_bt_hid_kb_release(key);
return true; return true;
@@ -267,8 +297,8 @@ static bool ducky_string(BadBleScript* bad_ble, const char* param) {
if(keycode != HID_KEYBOARD_NONE) { if(keycode != HID_KEYBOARD_NONE) {
bt_hid_hold_while_keyboard_buffer_full(1, -1); bt_hid_hold_while_keyboard_buffer_full(1, -1);
furi_hal_bt_hid_kb_press(keycode); furi_hal_bt_hid_kb_press(keycode);
FURI_LOG_I(WORKER_TAG, "BT RSSI: %f\r", (double)furi_hal_bt_get_rssi());
furi_delay_ms(25); furi_delay_ms(bt_timeout);
furi_hal_bt_hid_kb_release(keycode); furi_hal_bt_hid_kb_release(keycode);
} }
i++; i++;
@@ -377,8 +407,8 @@ static int32_t
bt_hid_hold_while_keyboard_buffer_full(1, -1); bt_hid_hold_while_keyboard_buffer_full(1, -1);
furi_hal_bt_hid_kb_press(KEY_MOD_LEFT_ALT | HID_KEYBOARD_PRINT_SCREEN); furi_hal_bt_hid_kb_press(KEY_MOD_LEFT_ALT | HID_KEYBOARD_PRINT_SCREEN);
furi_hal_bt_hid_kb_press(key); furi_hal_bt_hid_kb_press(key);
FURI_LOG_I(WORKER_TAG, "BT RSSI: %f\r", (double)furi_hal_bt_get_rssi());
furi_delay_ms(25); furi_delay_ms(bt_timeout);
furi_hal_bt_hid_kb_release(key); furi_hal_bt_hid_kb_release(key);
furi_hal_bt_hid_kb_release(KEY_MOD_LEFT_ALT | HID_KEYBOARD_PRINT_SCREEN); furi_hal_bt_hid_kb_release(KEY_MOD_LEFT_ALT | HID_KEYBOARD_PRINT_SCREEN);
return (0); return (0);
@@ -398,8 +428,8 @@ static int32_t
} }
FURI_LOG_I(WORKER_TAG, "Special key pressed %x\r\n", key); FURI_LOG_I(WORKER_TAG, "Special key pressed %x\r\n", key);
furi_hal_bt_hid_kb_press(key); furi_hal_bt_hid_kb_press(key);
FURI_LOG_I(WORKER_TAG, "BT RSSI: %f\r", (double)furi_hal_bt_get_rssi());
furi_delay_ms(25); furi_delay_ms(bt_timeout);
furi_hal_bt_hid_kb_release(key); furi_hal_bt_hid_kb_release(key);
return (0); return (0);
} }
@@ -513,9 +543,13 @@ static void bad_ble_hid_state_callback(BtStatus status, void* context) {
BadBleScript* bad_ble = (BadBleScript*)context; BadBleScript* bad_ble = (BadBleScript*)context;
bool state = (status == BtStatusConnected); bool state = (status == BtStatusConnected);
if(state == true) if(state == true) {
LevelRssiRange r = bt_remote_rssi_range(bad_ble->bt);
if (r != LevelRssiError) {
bt_timeout = bt_hid_delays[r];
}
furi_thread_flags_set(furi_thread_get_id(bad_ble->thread), WorkerEvtConnect); furi_thread_flags_set(furi_thread_get_id(bad_ble->thread), WorkerEvtConnect);
else } else
furi_thread_flags_set(furi_thread_get_id(bad_ble->thread), WorkerEvtDisconnect); furi_thread_flags_set(furi_thread_get_id(bad_ble->thread), WorkerEvtDisconnect);
} }
@@ -525,6 +559,8 @@ static int32_t bad_ble_worker(void* context) {
BadBleWorkerState worker_state = BadBleStateInit; BadBleWorkerState worker_state = BadBleStateInit;
int32_t delay_val = 0; int32_t delay_val = 0;
bt_timeout = bt_hid_delays[LevelRssi39_0];
// init ble hid // init ble hid
bt_disconnect(bad_ble->bt); bt_disconnect(bad_ble->bt);
@@ -625,6 +661,10 @@ static int32_t bad_ble_worker(void* context) {
storage_file_seek(script_file, 0, true); storage_file_seek(script_file, 0, true);
// extra time for PC to recognize Flipper as keyboard // extra time for PC to recognize Flipper as keyboard
furi_thread_flags_wait(0, FuriFlagWaitAny, 1500); furi_thread_flags_wait(0, FuriFlagWaitAny, 1500);
update_bt_timeout(bad_ble->bt);
FURI_LOG_I(WORKER_TAG, "BLE Key timeout : %u", bt_timeout);
worker_state = BadBleStateRunning; worker_state = BadBleStateRunning;
} else if(flags & WorkerEvtToggle) { // Cancel scheduled execution } else if(flags & WorkerEvtToggle) { // Cancel scheduled execution
worker_state = BadBleStateNotConnected; worker_state = BadBleStateNotConnected;
@@ -685,6 +725,9 @@ static int32_t bad_ble_worker(void* context) {
break; break;
} }
} }
update_bt_timeout(bad_ble->bt);
FURI_LOG_I(WORKER_TAG, "BLE Key timeout : %u", bt_timeout);
} }
// release all keys // release all keys

View File

@@ -30,7 +30,6 @@ void bad_ble_scene_error_on_enter(void* context) {
app->widget, GuiButtonTypeLeft, "Back", bad_ble_scene_error_event_callback, app); app->widget, GuiButtonTypeLeft, "Back", bad_ble_scene_error_event_callback, app);
} else if(app->error == BadBleAppErrorCloseRpc) { } else if(app->error == BadBleAppErrorCloseRpc) {
widget_add_icon_element(app->widget, 78, 0, &I_ActiveConnection_50x64); widget_add_icon_element(app->widget, 78, 0, &I_ActiveConnection_50x64);
if (settings->sfw_mode) {
widget_add_string_multiline_element( widget_add_string_multiline_element(
app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "Connection\nis active!"); app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "Connection\nis active!");
widget_add_string_multiline_element( widget_add_string_multiline_element(
@@ -42,19 +41,6 @@ void bad_ble_scene_error_on_enter(void* context) {
FontSecondary, FontSecondary,
"Disconnect from\nPC or phone to\nuse this function."); "Disconnect from\nPC or phone to\nuse this function.");
} }
else {
widget_add_string_multiline_element(
app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "I am not\na whore!");
widget_add_string_multiline_element(
app->widget,
3,
30,
AlignLeft,
AlignTop,
FontSecondary,
"Pull out from\nPC or phone to\nuse me like this.");
}
}
view_dispatcher_switch_to_view(app->view_dispatcher, BadBleAppViewError); view_dispatcher_switch_to_view(app->view_dispatcher, BadBleAppViewError);
free(settings); free(settings);

View File

@@ -50,12 +50,7 @@ static void bad_ble_draw_callback(Canvas* canvas, void* _model) {
if((model->state.state == BadBleStateIdle) || (model->state.state == BadBleStateDone) || if((model->state.state == BadBleStateIdle) || (model->state.state == BadBleStateDone) ||
(model->state.state == BadBleStateNotConnected)) { (model->state.state == BadBleStateNotConnected)) {
if (settings->sfw_mode) {
elements_button_center(canvas, "Start"); elements_button_center(canvas, "Start");
}
else {
elements_button_center(canvas, "Cum");
}
} else if((model->state.state == BadBleStateRunning) || (model->state.state == BadBleStateDelay)) { } else if((model->state.state == BadBleStateRunning) || (model->state.state == BadBleStateDelay)) {
elements_button_center(canvas, "Stop"); elements_button_center(canvas, "Stop");
} else if(model->state.state == BadBleStateWillRun) { } else if(model->state.state == BadBleStateWillRun) {
@@ -70,23 +65,12 @@ static void bad_ble_draw_callback(Canvas* canvas, void* _model) {
if(model->state.state == BadBleStateNotConnected) { if(model->state.state == BadBleStateNotConnected) {
canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18); canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18);
canvas_set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
if (settings->sfw_mode) {
canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Connect me"); canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Connect me");
canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "to a computer"); canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "to a computer");
}
else {
canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Plug me");
canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "in, Daddy");
}
} else if(model->state.state == BadBleStateWillRun) { } else if(model->state.state == BadBleStateWillRun) {
canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18); canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18);
canvas_set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
if (settings->sfw_mode) {
canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Will run"); canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Will run");
}
else {
canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Will cum");
}
canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "on connect"); canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "on connect");
} else if(model->state.state == BadBleStateFileError) { } else if(model->state.state == BadBleStateFileError) {
canvas_draw_icon(canvas, 4, 26, &I_Error_18x18); canvas_draw_icon(canvas, 4, 26, &I_Error_18x18);

View File

@@ -428,6 +428,22 @@ const uint8_t *bt_get_profile_mac_address(Bt *bt) {
} }
} }
bool bt_remote_rssi(Bt *bt, BtRssi *rssi) {
furi_assert(bt);
UNUSED(rssi);
uint8_t rssi_val;
uint32_t since = furi_hal_bt_get_conn_rssi(&rssi_val);
if (since == 0)
return false;
rssi->rssi = rssi_val;
rssi->since = since;
return true;
}
int32_t bt_srv(void* p) { int32_t bt_srv(void* p) {
UNUSED(p); UNUSED(p);
Bt* bt = bt_alloc(); Bt* bt = bt_alloc();

View File

@@ -23,6 +23,12 @@ typedef enum {
BtProfileHidKeyboard, BtProfileHidKeyboard,
} BtProfile; } BtProfile;
typedef struct {
uint8_t rssi;
uint32_t since;
} BtRssi;
typedef void (*BtStatusChangedCallback)(BtStatus status, void* context); typedef void (*BtStatusChangedCallback)(BtStatus status, void* context);
/** Change BLE Profile /** Change BLE Profile
@@ -42,6 +48,8 @@ const char *bt_get_profile_adv_name(Bt *bt);
void bt_set_profile_mac_address(Bt *bt, const uint8_t mac[6]); void bt_set_profile_mac_address(Bt *bt, const uint8_t mac[6]);
const uint8_t *bt_get_profile_mac_address(Bt *bt); const uint8_t *bt_get_profile_mac_address(Bt *bt);
bool bt_remote_rssi(Bt *bt, BtRssi *rssi);
/** Disconnect from Central /** Disconnect from Central
* *

View File

@@ -1,5 +1,5 @@
entry,status,name,type,params entry,status,name,type,params
Version,v,12.7,, Version,v,12.12,,
Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,, Header,+,applications/services/cli/cli_vcp.h,,
@@ -575,6 +575,7 @@ Function,?,bt_get_profile_adv_name,const char*,Bt*
Function,?,bt_get_profile_mac_address,const uint8_t*,Bt* Function,?,bt_get_profile_mac_address,const uint8_t*,Bt*
Function,+,bt_keys_storage_set_default_path,void,Bt* Function,+,bt_keys_storage_set_default_path,void,Bt*
Function,+,bt_keys_storage_set_storage_path,void,"Bt*, const char*" Function,+,bt_keys_storage_set_storage_path,void,"Bt*, const char*"
Function,?,bt_remote_rssi,_Bool,"Bt*, BtRssi*"
Function,?,bt_set_profile,_Bool,"Bt*, BtProfile" Function,?,bt_set_profile,_Bool,"Bt*, BtProfile"
Function,?,bt_set_profile_adv_name,void,"Bt*, const char*, ..." Function,?,bt_set_profile_adv_name,void,"Bt*, const char*, ..."
Function,?,bt_set_profile_mac_address,void,"Bt*, const uint8_t[6]" Function,?,bt_set_profile_mac_address,void,"Bt*, const uint8_t[6]"
@@ -999,6 +1000,7 @@ Function,+,furi_hal_bt_change_app,_Bool,"FuriHalBtProfile, GapEventCallback, voi
Function,+,furi_hal_bt_clear_white_list,_Bool, Function,+,furi_hal_bt_clear_white_list,_Bool,
Function,+,furi_hal_bt_dump_state,void,FuriString* Function,+,furi_hal_bt_dump_state,void,FuriString*
Function,+,furi_hal_bt_ensure_c2_mode,_Bool,BleGlueC2Mode Function,+,furi_hal_bt_ensure_c2_mode,_Bool,BleGlueC2Mode
Function,?,furi_hal_bt_get_conn_rssi,uint32_t,uint8_t*
Function,+,furi_hal_bt_get_key_storage_buff,void,"uint8_t**, uint16_t*" Function,+,furi_hal_bt_get_key_storage_buff,void,"uint8_t**, uint16_t*"
Function,?,furi_hal_bt_get_profile_adv_name,const char*,FuriHalBtProfile Function,?,furi_hal_bt_get_profile_adv_name,const char*,FuriHalBtProfile
Function,?,furi_hal_bt_get_profile_mac_addr,const uint8_t*,FuriHalBtProfile Function,?,furi_hal_bt_get_profile_mac_addr,const uint8_t*,FuriHalBtProfile
@@ -1035,7 +1037,7 @@ Function,+,furi_hal_bt_serial_start,void,
Function,+,furi_hal_bt_serial_stop,void, Function,+,furi_hal_bt_serial_stop,void,
Function,+,furi_hal_bt_serial_tx,_Bool,"uint8_t*, uint16_t" Function,+,furi_hal_bt_serial_tx,_Bool,"uint8_t*, uint16_t"
Function,+,furi_hal_bt_set_key_storage_change_callback,void,"BleGlueKeyStorageChangedCallback, void*" Function,+,furi_hal_bt_set_key_storage_change_callback,void,"BleGlueKeyStorageChangedCallback, void*"
Function,?,furi_hal_bt_set_profile_adv_name,void,"FuriHalBtProfile, const char[( 1 + 8 + ( 8 + 1 ) )]" Function,?,furi_hal_bt_set_profile_adv_name,void,"FuriHalBtProfile, const char[( 1 + ( 8 + 1 ) ) - 1]"
Function,?,furi_hal_bt_set_profile_mac_addr,void,"FuriHalBtProfile, const uint8_t[( 6 )]" Function,?,furi_hal_bt_set_profile_mac_addr,void,"FuriHalBtProfile, const uint8_t[( 6 )]"
Function,+,furi_hal_bt_start_advertising,void, Function,+,furi_hal_bt_start_advertising,void,
Function,+,furi_hal_bt_start_app,_Bool,"FuriHalBtProfile, GapEventCallback, void*" Function,+,furi_hal_bt_start_app,_Bool,"FuriHalBtProfile, GapEventCallback, void*"
@@ -1578,6 +1580,7 @@ Function,-,gamma,double,double
Function,-,gamma_r,double,"double, int*" Function,-,gamma_r,double,"double, int*"
Function,-,gammaf,float,float Function,-,gammaf,float,float
Function,-,gammaf_r,float,"float, int*" Function,-,gammaf_r,float,"float, int*"
Function,?,gap_get_remote_conn_rssi,uint32_t,int8_t*
Function,-,gap_get_state,GapState, Function,-,gap_get_state,GapState,
Function,-,gap_init,_Bool,"GapConfig*, GapEventCallback, void*" Function,-,gap_init,_Bool,"GapConfig*, GapEventCallback, void*"
Function,-,gap_start_advertising,void, Function,-,gap_start_advertising,void,
1 entry status name type params
2 Version v 12.7 12.12
3 Header + applications/services/bt/bt_service/bt.h
4 Header + applications/services/cli/cli.h
5 Header + applications/services/cli/cli_vcp.h
575 Function ? bt_get_profile_mac_address const uint8_t* Bt*
576 Function + bt_keys_storage_set_default_path void Bt*
577 Function + bt_keys_storage_set_storage_path void Bt*, const char*
578 Function ? bt_remote_rssi _Bool Bt*, BtRssi*
579 Function ? bt_set_profile _Bool Bt*, BtProfile
580 Function ? bt_set_profile_adv_name void Bt*, const char*, ...
581 Function ? bt_set_profile_mac_address void Bt*, const uint8_t[6]
1000 Function + furi_hal_bt_clear_white_list _Bool
1001 Function + furi_hal_bt_dump_state void FuriString*
1002 Function + furi_hal_bt_ensure_c2_mode _Bool BleGlueC2Mode
1003 Function ? furi_hal_bt_get_conn_rssi uint32_t uint8_t*
1004 Function + furi_hal_bt_get_key_storage_buff void uint8_t**, uint16_t*
1005 Function ? furi_hal_bt_get_profile_adv_name const char* FuriHalBtProfile
1006 Function ? furi_hal_bt_get_profile_mac_addr const uint8_t* FuriHalBtProfile
1037 Function + furi_hal_bt_serial_stop void
1038 Function + furi_hal_bt_serial_tx _Bool uint8_t*, uint16_t
1039 Function + furi_hal_bt_set_key_storage_change_callback void BleGlueKeyStorageChangedCallback, void*
1040 Function ? furi_hal_bt_set_profile_adv_name void FuriHalBtProfile, const char[( 1 + 8 + ( 8 + 1 ) )] FuriHalBtProfile, const char[( 1 + ( 8 + 1 ) ) - 1]
1041 Function ? furi_hal_bt_set_profile_mac_addr void FuriHalBtProfile, const uint8_t[( 6 )]
1042 Function + furi_hal_bt_start_advertising void
1043 Function + furi_hal_bt_start_app _Bool FuriHalBtProfile, GapEventCallback, void*
1580 Function - gamma_r double double, int*
1581 Function - gammaf float float
1582 Function - gammaf_r float float, int*
1583 Function ? gap_get_remote_conn_rssi uint32_t int8_t*
1584 Function - gap_get_state GapState
1585 Function - gap_init _Bool GapConfig*, GapEventCallback, void*
1586 Function - gap_start_advertising void

View File

@@ -27,6 +27,8 @@ typedef struct {
GapConfig* config; GapConfig* config;
GapConnectionParams connection_params; GapConnectionParams connection_params;
GapState state; GapState state;
int8_t conn_rssi;
uint32_t time_rssi_sample;
FuriMutex* state_mutex; FuriMutex* state_mutex;
GapEventCallback on_event_cb; GapEventCallback on_event_cb;
void* context; void* context;
@@ -52,6 +54,16 @@ static const uint8_t gap_erk[16] =
static Gap* gap = NULL; static Gap* gap = NULL;
static inline void fetch_rssi() {
uint8_t ret_rssi = 127;
if (hci_read_rssi(gap->service.connection_handle, &ret_rssi) == BLE_STATUS_SUCCESS) {
gap->conn_rssi = (int8_t) ret_rssi;
gap->time_rssi_sample = furi_get_tick();
return;
}
FURI_LOG_E(TAG, "Failed to read RSSI");
}
static void gap_advertise_start(GapState new_state); static void gap_advertise_start(GapState new_state);
static int32_t gap_app(void* context); static int32_t gap_app(void* context);
@@ -125,6 +137,9 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
gap->connection_params.supervisor_timeout = event->Supervision_Timeout; gap->connection_params.supervisor_timeout = event->Supervision_Timeout;
FURI_LOG_I(TAG, "Connection parameters event complete"); FURI_LOG_I(TAG, "Connection parameters event complete");
gap_verify_connection_parameters(gap); gap_verify_connection_parameters(gap);
// save rssi for current connection
fetch_rssi();
break; break;
} }
@@ -151,6 +166,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
gap->connection_params.slave_latency = event->Conn_Latency; gap->connection_params.slave_latency = event->Conn_Latency;
gap->connection_params.supervisor_timeout = event->Supervision_Timeout; gap->connection_params.supervisor_timeout = event->Supervision_Timeout;
// Stop advertising as connection completed // Stop advertising as connection completed
furi_timer_stop(gap->advertise_timer); furi_timer_stop(gap->advertise_timer);
@@ -159,6 +175,9 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
gap->service.connection_handle = event->Connection_Handle; gap->service.connection_handle = event->Connection_Handle;
gap_verify_connection_parameters(gap); gap_verify_connection_parameters(gap);
fetch_rssi();
// Start pairing by sending security request // Start pairing by sending security request
aci_gap_slave_security_req(event->Connection_Handle); aci_gap_slave_security_req(event->Connection_Handle);
} break; } break;
@@ -243,6 +262,8 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
pairing_complete->Status); pairing_complete->Status);
aci_gap_terminate(gap->service.connection_handle, 5); aci_gap_terminate(gap->service.connection_handle, 5);
} else { } else {
fetch_rssi();
FURI_LOG_I(TAG, "Pairing complete"); FURI_LOG_I(TAG, "Pairing complete");
GapEvent event = {.type = GapEventTypeConnected}; GapEvent event = {.type = GapEventTypeConnected};
gap->on_event_cb(event, gap->context); //-V595 gap->on_event_cb(event, gap->context); //-V595
@@ -495,6 +516,9 @@ bool gap_init(GapConfig* config, GapEventCallback on_event_cb, void* context) {
gap->service.connection_handle = 0xFFFF; gap->service.connection_handle = 0xFFFF;
gap->enable_adv = true; gap->enable_adv = true;
gap->conn_rssi = 127;
gap->time_rssi_sample = 0;
// Thread configuration // Thread configuration
gap->thread = furi_thread_alloc_ex("BleGapDriver", 1024, gap_app, gap); gap->thread = furi_thread_alloc_ex("BleGapDriver", 1024, gap_app, gap);
furi_thread_start(gap->thread); furi_thread_start(gap->thread);
@@ -514,6 +538,19 @@ bool gap_init(GapConfig* config, GapEventCallback on_event_cb, void* context) {
return true; return true;
} }
uint32_t gap_get_remote_conn_rssi(int8_t *rssi) {
if (gap && gap->state == GapStateConnected) {
fetch_rssi();
*rssi = gap->conn_rssi;
FURI_LOG_D(TAG, "RSSI: %d", *rssi);
if (gap->time_rssi_sample)
return furi_get_tick() - gap->time_rssi_sample;
}
return 0;
}
GapState gap_get_state() { GapState gap_get_state() {
GapState state; GapState state;
if(gap) { if(gap) {

View File

@@ -81,6 +81,8 @@ GapState gap_get_state();
void gap_thread_stop(); void gap_thread_stop();
uint32_t gap_get_remote_conn_rssi(int8_t *rssi);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -425,6 +425,23 @@ float furi_hal_bt_get_rssi() {
return val; return val;
} }
/** fill the RSSI of the remote host of the bt connection and returns the time since
* the beginning of the connection
*
*/
uint32_t furi_hal_bt_get_conn_rssi(uint8_t *rssi) {
int8_t ret_rssi = 0;
uint32_t since = gap_get_remote_conn_rssi(&ret_rssi);
if (ret_rssi == 127 || since == 0)
return 0;
*rssi = (uint8_t) abs(ret_rssi);
return since;
}
uint32_t furi_hal_bt_get_transmitted_packets() { uint32_t furi_hal_bt_get_transmitted_packets() {
uint32_t packets = 0; uint32_t packets = 0;
aci_hal_le_tx_test_packet_number(&packets); aci_hal_le_tx_test_packet_number(&packets);
@@ -450,13 +467,14 @@ bool furi_hal_bt_ensure_c2_mode(BleGlueC2Mode mode) {
return false; return false;
} }
void furi_hal_bt_set_profile_adv_name(FuriHalBtProfile profile, const char name[FURI_HAL_VERSION_DEVICE_NAME_LENGTH]) { void furi_hal_bt_set_profile_adv_name(
FuriHalBtProfile profile,
const char name[FURI_HAL_VERSION_DEVICE_NAME_LENGTH-1]) {
furi_assert(profile < FuriHalBtProfileNumber); furi_assert(profile < FuriHalBtProfileNumber);
furi_assert(name); furi_assert(name);
memcpy(&(profile_config[profile].config.adv_name[1]), memcpy(
name, FURI_HAL_VERSION_DEVICE_NAME_LENGTH); &(profile_config[profile].config.adv_name[1]), name, FURI_HAL_VERSION_DEVICE_NAME_LENGTH-1);
} }
const char* furi_hal_bt_get_profile_adv_name(FuriHalBtProfile profile) { const char* furi_hal_bt_get_profile_adv_name(FuriHalBtProfile profile) {
@@ -471,7 +489,6 @@ void furi_hal_bt_set_profile_mac_addr(
furi_assert(mac_addr); furi_assert(mac_addr);
memcpy(profile_config[profile].config.mac_address, mac_addr, GAP_MAC_ADDR_SIZE); memcpy(profile_config[profile].config.mac_address, mac_addr, GAP_MAC_ADDR_SIZE);
} }
const uint8_t* furi_hal_bt_get_profile_mac_addr(FuriHalBtProfile profile) { const uint8_t* furi_hal_bt_get_profile_mac_addr(FuriHalBtProfile profile) {

View File

@@ -224,14 +224,24 @@ uint32_t furi_hal_bt_get_transmitted_packets();
*/ */
bool furi_hal_bt_ensure_c2_mode(BleGlueC2Mode mode); bool furi_hal_bt_ensure_c2_mode(BleGlueC2Mode mode);
void furi_hal_bt_set_profile_adv_name(FuriHalBtProfile profile, const char name[FURI_HAL_VERSION_DEVICE_NAME_LENGTH]); /** Modify profile advertisement name and restart bluetooth
* @param[in] profile profile type
* @param[in] name new adv name
*/
void furi_hal_bt_set_profile_adv_name(FuriHalBtProfile profile, const char name[FURI_HAL_VERSION_DEVICE_NAME_LENGTH-1]);
const char *furi_hal_bt_get_profile_adv_name(FuriHalBtProfile profile); const char *furi_hal_bt_get_profile_adv_name(FuriHalBtProfile profile);
/** Modify profile mac address and restart bluetooth
* @param[in] profile profile type
* @param[in] mac new mac address
*/
void furi_hal_bt_set_profile_mac_addr(FuriHalBtProfile profile, const uint8_t mac_addr[GAP_MAC_ADDR_SIZE]); void furi_hal_bt_set_profile_mac_addr(FuriHalBtProfile profile, const uint8_t mac_addr[GAP_MAC_ADDR_SIZE]);
const uint8_t *furi_hal_bt_get_profile_mac_addr(FuriHalBtProfile profile); const uint8_t *furi_hal_bt_get_profile_mac_addr(FuriHalBtProfile profile);
uint32_t furi_hal_bt_get_conn_rssi(uint8_t *rssi);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

3146
flipper.log Normal file

File diff suppressed because it is too large Load Diff