mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-21 05:04:46 -07:00
ble: profile rework (#3272)
* ble: profile rework, initial * apps: hid: fix for pairing cleanup * app: hid: select transport based on #define * fixing PVS warnings * ble: serial service: fixed uid naming * bt service: on-demand dialog init; ble profiles: docs; battery svc: proper update * Added shci_cmd_resp_wait/shci_cmd_resp_release impl with semaphore * app: hid: separated transport code * ble: fixed service init order for serial svc; moved hardfault check to ble_glue * cli: ps: added thread prio to output, fixed heap display * ble_glue: naming changes; separate thread for event processing; * furi: added runtime stats; cli: added cpu% to `ps` * cli: fixed thread time calculation * furi: added getter for thread priority * fixing pvs warnings * hid profile: fixed naming * more naming fixes * hal: ble init small cleanup * cleanup & draft beacon api * f18: api sync * apps: moved example_custom_font from debug to examples * BLE extra beacon demo app * naming fix * UI fixes for demo app (wip) * desktop, ble svc: added statusbar icon for beacon * minor cleanup * Minor cleanup & naming fixes * api sync * Removed stale header * hal: added FURI_BLE_EXTRA_LOG for extra logging; comments & code cleanup * naming & macro fixes * quick fixes from review * Eliminated stock svc_ctl * cli: ps: removed runtime stats * minor include fixes * (void) * naming fixes * More naming fixes * fbt: always build all libs * fbt: explicitly globbing libs; dist: logging SDK path * scripts: fixed lib path precedence * hal: bt: profiles: naming changes, support for passing params to a profile; include cleanup * ble: hid: added parameter processing for profile template * api sync * BLE HID: long name trim * Removed unused check * desktop: updated beacon status icon; ble: hid: cleaner device name management * desktop: updated status icon Co-authored-by: あく <alleteam@gmail.com> Co-authored-by: nminaylov <nm29719@gmail.com>
This commit is contained in:
@@ -1,28 +1,30 @@
|
||||
#include "battery_service.h"
|
||||
#include "app_common.h"
|
||||
#include "gatt_char.h"
|
||||
#include <core/check.h>
|
||||
#include <furi_ble/gatt.h>
|
||||
|
||||
#include <ble/ble.h>
|
||||
|
||||
#include <furi.h>
|
||||
#include <furi_hal_power.h>
|
||||
|
||||
#include <m-list.h>
|
||||
|
||||
#define TAG "BtBatterySvc"
|
||||
|
||||
enum {
|
||||
// Common states
|
||||
/* Common states */
|
||||
BatterySvcPowerStateUnknown = 0b00,
|
||||
BatterySvcPowerStateUnsupported = 0b01,
|
||||
// Level states
|
||||
/* Level states */
|
||||
BatterySvcPowerStateGoodLevel = 0b10,
|
||||
BatterySvcPowerStateCriticallyLowLevel = 0b11,
|
||||
// Charging states
|
||||
/* Charging states */
|
||||
BatterySvcPowerStateNotCharging = 0b10,
|
||||
BatterySvcPowerStateCharging = 0b11,
|
||||
// Discharging states
|
||||
/* Discharging states */
|
||||
BatterySvcPowerStateNotDischarging = 0b10,
|
||||
BatterySvcPowerStateDischarging = 0b11,
|
||||
// Battery states
|
||||
/* Battery states */
|
||||
BatterySvcPowerStateBatteryNotPresent = 0b10,
|
||||
BatterySvcPowerStateBatteryPresent = 0b11,
|
||||
};
|
||||
@@ -46,96 +48,110 @@ typedef enum {
|
||||
BatterySvcGattCharacteristicCount,
|
||||
} BatterySvcGattCharacteristicId;
|
||||
|
||||
static const FlipperGattCharacteristicParams battery_svc_chars[BatterySvcGattCharacteristicCount] =
|
||||
{[BatterySvcGattCharacteristicBatteryLevel] =
|
||||
{.name = "Battery Level",
|
||||
.data_prop_type = FlipperGattCharacteristicDataFixed,
|
||||
.data.fixed.length = 1,
|
||||
.uuid.Char_UUID_16 = BATTERY_LEVEL_CHAR_UUID,
|
||||
.uuid_type = UUID_TYPE_16,
|
||||
.char_properties = CHAR_PROP_READ | CHAR_PROP_NOTIFY,
|
||||
.security_permissions = ATTR_PERMISSION_AUTHEN_READ,
|
||||
.gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS,
|
||||
.is_variable = CHAR_VALUE_LEN_CONSTANT},
|
||||
[BatterySvcGattCharacteristicPowerState] = {
|
||||
.name = "Power State",
|
||||
static const BleGattCharacteristicParams battery_svc_chars[BatterySvcGattCharacteristicCount] = {
|
||||
[BatterySvcGattCharacteristicBatteryLevel] =
|
||||
{.name = "Battery Level",
|
||||
.data_prop_type = FlipperGattCharacteristicDataFixed,
|
||||
.data.fixed.length = 1,
|
||||
.uuid.Char_UUID_16 = BATTERY_POWER_STATE,
|
||||
.uuid.Char_UUID_16 = BATTERY_LEVEL_CHAR_UUID,
|
||||
.uuid_type = UUID_TYPE_16,
|
||||
.char_properties = CHAR_PROP_READ | CHAR_PROP_NOTIFY,
|
||||
.security_permissions = ATTR_PERMISSION_AUTHEN_READ,
|
||||
.gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS,
|
||||
.is_variable = CHAR_VALUE_LEN_CONSTANT}};
|
||||
.is_variable = CHAR_VALUE_LEN_CONSTANT},
|
||||
[BatterySvcGattCharacteristicPowerState] = {
|
||||
.name = "Power State",
|
||||
.data_prop_type = FlipperGattCharacteristicDataFixed,
|
||||
.data.fixed.length = 1,
|
||||
.uuid.Char_UUID_16 = BATTERY_POWER_STATE,
|
||||
.uuid_type = UUID_TYPE_16,
|
||||
.char_properties = CHAR_PROP_READ | CHAR_PROP_NOTIFY,
|
||||
.security_permissions = ATTR_PERMISSION_AUTHEN_READ,
|
||||
.gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS,
|
||||
.is_variable = CHAR_VALUE_LEN_CONSTANT}};
|
||||
|
||||
typedef struct {
|
||||
struct BleServiceBattery {
|
||||
uint16_t svc_handle;
|
||||
FlipperGattCharacteristicInstance chars[BatterySvcGattCharacteristicCount];
|
||||
} BatterySvc;
|
||||
BleGattCharacteristicInstance chars[BatterySvcGattCharacteristicCount];
|
||||
bool auto_update;
|
||||
};
|
||||
|
||||
static BatterySvc* battery_svc = NULL;
|
||||
LIST_DEF(BatterySvcInstanceList, BleServiceBattery*, M_POD_OPLIST);
|
||||
|
||||
void battery_svc_start() {
|
||||
battery_svc = malloc(sizeof(BatterySvc));
|
||||
tBleStatus status;
|
||||
/* We need to keep track of all battery service instances so that we can update
|
||||
* them when the battery state changes. */
|
||||
static BatterySvcInstanceList_t instances;
|
||||
static bool instances_initialized = false;
|
||||
|
||||
// Add Battery service
|
||||
status = aci_gatt_add_service(
|
||||
UUID_TYPE_16, (Service_UUID_t*)&service_uuid, PRIMARY_SERVICE, 8, &battery_svc->svc_handle);
|
||||
if(status) {
|
||||
FURI_LOG_E(TAG, "Failed to add Battery service: %d", status);
|
||||
BleServiceBattery* ble_svc_battery_start(bool auto_update) {
|
||||
BleServiceBattery* battery_svc = malloc(sizeof(BleServiceBattery));
|
||||
|
||||
if(!ble_gatt_service_add(
|
||||
UUID_TYPE_16,
|
||||
(Service_UUID_t*)&service_uuid,
|
||||
PRIMARY_SERVICE,
|
||||
8,
|
||||
&battery_svc->svc_handle)) {
|
||||
free(battery_svc);
|
||||
return NULL;
|
||||
}
|
||||
for(size_t i = 0; i < BatterySvcGattCharacteristicCount; i++) {
|
||||
flipper_gatt_characteristic_init(
|
||||
ble_gatt_characteristic_init(
|
||||
battery_svc->svc_handle, &battery_svc_chars[i], &battery_svc->chars[i]);
|
||||
}
|
||||
|
||||
battery_svc_update_power_state();
|
||||
}
|
||||
|
||||
void battery_svc_stop() {
|
||||
tBleStatus status;
|
||||
if(battery_svc) {
|
||||
for(size_t i = 0; i < BatterySvcGattCharacteristicCount; i++) {
|
||||
flipper_gatt_characteristic_delete(battery_svc->svc_handle, &battery_svc->chars[i]);
|
||||
battery_svc->auto_update = auto_update;
|
||||
if(auto_update) {
|
||||
if(!instances_initialized) {
|
||||
BatterySvcInstanceList_init(instances);
|
||||
instances_initialized = true;
|
||||
}
|
||||
// Delete Battery service
|
||||
status = aci_gatt_del_service(battery_svc->svc_handle);
|
||||
if(status) {
|
||||
FURI_LOG_E(TAG, "Failed to delete Battery service: %d", status);
|
||||
|
||||
BatterySvcInstanceList_push_back(instances, battery_svc);
|
||||
}
|
||||
|
||||
return battery_svc;
|
||||
}
|
||||
|
||||
void ble_svc_battery_stop(BleServiceBattery* battery_svc) {
|
||||
furi_assert(battery_svc);
|
||||
if(battery_svc->auto_update) {
|
||||
BatterySvcInstanceList_it_t it;
|
||||
for(BatterySvcInstanceList_it(it, instances); !BatterySvcInstanceList_end_p(it);
|
||||
BatterySvcInstanceList_next(it)) {
|
||||
if(*BatterySvcInstanceList_ref(it) == battery_svc) {
|
||||
BatterySvcInstanceList_remove(instances, it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(battery_svc);
|
||||
battery_svc = NULL;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < BatterySvcGattCharacteristicCount; i++) {
|
||||
ble_gatt_characteristic_delete(battery_svc->svc_handle, &battery_svc->chars[i]);
|
||||
}
|
||||
/* Delete Battery service */
|
||||
ble_gatt_service_delete(battery_svc->svc_handle);
|
||||
free(battery_svc);
|
||||
}
|
||||
|
||||
bool battery_svc_is_started() {
|
||||
return battery_svc != NULL;
|
||||
}
|
||||
|
||||
bool battery_svc_update_level(uint8_t battery_charge) {
|
||||
// Check if service was started
|
||||
if(battery_svc == NULL) {
|
||||
return false;
|
||||
}
|
||||
// Update battery level characteristic
|
||||
return flipper_gatt_characteristic_update(
|
||||
bool ble_svc_battery_update_level(BleServiceBattery* battery_svc, uint8_t battery_charge) {
|
||||
furi_check(battery_svc);
|
||||
/* Update battery level characteristic */
|
||||
return ble_gatt_characteristic_update(
|
||||
battery_svc->svc_handle,
|
||||
&battery_svc->chars[BatterySvcGattCharacteristicBatteryLevel],
|
||||
&battery_charge);
|
||||
}
|
||||
|
||||
bool battery_svc_update_power_state() {
|
||||
// Check if service was started
|
||||
if(battery_svc == NULL) {
|
||||
return false;
|
||||
}
|
||||
// Update power state characteristic
|
||||
bool ble_svc_battery_update_power_state(BleServiceBattery* battery_svc, bool charging) {
|
||||
furi_check(battery_svc);
|
||||
|
||||
/* Update power state characteristic */
|
||||
BattrySvcPowerState power_state = {
|
||||
.level = BatterySvcPowerStateUnsupported,
|
||||
.present = BatterySvcPowerStateBatteryPresent,
|
||||
};
|
||||
if(furi_hal_power_is_charging()) {
|
||||
if(charging) {
|
||||
power_state.charging = BatterySvcPowerStateCharging;
|
||||
power_state.discharging = BatterySvcPowerStateNotDischarging;
|
||||
} else {
|
||||
@@ -143,8 +159,29 @@ bool battery_svc_update_power_state() {
|
||||
power_state.discharging = BatterySvcPowerStateDischarging;
|
||||
}
|
||||
|
||||
return flipper_gatt_characteristic_update(
|
||||
return ble_gatt_characteristic_update(
|
||||
battery_svc->svc_handle,
|
||||
&battery_svc->chars[BatterySvcGattCharacteristicPowerState],
|
||||
&power_state);
|
||||
}
|
||||
|
||||
void ble_svc_battery_state_update(uint8_t* battery_level, bool* charging) {
|
||||
if(!instances_initialized) {
|
||||
#ifdef FURI_BLE_EXTRA_LOG
|
||||
FURI_LOG_W(TAG, "Battery service not initialized");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
BatterySvcInstanceList_it_t it;
|
||||
for(BatterySvcInstanceList_it(it, instances); !BatterySvcInstanceList_end_p(it);
|
||||
BatterySvcInstanceList_next(it)) {
|
||||
BleServiceBattery* battery_svc = *BatterySvcInstanceList_ref(it);
|
||||
if(battery_level) {
|
||||
ble_svc_battery_update_level(battery_svc, *battery_level);
|
||||
}
|
||||
if(charging) {
|
||||
ble_svc_battery_update_power_state(battery_svc, *charging);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user