Files
Momentum-Firmware/revert_gatt_char_refactor.patch
2023-06-12 02:35:33 +01:00

2182 lines
84 KiB
Diff

diff --git a/applications/services/bt/bt_service/bt.c b/applications/services/bt/bt_service/bt.c
index 882fd11e85..b8cb09734d 100644
--- a/applications/services/bt/bt_service/bt.c
+++ b/applications/services/bt/bt_service/bt.c
@@ -1,7 +1,7 @@
#include "bt_i.h"
+#include "battery_service.h"
#include "bt_keys_storage.h"
-#include <services/battery_service.h>
#include <notification/notification_messages.h>
#include <gui/elements.h>
#include <assets_icons.h>
diff --git a/firmware/targets/f7/ble_glue/app_debug.c b/firmware/targets/f7/ble_glue/app_debug.c
index 35f53ae22c..78e789ac30 100644
--- a/firmware/targets/f7/ble_glue/app_debug.c
+++ b/firmware/targets/f7/ble_glue/app_debug.c
@@ -195,14 +195,14 @@ static void APPD_SetCPU2GpioConfig(void) {
gpio_config.Pin = gpiob_pin_list;
LL_C2_AHB2_GRP1_EnableClock(LL_C2_AHB2_GRP1_PERIPH_GPIOB);
LL_GPIO_Init(GPIOB, &gpio_config);
- LL_GPIO_ResetOutputPin(GPIOB, gpiob_pin_list);
+ LL_GPIO_ResetOutputPin(GPIOB, gpioa_pin_list);
}
if(gpioc_pin_list != 0) {
gpio_config.Pin = gpioc_pin_list;
LL_C2_AHB2_GRP1_EnableClock(LL_C2_AHB2_GRP1_PERIPH_GPIOC);
LL_GPIO_Init(GPIOC, &gpio_config);
- LL_GPIO_ResetOutputPin(GPIOC, gpioc_pin_list);
+ LL_GPIO_ResetOutputPin(GPIOC, gpioa_pin_list);
}
}
diff --git a/firmware/targets/f7/ble_glue/services/battery_service.c b/firmware/targets/f7/ble_glue/battery_service.c
similarity index 53%
rename from firmware/targets/f7/ble_glue/services/battery_service.c
rename to firmware/targets/f7/ble_glue/battery_service.c
index 63f736b3b7..8c371efadb 100644
--- a/firmware/targets/f7/ble_glue/services/battery_service.c
+++ b/firmware/targets/f7/ble_glue/battery_service.c
@@ -1,7 +1,5 @@
#include "battery_service.h"
#include "app_common.h"
-#include "gatt_char.h"
-
#include <ble/ble.h>
#include <furi.h>
@@ -9,6 +7,12 @@
#define TAG "BtBatterySvc"
+typedef struct {
+ uint16_t svc_handle;
+ uint16_t battery_level_char_handle;
+ uint16_t power_state_char_handle;
+} BatterySvc;
+
enum {
// Common states
BatterySvcPowerStateUnknown = 0b00,
@@ -36,44 +40,13 @@ typedef struct {
_Static_assert(sizeof(BattrySvcPowerState) == 1, "Incorrect structure size");
+static BatterySvc* battery_svc = NULL;
+
#define BATTERY_POWER_STATE (0x2A1A)
static const uint16_t service_uuid = BATTERY_SERVICE_UUID;
-
-typedef enum {
- BatterySvcGattCharacteristicBatteryLevel = 0,
- BatterySvcGattCharacteristicPowerState,
- 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",
- .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 {
- uint16_t svc_handle;
- FlipperGattCharacteristicInstance chars[BatterySvcGattCharacteristicCount];
-} BatterySvc;
-
-static BatterySvc* battery_svc = NULL;
+static const uint16_t battery_level_char_uuid = BATTERY_LEVEL_CHAR_UUID;
+static const uint16_t power_state_char_uuid = BATTERY_POWER_STATE;
void battery_svc_start() {
battery_svc = malloc(sizeof(BatterySvc));
@@ -85,19 +58,53 @@ void battery_svc_start() {
if(status) {
FURI_LOG_E(TAG, "Failed to add Battery service: %d", status);
}
- for(size_t i = 0; i < BatterySvcGattCharacteristicCount; i++) {
- flipper_gatt_characteristic_init(
- battery_svc->svc_handle, &battery_svc_chars[i], &battery_svc->chars[i]);
+ // Add Battery level characteristic
+ status = aci_gatt_add_char(
+ battery_svc->svc_handle,
+ UUID_TYPE_16,
+ (Char_UUID_t*)&battery_level_char_uuid,
+ 1,
+ CHAR_PROP_READ | CHAR_PROP_NOTIFY,
+ ATTR_PERMISSION_AUTHEN_READ,
+ GATT_DONT_NOTIFY_EVENTS,
+ 10,
+ CHAR_VALUE_LEN_CONSTANT,
+ &battery_svc->battery_level_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add Battery level characteristic: %d", status);
}
-
+ // Add Power state characteristic
+ status = aci_gatt_add_char(
+ battery_svc->svc_handle,
+ UUID_TYPE_16,
+ (Char_UUID_t*)&power_state_char_uuid,
+ 1,
+ CHAR_PROP_READ | CHAR_PROP_NOTIFY,
+ ATTR_PERMISSION_AUTHEN_READ,
+ GATT_DONT_NOTIFY_EVENTS,
+ 10,
+ CHAR_VALUE_LEN_CONSTANT,
+ &battery_svc->power_state_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add Battery level characteristic: %d", status);
+ }
+ // Update power state charachteristic
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]);
+ // Delete Battery level characteristic
+ status =
+ aci_gatt_del_char(battery_svc->svc_handle, battery_svc->battery_level_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete Battery level characteristic: %d", status);
+ }
+ // Delete Power state characteristic
+ status = aci_gatt_del_char(battery_svc->svc_handle, battery_svc->power_state_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete Battery level characteristic: %d", status);
}
// Delete Battery service
status = aci_gatt_del_service(battery_svc->svc_handle);
@@ -119,10 +126,13 @@ bool battery_svc_update_level(uint8_t battery_charge) {
return false;
}
// Update battery level characteristic
- return flipper_gatt_characteristic_update(
- battery_svc->svc_handle,
- &battery_svc->chars[BatterySvcGattCharacteristicBatteryLevel],
- &battery_charge);
+ FURI_LOG_D(TAG, "Updating battery level characteristic");
+ tBleStatus result = aci_gatt_update_char_value(
+ battery_svc->svc_handle, battery_svc->battery_level_char_handle, 0, 1, &battery_charge);
+ if(result) {
+ FURI_LOG_E(TAG, "Failed updating RX characteristic: %d", result);
+ }
+ return result != BLE_STATUS_SUCCESS;
}
bool battery_svc_update_power_state() {
@@ -142,9 +152,15 @@ bool battery_svc_update_power_state() {
power_state.charging = BatterySvcPowerStateNotCharging;
power_state.discharging = BatterySvcPowerStateDischarging;
}
-
- return flipper_gatt_characteristic_update(
+ FURI_LOG_D(TAG, "Updating power state characteristic");
+ tBleStatus result = aci_gatt_update_char_value(
battery_svc->svc_handle,
- &battery_svc->chars[BatterySvcGattCharacteristicPowerState],
- &power_state);
+ battery_svc->power_state_char_handle,
+ 0,
+ 1,
+ (uint8_t*)&power_state);
+ if(result) {
+ FURI_LOG_E(TAG, "Failed updating Power state characteristic: %d", result);
+ }
+ return result != BLE_STATUS_SUCCESS;
}
diff --git a/firmware/targets/f7/ble_glue/services/battery_service.h b/firmware/targets/f7/ble_glue/battery_service.h
similarity index 100%
rename from firmware/targets/f7/ble_glue/services/battery_service.h
rename to firmware/targets/f7/ble_glue/battery_service.h
diff --git a/firmware/targets/f7/ble_glue/ble_app.c b/firmware/targets/f7/ble_glue/ble_app.c
index 7a2148b6b8..4fc4d521be 100644
--- a/firmware/targets/f7/ble_glue/ble_app.c
+++ b/firmware/targets/f7/ble_glue/ble_app.c
@@ -33,45 +33,6 @@ static int32_t ble_app_hci_thread(void* context);
static void ble_app_hci_event_handler(void* pPayload);
static void ble_app_hci_status_not_handler(HCI_TL_CmdStatus_t status);
-static const HCI_TL_HciInitConf_t hci_tl_config = {
- .p_cmdbuffer = (uint8_t*)&ble_app_cmd_buffer,
- .StatusNotCallBack = ble_app_hci_status_not_handler,
-};
-
-static const SHCI_C2_CONFIG_Cmd_Param_t config_param = {
- .PayloadCmdSize = SHCI_C2_CONFIG_PAYLOAD_CMD_SIZE,
- .Config1 = SHCI_C2_CONFIG_CONFIG1_BIT0_BLE_NVM_DATA_TO_SRAM,
- .BleNvmRamAddress = (uint32_t)ble_app_nvm,
- .EvtMask1 = SHCI_C2_CONFIG_EVTMASK1_BIT1_BLE_NVM_RAM_UPDATE_ENABLE,
-};
-
-static const SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = {
- .Header = {{0, 0, 0}}, // Header unused
- .Param = {
- .pBleBufferAddress = 0, // pBleBufferAddress not used
- .BleBufferSize = 0, // BleBufferSize not used
- .NumAttrRecord = CFG_BLE_NUM_GATT_ATTRIBUTES,
- .NumAttrServ = CFG_BLE_NUM_GATT_SERVICES,
- .AttrValueArrSize = CFG_BLE_ATT_VALUE_ARRAY_SIZE,
- .NumOfLinks = CFG_BLE_NUM_LINK,
- .ExtendedPacketLengthEnable = CFG_BLE_DATA_LENGTH_EXTENSION,
- .PrWriteListSize = CFG_BLE_PREPARE_WRITE_LIST_SIZE,
- .MblockCount = CFG_BLE_MBLOCK_COUNT,
- .AttMtu = CFG_BLE_MAX_ATT_MTU,
- .SlaveSca = CFG_BLE_SLAVE_SCA,
- .MasterSca = CFG_BLE_MASTER_SCA,
- .LsSource = CFG_BLE_LSE_SOURCE,
- .MaxConnEventLength = CFG_BLE_MAX_CONN_EVENT_LENGTH,
- .HsStartupTime = CFG_BLE_HSE_STARTUP_TIME,
- .ViterbiEnable = CFG_BLE_VITERBI_MODE,
- .Options = CFG_BLE_OPTIONS,
- .HwVersion = 0,
- .max_coc_initiator_nbr = 32,
- .min_tx_power = 0,
- .max_tx_power = 0,
- .rx_model_config = 1,
- }};
-
bool ble_app_init() {
SHCI_CmdStatus_t status;
ble_app = malloc(sizeof(BleApp));
@@ -83,16 +44,52 @@ bool ble_app_init() {
furi_thread_start(ble_app->thread);
// Initialize Ble Transport Layer
+ HCI_TL_HciInitConf_t hci_tl_config = {
+ .p_cmdbuffer = (uint8_t*)&ble_app_cmd_buffer,
+ .StatusNotCallBack = ble_app_hci_status_not_handler,
+ };
hci_init(ble_app_hci_event_handler, (void*)&hci_tl_config);
// Configure NVM store for pairing data
- status = SHCI_C2_Config((SHCI_C2_CONFIG_Cmd_Param_t*)&config_param);
+ SHCI_C2_CONFIG_Cmd_Param_t config_param = {
+ .PayloadCmdSize = SHCI_C2_CONFIG_PAYLOAD_CMD_SIZE,
+ .Config1 = SHCI_C2_CONFIG_CONFIG1_BIT0_BLE_NVM_DATA_TO_SRAM,
+ .BleNvmRamAddress = (uint32_t)ble_app_nvm,
+ .EvtMask1 = SHCI_C2_CONFIG_EVTMASK1_BIT1_BLE_NVM_RAM_UPDATE_ENABLE,
+ };
+ status = SHCI_C2_Config(&config_param);
if(status) {
FURI_LOG_E(TAG, "Failed to configure 2nd core: %d", status);
}
// Start ble stack on 2nd core
- status = SHCI_C2_BLE_Init((SHCI_C2_Ble_Init_Cmd_Packet_t*)&ble_init_cmd_packet);
+ SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = {
+ .Header = {{0, 0, 0}}, // Header unused
+ .Param = {
+ .pBleBufferAddress = 0, // pBleBufferAddress not used
+ .BleBufferSize = 0, // BleBufferSize not used
+ .NumAttrRecord = CFG_BLE_NUM_GATT_ATTRIBUTES,
+ .NumAttrServ = CFG_BLE_NUM_GATT_SERVICES,
+ .AttrValueArrSize = CFG_BLE_ATT_VALUE_ARRAY_SIZE,
+ .NumOfLinks = CFG_BLE_NUM_LINK,
+ .ExtendedPacketLengthEnable = CFG_BLE_DATA_LENGTH_EXTENSION,
+ .PrWriteListSize = CFG_BLE_PREPARE_WRITE_LIST_SIZE,
+ .MblockCount = CFG_BLE_MBLOCK_COUNT,
+ .AttMtu = CFG_BLE_MAX_ATT_MTU,
+ .SlaveSca = CFG_BLE_SLAVE_SCA,
+ .MasterSca = CFG_BLE_MASTER_SCA,
+ .LsSource = CFG_BLE_LSE_SOURCE,
+ .MaxConnEventLength = CFG_BLE_MAX_CONN_EVENT_LENGTH,
+ .HsStartupTime = CFG_BLE_HSE_STARTUP_TIME,
+ .ViterbiEnable = CFG_BLE_VITERBI_MODE,
+ .Options = CFG_BLE_OPTIONS,
+ .HwVersion = 0,
+ .max_coc_initiator_nbr = 32,
+ .min_tx_power = 0,
+ .max_tx_power = 0,
+ .rx_model_config = 1,
+ }};
+ status = SHCI_C2_BLE_Init(&ble_init_cmd_packet);
if(status) {
FURI_LOG_E(TAG, "Failed to start ble stack: %d", status);
}
diff --git a/firmware/targets/f7/ble_glue/dev_info_service.c b/firmware/targets/f7/ble_glue/dev_info_service.c
new file mode 100644
index 0000000000..d24058632f
--- /dev/null
+++ b/firmware/targets/f7/ble_glue/dev_info_service.c
@@ -0,0 +1,220 @@
+#include "dev_info_service.h"
+#include "app_common.h"
+#include <ble/ble.h>
+
+#include <furi.h>
+#include <protobuf_version.h>
+#include <lib/toolbox/version.h>
+
+#define TAG "BtDevInfoSvc"
+
+typedef struct {
+ uint16_t service_handle;
+ uint16_t man_name_char_handle;
+ uint16_t serial_num_char_handle;
+ uint16_t firmware_rev_char_handle;
+ uint16_t software_rev_char_handle;
+ uint16_t rpc_version_char_handle;
+ FuriString* version_string;
+ char hardware_revision[4];
+} DevInfoSvc;
+
+static DevInfoSvc* dev_info_svc = NULL;
+
+static const char dev_info_man_name[] = "Flipper Devices Inc.";
+static const char dev_info_serial_num[] = "1.0";
+static const char dev_info_rpc_version[] = TOSTRING(PROTOBUF_MAJOR_VERSION.PROTOBUF_MINOR_VERSION);
+
+static const uint8_t dev_info_rpc_version_uuid[] =
+ {0x33, 0xa9, 0xb5, 0x3e, 0x87, 0x5d, 0x1a, 0x8e, 0xc8, 0x47, 0x5e, 0xae, 0x6d, 0x66, 0xf6, 0x03};
+
+void dev_info_svc_start() {
+ dev_info_svc = malloc(sizeof(DevInfoSvc));
+ dev_info_svc->version_string = furi_string_alloc_printf(
+ "%s %s %s %s",
+ version_get_githash(NULL),
+ version_get_version(NULL),
+ version_get_gitbranchnum(NULL),
+ version_get_builddate(NULL));
+ snprintf(
+ dev_info_svc->hardware_revision,
+ sizeof(dev_info_svc->hardware_revision),
+ "%d",
+ version_get_target(NULL));
+ tBleStatus status;
+
+ // Add Device Information Service
+ uint16_t uuid = DEVICE_INFORMATION_SERVICE_UUID;
+ status = aci_gatt_add_service(
+ UUID_TYPE_16, (Service_UUID_t*)&uuid, PRIMARY_SERVICE, 11, &dev_info_svc->service_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add Device Information Service: %d", status);
+ }
+
+ // Add characteristics
+ uuid = MANUFACTURER_NAME_UUID;
+ status = aci_gatt_add_char(
+ dev_info_svc->service_handle,
+ UUID_TYPE_16,
+ (Char_UUID_t*)&uuid,
+ strlen(dev_info_man_name),
+ CHAR_PROP_READ,
+ ATTR_PERMISSION_AUTHEN_READ,
+ GATT_DONT_NOTIFY_EVENTS,
+ 10,
+ CHAR_VALUE_LEN_CONSTANT,
+ &dev_info_svc->man_name_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add manufacturer name char: %d", status);
+ }
+ uuid = SERIAL_NUMBER_UUID;
+ status = aci_gatt_add_char(
+ dev_info_svc->service_handle,
+ UUID_TYPE_16,
+ (Char_UUID_t*)&uuid,
+ strlen(dev_info_serial_num),
+ CHAR_PROP_READ,
+ ATTR_PERMISSION_AUTHEN_READ,
+ GATT_DONT_NOTIFY_EVENTS,
+ 10,
+ CHAR_VALUE_LEN_CONSTANT,
+ &dev_info_svc->serial_num_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add serial number char: %d", status);
+ }
+ uuid = FIRMWARE_REVISION_UUID;
+ status = aci_gatt_add_char(
+ dev_info_svc->service_handle,
+ UUID_TYPE_16,
+ (Char_UUID_t*)&uuid,
+ strlen(dev_info_svc->hardware_revision),
+ CHAR_PROP_READ,
+ ATTR_PERMISSION_AUTHEN_READ,
+ GATT_DONT_NOTIFY_EVENTS,
+ 10,
+ CHAR_VALUE_LEN_CONSTANT,
+ &dev_info_svc->firmware_rev_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add firmware revision char: %d", status);
+ }
+ uuid = SOFTWARE_REVISION_UUID;
+ status = aci_gatt_add_char(
+ dev_info_svc->service_handle,
+ UUID_TYPE_16,
+ (Char_UUID_t*)&uuid,
+ furi_string_size(dev_info_svc->version_string),
+ CHAR_PROP_READ,
+ ATTR_PERMISSION_AUTHEN_READ,
+ GATT_DONT_NOTIFY_EVENTS,
+ 10,
+ CHAR_VALUE_LEN_CONSTANT,
+ &dev_info_svc->software_rev_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add software revision char: %d", status);
+ }
+ status = aci_gatt_add_char(
+ dev_info_svc->service_handle,
+ UUID_TYPE_128,
+ (const Char_UUID_t*)dev_info_rpc_version_uuid,
+ strlen(dev_info_rpc_version),
+ CHAR_PROP_READ,
+ ATTR_PERMISSION_AUTHEN_READ,
+ GATT_DONT_NOTIFY_EVENTS,
+ 10,
+ CHAR_VALUE_LEN_CONSTANT,
+ &dev_info_svc->rpc_version_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add rpc version characteristic: %d", status);
+ }
+
+ // Update characteristics
+ status = aci_gatt_update_char_value(
+ dev_info_svc->service_handle,
+ dev_info_svc->man_name_char_handle,
+ 0,
+ strlen(dev_info_man_name),
+ (uint8_t*)dev_info_man_name);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to update manufacturer name char: %d", status);
+ }
+ status = aci_gatt_update_char_value(
+ dev_info_svc->service_handle,
+ dev_info_svc->serial_num_char_handle,
+ 0,
+ strlen(dev_info_serial_num),
+ (uint8_t*)dev_info_serial_num);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to update serial number char: %d", status);
+ }
+ status = aci_gatt_update_char_value(
+ dev_info_svc->service_handle,
+ dev_info_svc->firmware_rev_char_handle,
+ 0,
+ strlen(dev_info_svc->hardware_revision),
+ (uint8_t*)dev_info_svc->hardware_revision);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to update firmware revision char: %d", status);
+ }
+ status = aci_gatt_update_char_value(
+ dev_info_svc->service_handle,
+ dev_info_svc->software_rev_char_handle,
+ 0,
+ furi_string_size(dev_info_svc->version_string),
+ (uint8_t*)furi_string_get_cstr(dev_info_svc->version_string));
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to update software revision char: %d", status);
+ }
+ status = aci_gatt_update_char_value(
+ dev_info_svc->service_handle,
+ dev_info_svc->rpc_version_char_handle,
+ 0,
+ strlen(dev_info_rpc_version),
+ (uint8_t*)dev_info_rpc_version);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to update rpc version char: %d", status);
+ }
+}
+
+void dev_info_svc_stop() {
+ tBleStatus status;
+ if(dev_info_svc) {
+ furi_string_free(dev_info_svc->version_string);
+ // Delete service characteristics
+ status =
+ aci_gatt_del_char(dev_info_svc->service_handle, dev_info_svc->man_name_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete manufacturer name char: %d", status);
+ }
+ status =
+ aci_gatt_del_char(dev_info_svc->service_handle, dev_info_svc->serial_num_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete serial number char: %d", status);
+ }
+ status = aci_gatt_del_char(
+ dev_info_svc->service_handle, dev_info_svc->firmware_rev_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete firmware revision char: %d", status);
+ }
+ status = aci_gatt_del_char(
+ dev_info_svc->service_handle, dev_info_svc->software_rev_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete software revision char: %d", status);
+ }
+ status =
+ aci_gatt_del_char(dev_info_svc->service_handle, dev_info_svc->rpc_version_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete rpc version char: %d", status);
+ }
+ // Delete service
+ status = aci_gatt_del_service(dev_info_svc->service_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete device info service: %d", status);
+ }
+ free(dev_info_svc);
+ dev_info_svc = NULL;
+ }
+}
+
+bool dev_info_svc_is_started() {
+ return dev_info_svc != NULL;
+}
diff --git a/firmware/targets/f7/ble_glue/services/dev_info_service.h b/firmware/targets/f7/ble_glue/dev_info_service.h
similarity index 100%
rename from firmware/targets/f7/ble_glue/services/dev_info_service.h
rename to firmware/targets/f7/ble_glue/dev_info_service.h
diff --git a/firmware/targets/f7/ble_glue/hid_service.c b/firmware/targets/f7/ble_glue/hid_service.c
new file mode 100644
index 0000000000..a31d6015f5
--- /dev/null
+++ b/firmware/targets/f7/ble_glue/hid_service.c
@@ -0,0 +1,416 @@
+#include "hid_service.h"
+#include "app_common.h"
+#include <ble/ble.h>
+
+#include <furi.h>
+
+#define TAG "BtHid"
+
+typedef struct {
+ uint16_t svc_handle;
+ uint16_t protocol_mode_char_handle;
+ uint16_t report_char_handle[HID_SVC_REPORT_COUNT];
+ uint16_t report_ref_desc_handle[HID_SVC_REPORT_COUNT];
+ uint16_t report_map_char_handle;
+ uint16_t info_char_handle;
+ uint16_t ctrl_point_char_handle;
+ // led state
+ uint16_t led_state_char_handle;
+ uint16_t led_state_desc_handle;
+ HidLedStateEventCallback led_state_event_callback;
+ void* led_state_ctx;
+} HIDSvc;
+
+static HIDSvc* hid_svc = NULL;
+
+static SVCCTL_EvtAckStatus_t hid_svc_event_handler(void* event) {
+ SVCCTL_EvtAckStatus_t ret = SVCCTL_EvtNotAck;
+ hci_event_pckt* event_pckt = (hci_event_pckt*)(((hci_uart_pckt*)event)->data);
+ evt_blecore_aci* blecore_evt = (evt_blecore_aci*)event_pckt->data;
+ // aci_gatt_attribute_modified_event_rp0* attribute_modified;
+ if(event_pckt->evt == HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE) {
+ if(blecore_evt->ecode == ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE) {
+ // Process modification events
+ ret = SVCCTL_EvtAckFlowEnable;
+ } else if(blecore_evt->ecode == ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE) {
+ // Process notification confirmation
+ ret = SVCCTL_EvtAckFlowEnable;
+ } else if(blecore_evt->ecode == ACI_GATT_WRITE_PERMIT_REQ_VSEVT_CODE) {
+ // Process write request
+ aci_gatt_write_permit_req_event_rp0* req =
+ (aci_gatt_write_permit_req_event_rp0*)blecore_evt->data;
+
+ furi_check(hid_svc->led_state_event_callback && hid_svc->led_state_ctx);
+
+ // this check is likely to be incorrect, it will actually work in our case
+ // but we need to investigate gatt api to see what is the rules
+ // that specify attibute handle value from char handle (or the reverse)
+ if(req->Attribute_Handle == (hid_svc->led_state_char_handle + 1)) {
+ hid_svc->led_state_event_callback(req->Data[0], hid_svc->led_state_ctx);
+ aci_gatt_write_resp(
+ req->Connection_Handle,
+ req->Attribute_Handle,
+ 0x00, /* write_status = 0 (no error))*/
+ 0x00, /* err_code */
+ req->Data_Length,
+ req->Data);
+ aci_gatt_write_char_value(
+ req->Connection_Handle,
+ hid_svc->led_state_char_handle,
+ req->Data_Length,
+ req->Data);
+ ret = SVCCTL_EvtAckFlowEnable;
+ }
+ }
+ }
+ return ret;
+}
+
+void hid_svc_start() {
+ tBleStatus status;
+ hid_svc = malloc(sizeof(HIDSvc));
+ Service_UUID_t svc_uuid = {};
+ Char_Desc_Uuid_t desc_uuid = {};
+ Char_UUID_t char_uuid = {};
+
+ // Register event handler
+ SVCCTL_RegisterSvcHandler(hid_svc_event_handler);
+ // Add service
+ svc_uuid.Service_UUID_16 = HUMAN_INTERFACE_DEVICE_SERVICE_UUID;
+ /**
+ * Add Human Interface Device Service
+ */
+ status = aci_gatt_add_service(
+ UUID_TYPE_16,
+ &svc_uuid,
+ PRIMARY_SERVICE,
+ 2 + /* protocol mode */
+ (4 * HID_SVC_INPUT_REPORT_COUNT) + (3 * HID_SVC_OUTPUT_REPORT_COUNT) +
+ (3 * HID_SVC_FEATURE_REPORT_COUNT) + 1 + 2 + 2 + 2 +
+ 4, /* Service + Report Map + HID Information + HID Control Point + LED state */
+ &hid_svc->svc_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add HID service: %d", status);
+ }
+ // Add Protocol mode characteristics
+ char_uuid.Char_UUID_16 = PROTOCOL_MODE_CHAR_UUID;
+ status = aci_gatt_add_char(
+ hid_svc->svc_handle,
+ UUID_TYPE_16,
+ &char_uuid,
+ 1,
+ CHAR_PROP_READ | CHAR_PROP_WRITE_WITHOUT_RESP,
+ ATTR_PERMISSION_NONE,
+ GATT_NOTIFY_ATTRIBUTE_WRITE,
+ 10,
+ CHAR_VALUE_LEN_CONSTANT,
+ &hid_svc->protocol_mode_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add protocol mode characteristic: %d", status);
+ }
+ // Update Protocol mode characteristic
+ uint8_t protocol_mode = 1;
+ status = aci_gatt_update_char_value(
+ hid_svc->svc_handle, hid_svc->protocol_mode_char_handle, 0, 1, &protocol_mode);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to update protocol mode characteristic: %d", status);
+ }
+
+#if(HID_SVC_REPORT_COUNT != 0)
+ for(uint8_t i = 0; i < HID_SVC_REPORT_COUNT; i++) {
+ if(i < HID_SVC_INPUT_REPORT_COUNT) { //-V547
+ uint8_t buf[2] = {i + 1, 1}; // 1 input
+ char_uuid.Char_UUID_16 = REPORT_CHAR_UUID;
+ status = aci_gatt_add_char(
+ hid_svc->svc_handle,
+ UUID_TYPE_16,
+ &char_uuid,
+ HID_SVC_REPORT_MAX_LEN,
+ CHAR_PROP_READ | CHAR_PROP_NOTIFY,
+ ATTR_PERMISSION_NONE,
+ GATT_DONT_NOTIFY_EVENTS,
+ 10,
+ CHAR_VALUE_LEN_VARIABLE,
+ &(hid_svc->report_char_handle[i]));
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add report characteristic: %d", status);
+ }
+
+ desc_uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID;
+ status = aci_gatt_add_char_desc(
+ hid_svc->svc_handle,
+ hid_svc->report_char_handle[i],
+ UUID_TYPE_16,
+ &desc_uuid,
+ HID_SVC_REPORT_REF_LEN,
+ HID_SVC_REPORT_REF_LEN,
+ buf,
+ ATTR_PERMISSION_NONE,
+ ATTR_ACCESS_READ_WRITE,
+ GATT_DONT_NOTIFY_EVENTS,
+ MIN_ENCRY_KEY_SIZE,
+ CHAR_VALUE_LEN_CONSTANT,
+ &(hid_svc->report_ref_desc_handle[i]));
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add report reference descriptor: %d", status);
+ }
+ } else if((i - HID_SVC_INPUT_REPORT_COUNT) < HID_SVC_OUTPUT_REPORT_COUNT) {
+ uint8_t buf[2] = {i + 1, 2}; // 2 output
+ char_uuid.Char_UUID_16 = REPORT_CHAR_UUID;
+ status = aci_gatt_add_char(
+ hid_svc->svc_handle,
+ UUID_TYPE_16,
+ &char_uuid,
+ HID_SVC_REPORT_MAX_LEN,
+ CHAR_PROP_READ | CHAR_PROP_NOTIFY,
+ ATTR_PERMISSION_NONE,
+ GATT_DONT_NOTIFY_EVENTS,
+ 10,
+ CHAR_VALUE_LEN_VARIABLE,
+ &(hid_svc->report_char_handle[i]));
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add report characteristic: %d", status);
+ }
+
+ desc_uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID;
+ status = aci_gatt_add_char_desc(
+ hid_svc->svc_handle,
+ hid_svc->report_char_handle[i],
+ UUID_TYPE_16,
+ &desc_uuid,
+ HID_SVC_REPORT_REF_LEN,
+ HID_SVC_REPORT_REF_LEN,
+ buf,
+ ATTR_PERMISSION_NONE,
+ ATTR_ACCESS_READ_WRITE,
+ GATT_DONT_NOTIFY_EVENTS,
+ MIN_ENCRY_KEY_SIZE,
+ CHAR_VALUE_LEN_CONSTANT,
+ &(hid_svc->report_ref_desc_handle[i]));
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add report reference descriptor: %d", status);
+ }
+ } else {
+ uint8_t buf[2] = {i + 1, 3}; // 3 feature
+ char_uuid.Char_UUID_16 = REPORT_CHAR_UUID;
+ status = aci_gatt_add_char(
+ hid_svc->svc_handle,
+ UUID_TYPE_16,
+ &char_uuid,
+ HID_SVC_REPORT_MAX_LEN,
+ CHAR_PROP_READ | CHAR_PROP_NOTIFY,
+ ATTR_PERMISSION_NONE,
+ GATT_DONT_NOTIFY_EVENTS,
+ 10,
+ CHAR_VALUE_LEN_VARIABLE,
+ &(hid_svc->report_char_handle[i]));
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add report characteristic: %d", status);
+ }
+
+ desc_uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID;
+ status = aci_gatt_add_char_desc(
+ hid_svc->svc_handle,
+ hid_svc->report_char_handle[i],
+ UUID_TYPE_16,
+ &desc_uuid,
+ HID_SVC_REPORT_REF_LEN,
+ HID_SVC_REPORT_REF_LEN,
+ buf,
+ ATTR_PERMISSION_NONE,
+ ATTR_ACCESS_READ_WRITE,
+ GATT_DONT_NOTIFY_EVENTS,
+ MIN_ENCRY_KEY_SIZE,
+ CHAR_VALUE_LEN_CONSTANT,
+ &(hid_svc->report_ref_desc_handle[i]));
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add report reference descriptor: %d", status);
+ }
+ }
+ }
+#endif
+ // Add led state output report
+ char_uuid.Char_UUID_16 = REPORT_CHAR_UUID;
+ status = aci_gatt_add_char(
+ hid_svc->svc_handle,
+ UUID_TYPE_16,
+ &char_uuid,
+ 1,
+ CHAR_PROP_READ | CHAR_PROP_WRITE_WITHOUT_RESP | CHAR_PROP_WRITE,
+ ATTR_PERMISSION_NONE,
+ GATT_NOTIFY_ATTRIBUTE_WRITE | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP,
+ 10,
+ CHAR_VALUE_LEN_CONSTANT,
+ &(hid_svc->led_state_char_handle));
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add led state characteristic: %d", status);
+ }
+
+ // Add led state char descriptor specifying it is an output report
+ uint8_t buf[2] = {HID_SVC_REPORT_COUNT + 1, 2};
+ desc_uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID;
+ status = aci_gatt_add_char_desc(
+ hid_svc->svc_handle,
+ hid_svc->led_state_char_handle,
+ UUID_TYPE_16,
+ &desc_uuid,
+ HID_SVC_REPORT_REF_LEN,
+ HID_SVC_REPORT_REF_LEN,
+ buf,
+ ATTR_PERMISSION_NONE,
+ ATTR_ACCESS_READ_WRITE,
+ GATT_DONT_NOTIFY_EVENTS,
+ MIN_ENCRY_KEY_SIZE,
+ CHAR_VALUE_LEN_CONSTANT,
+ &(hid_svc->led_state_desc_handle));
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add led state descriptor: %d", status);
+ }
+ // Add Report Map characteristic
+ char_uuid.Char_UUID_16 = REPORT_MAP_CHAR_UUID;
+ status = aci_gatt_add_char(
+ hid_svc->svc_handle,
+ UUID_TYPE_16,
+ &char_uuid,
+ HID_SVC_REPORT_MAP_MAX_LEN,
+ CHAR_PROP_READ,
+ ATTR_PERMISSION_NONE,
+ GATT_DONT_NOTIFY_EVENTS,
+ 10,
+ CHAR_VALUE_LEN_VARIABLE,
+ &hid_svc->report_map_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add report map characteristic: %d", status);
+ }
+
+ // Add Information characteristic
+ char_uuid.Char_UUID_16 = HID_INFORMATION_CHAR_UUID;
+ status = aci_gatt_add_char(
+ hid_svc->svc_handle,
+ UUID_TYPE_16,
+ &char_uuid,
+ HID_SVC_INFO_LEN,
+ CHAR_PROP_READ,
+ ATTR_PERMISSION_NONE,
+ GATT_DONT_NOTIFY_EVENTS,
+ 10,
+ CHAR_VALUE_LEN_CONSTANT,
+ &hid_svc->info_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add information characteristic: %d", status);
+ }
+ // Add Control Point characteristic
+ char_uuid.Char_UUID_16 = HID_CONTROL_POINT_CHAR_UUID;
+ status = aci_gatt_add_char(
+ hid_svc->svc_handle,
+ UUID_TYPE_16,
+ &char_uuid,
+ HID_SVC_CONTROL_POINT_LEN,
+ CHAR_PROP_WRITE_WITHOUT_RESP,
+ ATTR_PERMISSION_NONE,
+ GATT_NOTIFY_ATTRIBUTE_WRITE,
+ 10,
+ CHAR_VALUE_LEN_CONSTANT,
+ &hid_svc->ctrl_point_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add control point characteristic: %d", status);
+ }
+
+ hid_svc->led_state_event_callback = NULL;
+ hid_svc->led_state_ctx = NULL;
+}
+
+bool hid_svc_update_report_map(const uint8_t* data, uint16_t len) {
+ furi_assert(data);
+ furi_assert(hid_svc);
+
+ tBleStatus status = aci_gatt_update_char_value(
+ hid_svc->svc_handle, hid_svc->report_map_char_handle, 0, len, data);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed updating report map characteristic: %d", status);
+ return false;
+ }
+ return true;
+}
+
+bool hid_svc_update_input_report(uint8_t input_report_num, uint8_t* data, uint16_t len) {
+ furi_assert(data);
+ furi_assert(hid_svc);
+
+ tBleStatus status = aci_gatt_update_char_value(
+ hid_svc->svc_handle, hid_svc->report_char_handle[input_report_num], 0, len, data);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed updating report characteristic: %d", status);
+ return false;
+ }
+ return true;
+}
+
+bool hid_svc_update_info(uint8_t* data, uint16_t len) {
+ furi_assert(data);
+ furi_assert(hid_svc);
+
+ tBleStatus status =
+ aci_gatt_update_char_value(hid_svc->svc_handle, hid_svc->info_char_handle, 0, len, data);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed updating info characteristic: %d", status);
+ return false;
+ }
+ return true;
+}
+
+void hid_svc_register_led_state_callback(HidLedStateEventCallback callback, void* context) {
+ furi_assert(hid_svc);
+ furi_assert(callback);
+ furi_assert(context);
+
+ hid_svc->led_state_event_callback = callback;
+ hid_svc->led_state_ctx = context;
+}
+
+bool hid_svc_is_started() {
+ return hid_svc != NULL;
+}
+
+void hid_svc_stop() {
+ tBleStatus status;
+ if(hid_svc) {
+ // Delete characteristics
+ status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->report_map_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete Report Map characteristic: %d", status);
+ }
+#if(HID_SVC_INPUT_REPORT_COUNT != 0)
+ for(uint8_t i = 0; i < HID_SVC_REPORT_COUNT; i++) {
+ status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->report_char_handle[i]);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete Report characteristic: %d", status);
+ }
+ }
+#endif
+ status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->protocol_mode_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete Protocol Mode characteristic: %d", status);
+ }
+ status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->info_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete Information characteristic: %d", status);
+ }
+ status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->ctrl_point_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete Control Point characteristic: %d", status);
+ }
+ status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->led_state_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete led state characteristic: %d", status);
+ }
+ // Delete service
+ status = aci_gatt_del_service(hid_svc->svc_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete HID service: %d", status);
+ }
+ // Delete buffer size mutex
+ free(hid_svc);
+ hid_svc = NULL;
+ }
+}
diff --git a/firmware/targets/f7/ble_glue/services/hid_service.h b/firmware/targets/f7/ble_glue/hid_service.h
similarity index 89%
rename from firmware/targets/f7/ble_glue/services/hid_service.h
rename to firmware/targets/f7/ble_glue/hid_service.h
index 4d0ed4c4f9..b8f6b244d2 100644
--- a/firmware/targets/f7/ble_glue/services/hid_service.h
+++ b/firmware/targets/f7/ble_glue/hid_service.h
@@ -27,7 +27,6 @@ bool hid_svc_update_report_map(const uint8_t* data, uint16_t len);
bool hid_svc_update_input_report(uint8_t input_report_num, uint8_t* data, uint16_t len);
-// Expects data to be of length HID_SVC_INFO_LEN (4 bytes)
-bool hid_svc_update_info(uint8_t* data);
+bool hid_svc_update_info(uint8_t* data, uint16_t len);
void hid_svc_register_led_state_callback(HidLedStateEventCallback callback, void* context);
diff --git a/firmware/targets/f7/ble_glue/services/serial_service.c b/firmware/targets/f7/ble_glue/serial_service.c
similarity index 57%
rename from firmware/targets/f7/ble_glue/services/serial_service.c
rename to firmware/targets/f7/ble_glue/serial_service.c
index ab009bbfcb..c6421dc28f 100644
--- a/firmware/targets/f7/ble_glue/services/serial_service.c
+++ b/firmware/targets/f7/ble_glue/serial_service.c
@@ -1,67 +1,17 @@
#include "serial_service.h"
#include "app_common.h"
#include <ble/ble.h>
-#include "gatt_char.h"
#include <furi.h>
-#include "serial_service_uuid.inc"
-
#define TAG "BtSerialSvc"
-typedef enum {
- SerialSvcGattCharacteristicTx = 0,
- SerialSvcGattCharacteristicRx,
- SerialSvcGattCharacteristicFlowCtrl,
- SerialSvcGattCharacteristicStatus,
- SerialSvcGattCharacteristicCount,
-} SerialSvcGattCharacteristicId;
-
-static const FlipperGattCharacteristicParams serial_svc_chars[SerialSvcGattCharacteristicCount] = {
- [SerialSvcGattCharacteristicTx] =
- {.name = "TX",
- .data_prop_type = FlipperGattCharacteristicDataFixed,
- .data.fixed.length = SERIAL_SVC_DATA_LEN_MAX,
- .uuid.Char_UUID_128 = SERIAL_SVC_TX_CHAR_UUID,
- .uuid_type = UUID_TYPE_128,
- .char_properties = CHAR_PROP_READ | CHAR_PROP_INDICATE,
- .security_permissions = ATTR_PERMISSION_AUTHEN_READ,
- .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS,
- .is_variable = CHAR_VALUE_LEN_VARIABLE},
- [SerialSvcGattCharacteristicRx] =
- {.name = "RX",
- .data_prop_type = FlipperGattCharacteristicDataFixed,
- .data.fixed.length = SERIAL_SVC_DATA_LEN_MAX,
- .uuid.Char_UUID_128 = SERIAL_SVC_RX_CHAR_UUID,
- .uuid_type = UUID_TYPE_128,
- .char_properties = CHAR_PROP_WRITE_WITHOUT_RESP | CHAR_PROP_WRITE | CHAR_PROP_READ,
- .security_permissions = ATTR_PERMISSION_AUTHEN_READ | ATTR_PERMISSION_AUTHEN_WRITE,
- .gatt_evt_mask = GATT_NOTIFY_ATTRIBUTE_WRITE,
- .is_variable = CHAR_VALUE_LEN_VARIABLE},
- [SerialSvcGattCharacteristicFlowCtrl] =
- {.name = "Flow control",
- .data_prop_type = FlipperGattCharacteristicDataFixed,
- .data.fixed.length = sizeof(uint32_t),
- .uuid.Char_UUID_128 = SERIAL_SVC_FLOW_CONTROL_UUID,
- .uuid_type = UUID_TYPE_128,
- .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},
- [SerialSvcGattCharacteristicStatus] = {
- .name = "RPC status",
- .data_prop_type = FlipperGattCharacteristicDataFixed,
- .data.fixed.length = sizeof(SerialServiceRpcStatus),
- .uuid.Char_UUID_128 = SERIAL_SVC_RPC_STATUS_UUID,
- .uuid_type = UUID_TYPE_128,
- .char_properties = CHAR_PROP_READ | CHAR_PROP_WRITE | CHAR_PROP_NOTIFY,
- .security_permissions = ATTR_PERMISSION_AUTHEN_READ | ATTR_PERMISSION_AUTHEN_WRITE,
- .gatt_evt_mask = GATT_NOTIFY_ATTRIBUTE_WRITE,
- .is_variable = CHAR_VALUE_LEN_CONSTANT}};
-
typedef struct {
uint16_t svc_handle;
- FlipperGattCharacteristicInstance chars[SerialSvcGattCharacteristicCount];
+ uint16_t rx_char_handle;
+ uint16_t tx_char_handle;
+ uint16_t flow_ctrl_char_handle;
+ uint16_t rpc_status_char_handle;
FuriMutex* buff_size_mtx;
uint32_t buff_size;
uint16_t bytes_ready_to_receive;
@@ -71,6 +21,17 @@ typedef struct {
static SerialSvc* serial_svc = NULL;
+static const uint8_t service_uuid[] =
+ {0x00, 0x00, 0xfe, 0x60, 0xcc, 0x7a, 0x48, 0x2a, 0x98, 0x4a, 0x7f, 0x2e, 0xd5, 0xb3, 0xe5, 0x8f};
+static const uint8_t char_tx_uuid[] =
+ {0x00, 0x00, 0xfe, 0x61, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19};
+static const uint8_t char_rx_uuid[] =
+ {0x00, 0x00, 0xfe, 0x62, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19};
+static const uint8_t flow_ctrl_uuid[] =
+ {0x00, 0x00, 0xfe, 0x63, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19};
+static const uint8_t rpc_status_uuid[] =
+ {0x00, 0x00, 0xfe, 0x64, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19};
+
static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void* event) {
SVCCTL_EvtAckStatus_t ret = SVCCTL_EvtNotAck;
hci_event_pckt* event_pckt = (hci_event_pckt*)(((hci_uart_pckt*)event)->data);
@@ -79,14 +40,11 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void* event) {
if(event_pckt->evt == HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE) {
if(blecore_evt->ecode == ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE) {
attribute_modified = (aci_gatt_attribute_modified_event_rp0*)blecore_evt->data;
- if(attribute_modified->Attr_Handle ==
- serial_svc->chars[SerialSvcGattCharacteristicRx].handle + 2) {
+ if(attribute_modified->Attr_Handle == serial_svc->rx_char_handle + 2) {
// Descriptor handle
ret = SVCCTL_EvtAckFlowEnable;
FURI_LOG_D(TAG, "RX descriptor event");
- } else if(
- attribute_modified->Attr_Handle ==
- serial_svc->chars[SerialSvcGattCharacteristicRx].handle + 1) {
+ } else if(attribute_modified->Attr_Handle == serial_svc->rx_char_handle + 1) {
FURI_LOG_D(TAG, "Received %d bytes", attribute_modified->Attr_Data_Length);
if(serial_svc->callback) {
furi_check(
@@ -112,9 +70,7 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void* event) {
furi_check(furi_mutex_release(serial_svc->buff_size_mtx) == FuriStatusOk);
}
ret = SVCCTL_EvtAckFlowEnable;
- } else if(
- attribute_modified->Attr_Handle ==
- serial_svc->chars[SerialSvcGattCharacteristicStatus].handle + 1) {
+ } else if(attribute_modified->Attr_Handle == serial_svc->rpc_status_char_handle + 1) {
SerialServiceRpcStatus* rpc_status =
(SerialServiceRpcStatus*)attribute_modified->Attr_Data;
if(*rpc_status == SerialServiceRpcStatusNotActive) {
@@ -141,12 +97,18 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void* event) {
}
static void serial_svc_update_rpc_char(SerialServiceRpcStatus status) {
- flipper_gatt_characteristic_update(
- serial_svc->svc_handle, &serial_svc->chars[SerialSvcGattCharacteristicStatus], &status);
+ tBleStatus ble_status = aci_gatt_update_char_value(
+ serial_svc->svc_handle,
+ serial_svc->rpc_status_char_handle,
+ 0,
+ sizeof(SerialServiceRpcStatus),
+ (uint8_t*)&status);
+ if(ble_status) {
+ FURI_LOG_E(TAG, "Failed to update RPC status char: %d", ble_status);
+ }
}
void serial_svc_start() {
- UNUSED(serial_svc_chars);
tBleStatus status;
serial_svc = malloc(sizeof(SerialSvc));
// Register event handler
@@ -154,17 +116,72 @@ void serial_svc_start() {
// Add service
status = aci_gatt_add_service(
- UUID_TYPE_128, &service_uuid, PRIMARY_SERVICE, 12, &serial_svc->svc_handle);
+ UUID_TYPE_128, (Service_UUID_t*)service_uuid, PRIMARY_SERVICE, 12, &serial_svc->svc_handle);
if(status) {
FURI_LOG_E(TAG, "Failed to add Serial service: %d", status);
}
- // Add characteristics
- for(uint8_t i = 0; i < SerialSvcGattCharacteristicCount; i++) {
- flipper_gatt_characteristic_init(
- serial_svc->svc_handle, &serial_svc_chars[i], &serial_svc->chars[i]);
+ // Add RX characteristics
+ status = aci_gatt_add_char(
+ serial_svc->svc_handle,
+ UUID_TYPE_128,
+ (const Char_UUID_t*)char_rx_uuid,
+ SERIAL_SVC_DATA_LEN_MAX,
+ CHAR_PROP_WRITE_WITHOUT_RESP | CHAR_PROP_WRITE | CHAR_PROP_READ,
+ ATTR_PERMISSION_AUTHEN_READ | ATTR_PERMISSION_AUTHEN_WRITE,
+ GATT_NOTIFY_ATTRIBUTE_WRITE,
+ 10,
+ CHAR_VALUE_LEN_VARIABLE,
+ &serial_svc->rx_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add RX characteristic: %d", status);
}
+ // Add TX characteristic
+ status = aci_gatt_add_char(
+ serial_svc->svc_handle,
+ UUID_TYPE_128,
+ (const Char_UUID_t*)char_tx_uuid,
+ SERIAL_SVC_DATA_LEN_MAX,
+ CHAR_PROP_READ | CHAR_PROP_INDICATE,
+ ATTR_PERMISSION_AUTHEN_READ,
+ GATT_DONT_NOTIFY_EVENTS,
+ 10,
+ CHAR_VALUE_LEN_VARIABLE,
+ &serial_svc->tx_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add TX characteristic: %d", status);
+ }
+ // Add Flow Control characteristic
+ status = aci_gatt_add_char(
+ serial_svc->svc_handle,
+ UUID_TYPE_128,
+ (const Char_UUID_t*)flow_ctrl_uuid,
+ sizeof(uint32_t),
+ CHAR_PROP_READ | CHAR_PROP_NOTIFY,
+ ATTR_PERMISSION_AUTHEN_READ,
+ GATT_DONT_NOTIFY_EVENTS,
+ 10,
+ CHAR_VALUE_LEN_CONSTANT,
+ &serial_svc->flow_ctrl_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add Flow Control characteristic: %d", status);
+ }
+ // Add RPC status characteristic
+ status = aci_gatt_add_char(
+ serial_svc->svc_handle,
+ UUID_TYPE_128,
+ (const Char_UUID_t*)rpc_status_uuid,
+ sizeof(SerialServiceRpcStatus),
+ CHAR_PROP_READ | CHAR_PROP_WRITE | CHAR_PROP_NOTIFY,
+ ATTR_PERMISSION_AUTHEN_READ | ATTR_PERMISSION_AUTHEN_WRITE,
+ GATT_NOTIFY_ATTRIBUTE_WRITE,
+ 10,
+ CHAR_VALUE_LEN_CONSTANT,
+ &serial_svc->rpc_status_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to add RPC status characteristic: %d", status);
+ }
serial_svc_update_rpc_char(SerialServiceRpcStatusNotActive);
// Allocate buffer size mutex
serial_svc->buff_size_mtx = furi_mutex_alloc(FuriMutexTypeNormal);
@@ -179,12 +196,13 @@ void serial_svc_set_callbacks(
serial_svc->context = context;
serial_svc->buff_size = buff_size;
serial_svc->bytes_ready_to_receive = buff_size;
-
uint32_t buff_size_reversed = REVERSE_BYTES_U32(serial_svc->buff_size);
- flipper_gatt_characteristic_update(
+ aci_gatt_update_char_value(
serial_svc->svc_handle,
- &serial_svc->chars[SerialSvcGattCharacteristicFlowCtrl],
- &buff_size_reversed);
+ serial_svc->flow_ctrl_char_handle,
+ 0,
+ sizeof(uint32_t),
+ (uint8_t*)&buff_size_reversed);
}
void serial_svc_notify_buffer_is_empty() {
@@ -195,12 +213,13 @@ void serial_svc_notify_buffer_is_empty() {
if(serial_svc->bytes_ready_to_receive == 0) {
FURI_LOG_D(TAG, "Buffer is empty. Notifying client");
serial_svc->bytes_ready_to_receive = serial_svc->buff_size;
-
uint32_t buff_size_reversed = REVERSE_BYTES_U32(serial_svc->buff_size);
- flipper_gatt_characteristic_update(
+ aci_gatt_update_char_value(
serial_svc->svc_handle,
- &serial_svc->chars[SerialSvcGattCharacteristicFlowCtrl],
- &buff_size_reversed);
+ serial_svc->flow_ctrl_char_handle,
+ 0,
+ sizeof(uint32_t),
+ (uint8_t*)&buff_size_reversed);
}
furi_check(furi_mutex_release(serial_svc->buff_size_mtx) == FuriStatusOk);
}
@@ -208,8 +227,22 @@ void serial_svc_notify_buffer_is_empty() {
void serial_svc_stop() {
tBleStatus status;
if(serial_svc) {
- for(uint8_t i = 0; i < SerialSvcGattCharacteristicCount; i++) {
- flipper_gatt_characteristic_delete(serial_svc->svc_handle, &serial_svc->chars[i]);
+ // Delete characteristics
+ status = aci_gatt_del_char(serial_svc->svc_handle, serial_svc->tx_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete TX characteristic: %d", status);
+ }
+ status = aci_gatt_del_char(serial_svc->svc_handle, serial_svc->rx_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete RX characteristic: %d", status);
+ }
+ status = aci_gatt_del_char(serial_svc->svc_handle, serial_svc->flow_ctrl_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete Flow Control characteristic: %d", status);
+ }
+ status = aci_gatt_del_char(serial_svc->svc_handle, serial_svc->rpc_status_char_handle);
+ if(status) {
+ FURI_LOG_E(TAG, "Failed to delete RPC Status characteristic: %d", status);
}
// Delete service
status = aci_gatt_del_service(serial_svc->svc_handle);
@@ -240,7 +273,7 @@ bool serial_svc_update_tx(uint8_t* data, uint16_t data_len) {
tBleStatus result = aci_gatt_update_char_value_ext(
0,
serial_svc->svc_handle,
- serial_svc->chars[SerialSvcGattCharacteristicTx].handle,
+ serial_svc->tx_char_handle,
remained ? 0x00 : 0x02,
data_len,
value_offset,
diff --git a/firmware/targets/f7/ble_glue/services/serial_service.h b/firmware/targets/f7/ble_glue/serial_service.h
similarity index 100%
rename from firmware/targets/f7/ble_glue/services/serial_service.h
rename to firmware/targets/f7/ble_glue/serial_service.h
diff --git a/firmware/targets/f7/ble_glue/services/dev_info_service.c b/firmware/targets/f7/ble_glue/services/dev_info_service.c
deleted file mode 100644
index 5bee97b416..0000000000
--- a/firmware/targets/f7/ble_glue/services/dev_info_service.c
+++ /dev/null
@@ -1,176 +0,0 @@
-#include "dev_info_service.h"
-#include "app_common.h"
-#include "gatt_char.h"
-#include <ble/ble.h>
-
-#include <furi.h>
-#include <protobuf_version.h>
-#include <lib/toolbox/version.h>
-
-#include "dev_info_service_uuid.inc"
-
-#define TAG "BtDevInfoSvc"
-
-typedef enum {
- DevInfoSvcGattCharacteristicMfgName = 0,
- DevInfoSvcGattCharacteristicSerial,
- DevInfoSvcGattCharacteristicFirmwareRev,
- DevInfoSvcGattCharacteristicSoftwareRev,
- DevInfoSvcGattCharacteristicRpcVersion,
- DevInfoSvcGattCharacteristicCount,
-} DevInfoSvcGattCharacteristicId;
-
-#define DEVICE_INFO_HARDWARE_REV_SIZE 4
-typedef struct {
- uint16_t service_handle;
- FlipperGattCharacteristicInstance characteristics[DevInfoSvcGattCharacteristicCount];
- FuriString* version_string;
- char hardware_revision[DEVICE_INFO_HARDWARE_REV_SIZE];
-} DevInfoSvc;
-
-static DevInfoSvc* dev_info_svc = NULL;
-
-static const char dev_info_man_name[] = "Flipper Devices Inc.";
-static const char dev_info_serial_num[] = "1.0";
-static const char dev_info_rpc_version[] = TOSTRING(PROTOBUF_MAJOR_VERSION.PROTOBUF_MINOR_VERSION);
-
-static bool dev_info_char_firmware_rev_callback(
- const void* context,
- const uint8_t** data,
- uint16_t* data_len) {
- const DevInfoSvc* dev_info_svc = *(DevInfoSvc**)context;
- *data_len = sizeof(dev_info_svc->hardware_revision);
- if(data) {
- *data = (const uint8_t*)&dev_info_svc->hardware_revision;
- }
- return false;
-}
-
-static bool dev_info_char_software_rev_callback(
- const void* context,
- const uint8_t** data,
- uint16_t* data_len) {
- const DevInfoSvc* dev_info_svc = *(DevInfoSvc**)context;
- *data_len = furi_string_size(dev_info_svc->version_string);
- if(data) {
- *data = (const uint8_t*)furi_string_get_cstr(dev_info_svc->version_string);
- }
- return false;
-}
-
-static const FlipperGattCharacteristicParams dev_info_svc_chars[DevInfoSvcGattCharacteristicCount] =
- {[DevInfoSvcGattCharacteristicMfgName] =
- {.name = "Manufacturer Name",
- .data_prop_type = FlipperGattCharacteristicDataFixed,
- .data.fixed.length = sizeof(dev_info_man_name) - 1,
- .data.fixed.ptr = (const uint8_t*)&dev_info_man_name,
- .uuid.Char_UUID_16 = MANUFACTURER_NAME_UUID,
- .uuid_type = UUID_TYPE_16,
- .char_properties = CHAR_PROP_READ,
- .security_permissions = ATTR_PERMISSION_AUTHEN_READ,
- .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS,
- .is_variable = CHAR_VALUE_LEN_CONSTANT},
- [DevInfoSvcGattCharacteristicSerial] =
- {.name = "Serial Number",
- .data_prop_type = FlipperGattCharacteristicDataFixed,
- .data.fixed.length = sizeof(dev_info_serial_num) - 1,
- .data.fixed.ptr = (const uint8_t*)&dev_info_serial_num,
- .uuid.Char_UUID_16 = SERIAL_NUMBER_UUID,
- .uuid_type = UUID_TYPE_16,
- .char_properties = CHAR_PROP_READ,
- .security_permissions = ATTR_PERMISSION_AUTHEN_READ,
- .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS,
- .is_variable = CHAR_VALUE_LEN_CONSTANT},
- [DevInfoSvcGattCharacteristicFirmwareRev] =
- {.name = "Firmware Revision",
- .data_prop_type = FlipperGattCharacteristicDataCallback,
- .data.callback.context = &dev_info_svc,
- .data.callback.fn = dev_info_char_firmware_rev_callback,
- .uuid.Char_UUID_16 = FIRMWARE_REVISION_UUID,
- .uuid_type = UUID_TYPE_16,
- .char_properties = CHAR_PROP_READ,
- .security_permissions = ATTR_PERMISSION_AUTHEN_READ,
- .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS,
- .is_variable = CHAR_VALUE_LEN_CONSTANT},
- [DevInfoSvcGattCharacteristicSoftwareRev] =
- {.name = "Software Revision",
- .data_prop_type = FlipperGattCharacteristicDataCallback,
- .data.callback.context = &dev_info_svc,
- .data.callback.fn = dev_info_char_software_rev_callback,
- .uuid.Char_UUID_16 = SOFTWARE_REVISION_UUID,
- .uuid_type = UUID_TYPE_16,
- .char_properties = CHAR_PROP_READ,
- .security_permissions = ATTR_PERMISSION_AUTHEN_READ,
- .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS,
- .is_variable = CHAR_VALUE_LEN_CONSTANT},
- [DevInfoSvcGattCharacteristicRpcVersion] = {
- .name = "RPC Version",
- .data_prop_type = FlipperGattCharacteristicDataFixed,
- .data.fixed.length = sizeof(dev_info_rpc_version) - 1,
- .data.fixed.ptr = (const uint8_t*)&dev_info_rpc_version,
- .uuid.Char_UUID_128 = DEV_INVO_RPC_VERSION_UID,
- .uuid_type = UUID_TYPE_128,
- .char_properties = CHAR_PROP_READ,
- .security_permissions = ATTR_PERMISSION_AUTHEN_READ,
- .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS,
- .is_variable = CHAR_VALUE_LEN_CONSTANT}};
-
-void dev_info_svc_start() {
- dev_info_svc = malloc(sizeof(DevInfoSvc));
- dev_info_svc->version_string = furi_string_alloc_printf(
- "%s %s %s %s",
- version_get_githash(NULL),
- version_get_version(NULL),
- version_get_gitbranchnum(NULL),
- version_get_builddate(NULL));
- snprintf(
- dev_info_svc->hardware_revision,
- sizeof(dev_info_svc->hardware_revision),
- "%d",
- version_get_target(NULL));
- tBleStatus status;
-
- // Add Device Information Service
- uint16_t uuid = DEVICE_INFORMATION_SERVICE_UUID;
- status = aci_gatt_add_service(
- UUID_TYPE_16,
- (Service_UUID_t*)&uuid,
- PRIMARY_SERVICE,
- 1 + 2 * DevInfoSvcGattCharacteristicCount,
- &dev_info_svc->service_handle);
- if(status) {
- FURI_LOG_E(TAG, "Failed to add Device Information Service: %d", status);
- }
-
- for(size_t i = 0; i < DevInfoSvcGattCharacteristicCount; i++) {
- flipper_gatt_characteristic_init(
- dev_info_svc->service_handle,
- &dev_info_svc_chars[i],
- &dev_info_svc->characteristics[i]);
- flipper_gatt_characteristic_update(
- dev_info_svc->service_handle, &dev_info_svc->characteristics[i], NULL);
- }
-}
-
-void dev_info_svc_stop() {
- tBleStatus status;
- if(dev_info_svc) {
- furi_string_free(dev_info_svc->version_string);
- // Delete service characteristics
- for(size_t i = 0; i < DevInfoSvcGattCharacteristicCount; i++) {
- flipper_gatt_characteristic_delete(
- dev_info_svc->service_handle, &dev_info_svc->characteristics[i]);
- }
- // Delete service
- status = aci_gatt_del_service(dev_info_svc->service_handle);
- if(status) {
- FURI_LOG_E(TAG, "Failed to delete device info service: %d", status);
- }
- free(dev_info_svc);
- dev_info_svc = NULL;
- }
-}
-
-bool dev_info_svc_is_started() {
- return dev_info_svc != NULL;
-}
diff --git a/firmware/targets/f7/ble_glue/services/dev_info_service_uuid.inc b/firmware/targets/f7/ble_glue/services/dev_info_service_uuid.inc
deleted file mode 100644
index ad520f62e5..0000000000
--- a/firmware/targets/f7/ble_glue/services/dev_info_service_uuid.inc
+++ /dev/null
@@ -1,3 +0,0 @@
-#define DEV_INVO_RPC_VERSION_UID \
- { 0x33, 0xa9, 0xb5, 0x3e, 0x87, 0x5d, 0x1a, 0x8e, 0xc8, 0x47, 0x5e, 0xae, 0x6d, 0x66, 0xf6, 0x03 }
-
diff --git a/firmware/targets/f7/ble_glue/services/gatt_char.c b/firmware/targets/f7/ble_glue/services/gatt_char.c
deleted file mode 100644
index 9b6a44f61b..0000000000
--- a/firmware/targets/f7/ble_glue/services/gatt_char.c
+++ /dev/null
@@ -1,123 +0,0 @@
-#include "gatt_char.h"
-
-#include <furi.h>
-
-#define TAG "GattChar"
-
-#define GATT_MIN_READ_KEY_SIZE (10)
-
-void flipper_gatt_characteristic_init(
- uint16_t svc_handle,
- const FlipperGattCharacteristicParams* char_descriptor,
- FlipperGattCharacteristicInstance* char_instance) {
- furi_assert(char_descriptor);
- furi_assert(char_instance);
-
- // Copy the descriptor to the instance, since it may point to stack memory
- // TODO: only copy if really comes from stack
- char_instance->characteristic = malloc(sizeof(FlipperGattCharacteristicParams));
- memcpy(
- (void*)char_instance->characteristic,
- char_descriptor,
- sizeof(FlipperGattCharacteristicParams));
-
- uint16_t char_data_size = 0;
- if(char_descriptor->data_prop_type == FlipperGattCharacteristicDataFixed) {
- char_data_size = char_descriptor->data.fixed.length;
- } else if(char_descriptor->data_prop_type == FlipperGattCharacteristicDataCallback) {
- char_descriptor->data.callback.fn(
- char_descriptor->data.callback.context, NULL, &char_data_size);
- }
-
- tBleStatus status = aci_gatt_add_char(
- svc_handle,
- char_descriptor->uuid_type,
- &char_descriptor->uuid,
- char_data_size,
- char_descriptor->char_properties,
- char_descriptor->security_permissions,
- char_descriptor->gatt_evt_mask,
- GATT_MIN_READ_KEY_SIZE,
- char_descriptor->is_variable,
- &char_instance->handle);
- if(status) {
- FURI_LOG_E(TAG, "Failed to add %s char: %d", char_descriptor->name, status);
- }
-
- char_instance->descriptor_handle = 0;
- if((status == 0) && char_descriptor->descriptor_params) {
- uint8_t const* char_data = NULL;
- const FlipperGattCharacteristicDescriptorParams* char_data_descriptor =
- char_descriptor->descriptor_params;
- bool release_data = char_data_descriptor->data_callback.fn(
- char_data_descriptor->data_callback.context, &char_data, &char_data_size);
-
- status = aci_gatt_add_char_desc(
- svc_handle,
- char_instance->handle,
- char_data_descriptor->uuid_type,
- &char_data_descriptor->uuid,
- char_data_descriptor->max_length,
- char_data_size,
- char_data,
- char_data_descriptor->security_permissions,
- char_data_descriptor->access_permissions,
- char_data_descriptor->gatt_evt_mask,
- GATT_MIN_READ_KEY_SIZE,
- char_data_descriptor->is_variable,
- &char_instance->descriptor_handle);
- if(status) {
- FURI_LOG_E(TAG, "Failed to add %s char descriptor: %d", char_descriptor->name, status);
- }
- if(release_data) {
- free((void*)char_data);
- }
- }
-}
-
-void flipper_gatt_characteristic_delete(
- uint16_t svc_handle,
- FlipperGattCharacteristicInstance* char_instance) {
- tBleStatus status = aci_gatt_del_char(svc_handle, char_instance->handle);
- if(status) {
- FURI_LOG_E(
- TAG, "Failed to delete %s char: %d", char_instance->characteristic->name, status);
- }
- free((void*)char_instance->characteristic);
-}
-
-bool flipper_gatt_characteristic_update(
- uint16_t svc_handle,
- FlipperGattCharacteristicInstance* char_instance,
- const void* source) {
- furi_assert(char_instance);
- const FlipperGattCharacteristicParams* char_descriptor = char_instance->characteristic;
- FURI_LOG_D(TAG, "Updating %s char", char_descriptor->name);
-
- const uint8_t* char_data = NULL;
- uint16_t char_data_size = 0;
- bool release_data = false;
- if(char_descriptor->data_prop_type == FlipperGattCharacteristicDataFixed) {
- char_data = char_descriptor->data.fixed.ptr;
- if(source) {
- char_data = (uint8_t*)source;
- }
- char_data_size = char_descriptor->data.fixed.length;
- } else if(char_descriptor->data_prop_type == FlipperGattCharacteristicDataCallback) {
- const void* context = char_descriptor->data.callback.context;
- if(source) {
- context = source;
- }
- release_data = char_descriptor->data.callback.fn(context, &char_data, &char_data_size);
- }
-
- tBleStatus result = aci_gatt_update_char_value(
- svc_handle, char_instance->handle, 0, char_data_size, char_data);
- if(result) {
- FURI_LOG_E(TAG, "Failed updating %s characteristic: %d", char_descriptor->name, result);
- }
- if(release_data) {
- free((void*)char_data);
- }
- return result != BLE_STATUS_SUCCESS;
-}
\ No newline at end of file
diff --git a/firmware/targets/f7/ble_glue/services/gatt_char.h b/firmware/targets/f7/ble_glue/services/gatt_char.h
deleted file mode 100644
index 959ab67a49..0000000000
--- a/firmware/targets/f7/ble_glue/services/gatt_char.h
+++ /dev/null
@@ -1,96 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-
-#include <ble/ble.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Callback signature for getting characteristic data
-// Is called when characteristic is created to get max data length. Data ptr is NULL in this case
-// The result is passed to aci_gatt_add_char as "Char_Value_Length"
-// For updates, called with a context - see flipper_gatt_characteristic_update
-// Returns true if *data ownership is transferred to the caller and will be freed
-typedef bool (*cbFlipperGattCharacteristicData)(
- const void* context,
- const uint8_t** data,
- uint16_t* data_len);
-
-typedef enum {
- FlipperGattCharacteristicDataFixed,
- FlipperGattCharacteristicDataCallback,
-} FlipperGattCharacteristicDataType;
-
-typedef struct {
- Char_Desc_Uuid_t uuid;
- struct {
- cbFlipperGattCharacteristicData fn;
- const void* context;
- } data_callback;
- uint8_t uuid_type;
- uint8_t max_length;
- uint8_t security_permissions;
- uint8_t access_permissions;
- uint8_t gatt_evt_mask;
- uint8_t is_variable;
-} FlipperGattCharacteristicDescriptorParams;
-
-typedef struct {
- const char* name;
- FlipperGattCharacteristicDescriptorParams* descriptor_params;
- union {
- struct {
- const uint8_t* ptr;
- uint16_t length;
- } fixed;
- struct {
- cbFlipperGattCharacteristicData fn;
- const void* context;
- } callback;
- } data;
- Char_UUID_t uuid;
- // Some packed bitfields to save space
- FlipperGattCharacteristicDataType data_prop_type : 2;
- uint8_t is_variable : 2;
- uint8_t uuid_type : 2;
- uint8_t char_properties;
- uint8_t security_permissions;
- uint8_t gatt_evt_mask;
-} FlipperGattCharacteristicParams;
-
-_Static_assert(
- sizeof(FlipperGattCharacteristicParams) == 36,
- "FlipperGattCharacteristicParams size must be 36 bytes");
-
-typedef struct {
- const FlipperGattCharacteristicParams* characteristic;
- uint16_t handle;
- uint16_t descriptor_handle;
-} FlipperGattCharacteristicInstance;
-
-// Initialize a characteristic instance; copies the characteristic descriptor into the instance
-void flipper_gatt_characteristic_init(
- uint16_t svc_handle,
- const FlipperGattCharacteristicParams* char_descriptor,
- FlipperGattCharacteristicInstance* char_instance);
-
-// Delete a characteristic instance; frees the copied characteristic descriptor from the instance
-void flipper_gatt_characteristic_delete(
- uint16_t svc_handle,
- FlipperGattCharacteristicInstance* char_instance);
-
-// Update a characteristic instance; if source==NULL, uses the data from the characteristic
-// - For fixed data, fixed.ptr is used as the source if source==NULL
-// - For callback-based data, collback.context is passed as the context if source==NULL
-bool flipper_gatt_characteristic_update(
- uint16_t svc_handle,
- FlipperGattCharacteristicInstance* char_instance,
- const void* source);
-
-#ifdef __cplusplus
-}
-#endif
\ No newline at end of file
diff --git a/firmware/targets/f7/ble_glue/services/hid_service.c b/firmware/targets/f7/ble_glue/services/hid_service.c
deleted file mode 100644
index 11f10b7b38..0000000000
--- a/firmware/targets/f7/ble_glue/services/hid_service.c
+++ /dev/null
@@ -1,365 +0,0 @@
-#include "hid_service.h"
-#include "app_common.h"
-#include <ble/ble.h>
-#include "gatt_char.h"
-
-#include <furi.h>
-
-#define TAG "BtHid"
-
-typedef enum {
- HidSvcGattCharacteristicProtocolMode = 0,
- HidSvcGattCharacteristicReportMap,
- HidSvcGattCharacteristicInfo,
- HidSvcGattCharacteristicCtrlPoint,
- HidSvcGattCharacteristicLed,
- HidSvcGattCharacteristicCount,
-} HidSvcGattCharacteristicId;
-
-typedef struct {
- uint8_t report_idx;
- uint8_t report_type;
-} HidSvcReportId;
-
-static_assert(sizeof(HidSvcReportId) == sizeof(uint16_t), "HidSvcReportId must be 2 bytes");
-
-static bool
- hid_svc_char_desc_data_callback(const void* context, const uint8_t** data, uint16_t* data_len) {
- const HidSvcReportId* report_id = context;
- *data_len = sizeof(HidSvcReportId);
- if(data) {
- *data = (const uint8_t*)report_id;
- }
- return false;
-}
-
-typedef struct {
- const void* data_ptr;
- uint16_t data_len;
-} HidSvcDataWrapper;
-
-static bool
- hid_svc_report_data_callback(const void* context, const uint8_t** data, uint16_t* data_len) {
- const HidSvcDataWrapper* report_data = context;
- if(data) {
- *data = report_data->data_ptr;
- *data_len = report_data->data_len;
- } else {
- *data_len = HID_SVC_REPORT_MAP_MAX_LEN;
- }
- return false;
-}
-
-// LED Descriptor params for BadBT
-
-static uint8_t led_desc_context_buf[2] = {HID_SVC_REPORT_COUNT + 1, 2};
-
-static FlipperGattCharacteristicDescriptorParams hid_svc_char_descr_led = {
- .uuid_type = UUID_TYPE_16,
- .uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID,
- .max_length = HID_SVC_REPORT_REF_LEN,
- .data_callback.fn = hid_svc_char_desc_data_callback,
- .data_callback.context = led_desc_context_buf,
- .security_permissions = ATTR_PERMISSION_NONE,
- .access_permissions = ATTR_ACCESS_READ_WRITE,
- .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS,
- .is_variable = CHAR_VALUE_LEN_CONSTANT,
-};
-
-static const FlipperGattCharacteristicParams hid_svc_chars[HidSvcGattCharacteristicCount] = {
- [HidSvcGattCharacteristicProtocolMode] =
- {.name = "Protocol Mode",
- .data_prop_type = FlipperGattCharacteristicDataFixed,
- .data.fixed.length = 1,
- .uuid.Char_UUID_16 = PROTOCOL_MODE_CHAR_UUID,
- .uuid_type = UUID_TYPE_16,
- .char_properties = CHAR_PROP_READ | CHAR_PROP_WRITE_WITHOUT_RESP,
- .security_permissions = ATTR_PERMISSION_NONE,
- .gatt_evt_mask = GATT_NOTIFY_ATTRIBUTE_WRITE,
- .is_variable = CHAR_VALUE_LEN_CONSTANT},
- [HidSvcGattCharacteristicReportMap] =
- {.name = "Report Map",
- .data_prop_type = FlipperGattCharacteristicDataCallback,
- .data.callback.fn = hid_svc_report_data_callback,
- .data.callback.context = NULL,
- .uuid.Char_UUID_16 = REPORT_MAP_CHAR_UUID,
- .uuid_type = UUID_TYPE_16,
- .char_properties = CHAR_PROP_READ,
- .security_permissions = ATTR_PERMISSION_NONE,
- .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS,
- .is_variable = CHAR_VALUE_LEN_VARIABLE},
- [HidSvcGattCharacteristicInfo] =
- {.name = "HID Information",
- .data_prop_type = FlipperGattCharacteristicDataFixed,
- .data.fixed.length = HID_SVC_INFO_LEN,
- .data.fixed.ptr = NULL,
- .uuid.Char_UUID_16 = HID_INFORMATION_CHAR_UUID,
- .uuid_type = UUID_TYPE_16,
- .char_properties = CHAR_PROP_READ,
- .security_permissions = ATTR_PERMISSION_NONE,
- .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS,
- .is_variable = CHAR_VALUE_LEN_CONSTANT},
- [HidSvcGattCharacteristicCtrlPoint] =
- {.name = "HID Control Point",
- .data_prop_type = FlipperGattCharacteristicDataFixed,
- .data.fixed.length = HID_SVC_CONTROL_POINT_LEN,
- .uuid.Char_UUID_16 = HID_CONTROL_POINT_CHAR_UUID,
- .uuid_type = UUID_TYPE_16,
- .char_properties = CHAR_PROP_WRITE_WITHOUT_RESP,
- .security_permissions = ATTR_PERMISSION_NONE,
- .gatt_evt_mask = GATT_NOTIFY_ATTRIBUTE_WRITE,
- .is_variable = CHAR_VALUE_LEN_CONSTANT},
- [HidSvcGattCharacteristicLed] =
- {
- .name =
- "HID LED State", // LED Characteristic and descriptor for BadBT to get numlock state for altchars
- .data_prop_type = FlipperGattCharacteristicDataFixed,
- .data.fixed.length = 1,
- .uuid.Char_UUID_16 = REPORT_CHAR_UUID,
- .uuid_type = UUID_TYPE_16,
- .char_properties = CHAR_PROP_READ | CHAR_PROP_WRITE_WITHOUT_RESP | CHAR_PROP_WRITE,
- .security_permissions = ATTR_PERMISSION_NONE,
- .gatt_evt_mask = GATT_NOTIFY_ATTRIBUTE_WRITE |
- GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP,
- .is_variable = CHAR_VALUE_LEN_CONSTANT,
- .descriptor_params = &hid_svc_char_descr_led,
- },
-};
-
-static const FlipperGattCharacteristicDescriptorParams hid_svc_char_descr_template = {
- .uuid_type = UUID_TYPE_16,
- .uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID,
- .max_length = HID_SVC_REPORT_REF_LEN,
- .data_callback.fn = hid_svc_char_desc_data_callback,
- .security_permissions = ATTR_PERMISSION_NONE,
- .access_permissions = ATTR_ACCESS_READ_WRITE,
- .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS,
- .is_variable = CHAR_VALUE_LEN_CONSTANT,
-};
-
-static const FlipperGattCharacteristicParams hid_svc_report_template = {
- .name = "Report",
- .data_prop_type = FlipperGattCharacteristicDataCallback,
- .data.callback.fn = hid_svc_report_data_callback,
- .data.callback.context = NULL,
- .uuid.Char_UUID_16 = REPORT_CHAR_UUID,
- .uuid_type = UUID_TYPE_16,
- .char_properties = CHAR_PROP_READ | CHAR_PROP_NOTIFY,
- .security_permissions = ATTR_PERMISSION_NONE,
- .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS,
- .is_variable = CHAR_VALUE_LEN_VARIABLE,
-};
-
-typedef struct {
- uint16_t svc_handle;
- FlipperGattCharacteristicInstance chars[HidSvcGattCharacteristicCount];
- FlipperGattCharacteristicInstance input_report_chars[HID_SVC_INPUT_REPORT_COUNT];
- FlipperGattCharacteristicInstance output_report_chars[HID_SVC_OUTPUT_REPORT_COUNT];
- FlipperGattCharacteristicInstance feature_report_chars[HID_SVC_FEATURE_REPORT_COUNT];
- // led state
- HidLedStateEventCallback led_state_event_callback;
- void* led_state_ctx;
-} HIDSvc;
-
-static HIDSvc* hid_svc = NULL;
-
-static SVCCTL_EvtAckStatus_t hid_svc_event_handler(void* event) {
- SVCCTL_EvtAckStatus_t ret = SVCCTL_EvtNotAck;
- hci_event_pckt* event_pckt = (hci_event_pckt*)(((hci_uart_pckt*)event)->data);
- evt_blecore_aci* blecore_evt = (evt_blecore_aci*)event_pckt->data;
- // aci_gatt_attribute_modified_event_rp0* attribute_modified;
- if(event_pckt->evt == HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE) {
- if(blecore_evt->ecode == ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE) {
- // Process modification events
- ret = SVCCTL_EvtAckFlowEnable;
- } else if(blecore_evt->ecode == ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE) {
- // Process notification confirmation
- ret = SVCCTL_EvtAckFlowEnable;
- } else if(blecore_evt->ecode == ACI_GATT_WRITE_PERMIT_REQ_VSEVT_CODE) {
- // LED Characteristic and descriptor for BadBT to get numlock state for altchars
- //
- // Process write request
- aci_gatt_write_permit_req_event_rp0* req =
- (aci_gatt_write_permit_req_event_rp0*)blecore_evt->data;
-
- furi_check(hid_svc->led_state_event_callback && hid_svc->led_state_ctx);
-
- // this check is likely to be incorrect, it will actually work in our case
- // but we need to investigate gatt api to see what is the rules
- // that specify attibute handle value from char handle (or the reverse)
- if(req->Attribute_Handle == (hid_svc->chars[HidSvcGattCharacteristicLed].handle + 1)) {
- hid_svc->led_state_event_callback(req->Data[0], hid_svc->led_state_ctx);
- aci_gatt_write_resp(
- req->Connection_Handle,
- req->Attribute_Handle,
- 0x00, /* write_status = 0 (no error))*/
- 0x00, /* err_code */
- req->Data_Length,
- req->Data);
- aci_gatt_write_char_value(
- req->Connection_Handle,
- hid_svc->chars[HidSvcGattCharacteristicLed].handle,
- req->Data_Length,
- req->Data);
- ret = SVCCTL_EvtAckFlowEnable;
- }
- }
- }
- return ret;
-}
-
-void hid_svc_start() {
- tBleStatus status;
- hid_svc = malloc(sizeof(HIDSvc));
- Service_UUID_t svc_uuid = {};
-
- // Register event handler
- SVCCTL_RegisterSvcHandler(hid_svc_event_handler);
- // Add service
- svc_uuid.Service_UUID_16 = HUMAN_INTERFACE_DEVICE_SERVICE_UUID;
- /**
- * Add Human Interface Device Service
- */
- status = aci_gatt_add_service(
- UUID_TYPE_16,
- &svc_uuid,
- PRIMARY_SERVICE,
- 2 + /* protocol mode */
- (4 * HID_SVC_INPUT_REPORT_COUNT) + (3 * HID_SVC_OUTPUT_REPORT_COUNT) +
- (3 * HID_SVC_FEATURE_REPORT_COUNT) + 1 + 2 + 2 + 2 +
- 4, /* Service + Report Map + HID Information + HID Control Point + LED state */
- &hid_svc->svc_handle);
- if(status) {
- FURI_LOG_E(TAG, "Failed to add HID service: %d", status);
- }
-
- for(size_t i = 0; i < HidSvcGattCharacteristicCount; i++) {
- flipper_gatt_characteristic_init(
- hid_svc->svc_handle, &hid_svc_chars[i], &hid_svc->chars[i]);
- }
- uint8_t protocol_mode = 1;
- flipper_gatt_characteristic_update(
- hid_svc->svc_handle,
- &hid_svc->chars[HidSvcGattCharacteristicProtocolMode],
- &protocol_mode);
-
- // reports
- FlipperGattCharacteristicDescriptorParams hid_svc_char_descr;
- FlipperGattCharacteristicParams report_char;
- HidSvcReportId report_id;
-
- memcpy(&hid_svc_char_descr, &hid_svc_char_descr_template, sizeof(hid_svc_char_descr));
- memcpy(&report_char, &hid_svc_report_template, sizeof(report_char));
-
- hid_svc_char_descr.data_callback.context = &report_id;
- report_char.descriptor_params = &hid_svc_char_descr;
-
- typedef struct {
- uint8_t report_type;
- uint8_t report_count;
- FlipperGattCharacteristicInstance* chars;
- } HidSvcReportCharProps;
-
- HidSvcReportCharProps hid_report_chars[] = {
- {0x01, HID_SVC_INPUT_REPORT_COUNT, hid_svc->input_report_chars},
- {0x02, HID_SVC_OUTPUT_REPORT_COUNT, hid_svc->output_report_chars},
- {0x03, HID_SVC_FEATURE_REPORT_COUNT, hid_svc->feature_report_chars},
- };
-
- for(size_t report_type_idx = 0; report_type_idx < COUNT_OF(hid_report_chars);
- report_type_idx++) {
- report_id.report_type = hid_report_chars[report_type_idx].report_type;
- for(size_t report_idx = 0; report_idx < hid_report_chars[report_type_idx].report_count;
- report_idx++) {
- report_id.report_idx = report_idx + 1;
- flipper_gatt_characteristic_init(
- hid_svc->svc_handle,
- &report_char,
- &hid_report_chars[report_type_idx].chars[report_idx]);
- }
- }
-}
-
-bool hid_svc_update_report_map(const uint8_t* data, uint16_t len) {
- furi_assert(data);
- furi_assert(hid_svc);
-
- HidSvcDataWrapper report_data = {
- .data_ptr = data,
- .data_len = len,
- };
- return flipper_gatt_characteristic_update(
- hid_svc->svc_handle, &hid_svc->chars[HidSvcGattCharacteristicReportMap], &report_data);
-}
-
-bool hid_svc_update_input_report(uint8_t input_report_num, uint8_t* data, uint16_t len) {
- furi_assert(data);
- furi_assert(hid_svc);
- furi_assert(input_report_num < HID_SVC_INPUT_REPORT_COUNT);
-
- HidSvcDataWrapper report_data = {
- .data_ptr = data,
- .data_len = len,
- };
- return flipper_gatt_characteristic_update(
- hid_svc->svc_handle, &hid_svc->input_report_chars[input_report_num], &report_data);
-}
-
-bool hid_svc_update_info(uint8_t* data) {
- furi_assert(data);
- furi_assert(hid_svc);
-
- return flipper_gatt_characteristic_update(
- hid_svc->svc_handle, &hid_svc->chars[HidSvcGattCharacteristicInfo], &data);
-}
-
-void hid_svc_register_led_state_callback(HidLedStateEventCallback callback, void* context) {
- furi_assert(hid_svc);
- furi_assert(callback);
- furi_assert(context);
-
- hid_svc->led_state_event_callback = callback;
- hid_svc->led_state_ctx = context;
-}
-
-bool hid_svc_is_started() {
- return hid_svc != NULL;
-}
-
-void hid_svc_stop() {
- tBleStatus status;
- if(hid_svc) {
- // Delete characteristics
- for(size_t i = 0; i < HidSvcGattCharacteristicCount; i++) {
- flipper_gatt_characteristic_delete(hid_svc->svc_handle, &hid_svc->chars[i]);
- }
-
- typedef struct {
- uint8_t report_count;
- FlipperGattCharacteristicInstance* chars;
- } HidSvcReportCharProps;
-
- HidSvcReportCharProps hid_report_chars[] = {
- {HID_SVC_INPUT_REPORT_COUNT, hid_svc->input_report_chars},
- {HID_SVC_OUTPUT_REPORT_COUNT, hid_svc->output_report_chars},
- {HID_SVC_FEATURE_REPORT_COUNT, hid_svc->feature_report_chars},
- };
-
- for(size_t report_type_idx = 0; report_type_idx < COUNT_OF(hid_report_chars);
- report_type_idx++) {
- for(size_t report_idx = 0; report_idx < hid_report_chars[report_type_idx].report_count;
- report_idx++) {
- flipper_gatt_characteristic_delete(
- hid_svc->svc_handle, &hid_report_chars[report_type_idx].chars[report_idx]);
- }
- }
-
- // Delete service
- status = aci_gatt_del_service(hid_svc->svc_handle);
- if(status) {
- FURI_LOG_E(TAG, "Failed to delete HID service: %d", status);
- }
- free(hid_svc);
- hid_svc = NULL;
- }
-}
diff --git a/firmware/targets/f7/ble_glue/services/serial_service_uuid.inc b/firmware/targets/f7/ble_glue/services/serial_service_uuid.inc
deleted file mode 100644
index a297d9ad60..0000000000
--- a/firmware/targets/f7/ble_glue/services/serial_service_uuid.inc
+++ /dev/null
@@ -1,12 +0,0 @@
-
-static const Service_UUID_t service_uuid = { .Service_UUID_128 = \
- { 0x00, 0x00, 0xfe, 0x60, 0xcc, 0x7a, 0x48, 0x2a, 0x98, 0x4a, 0x7f, 0x2e, 0xd5, 0xb3, 0xe5, 0x8f }};
-
-#define SERIAL_SVC_TX_CHAR_UUID \
- { 0x00, 0x00, 0xfe, 0x61, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19 }
-#define SERIAL_SVC_RX_CHAR_UUID \
- { 0x00, 0x00, 0xfe, 0x62, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19 }
-#define SERIAL_SVC_FLOW_CONTROL_UUID \
- { 0x00, 0x00, 0xfe, 0x63, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19 }
-#define SERIAL_SVC_RPC_STATUS_UUID \
- { 0x00, 0x00, 0xfe, 0x64, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19 }
diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c
index 22d286abd0..f71cd37762 100644
--- a/firmware/targets/f7/furi_hal/furi_hal_bt.c
+++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c
@@ -8,7 +8,8 @@
#include <furi_hal_bt_hid.h>
#include <furi_hal_bt_serial.h>
#include <furi_hal_bus.c>
-#include <services/battery_service.h>
+#include "battery_service.h"
+
#include <furi.h>
#define TAG "FuriHalBt"
diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt_hid.c b/firmware/targets/f7/furi_hal/furi_hal_bt_hid.c
index 2bbfc15231..8e05a99049 100644
--- a/firmware/targets/f7/furi_hal/furi_hal_bt_hid.c
+++ b/firmware/targets/f7/furi_hal/furi_hal_bt_hid.c
@@ -1,11 +1,11 @@
#include <furi_hal_bt_hid.h>
#include <furi_hal_usb_hid.h>
-#include <services/dev_info_service.h>
-#include <services/battery_service.h>
-#include <services/hid_service.h>
+#include "usb_hid.h"
+#include "dev_info_service.h"
+#include "battery_service.h"
+#include "hid_service.h"
#include <furi.h>
-#include <usb_hid.h>
#define FURI_HAL_BT_INFO_BASE_USB_SPECIFICATION (0x0101)
#define FURI_HAL_BT_INFO_COUNTRY_CODE (0x00)
@@ -221,7 +221,7 @@ void furi_hal_bt_hid_start() {
FURI_HAL_BT_HID_INFO_FLAG_REMOTE_WAKE_MSK |
FURI_HAL_BT_HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK,
};
- hid_svc_update_info(hid_info_val);
+ hid_svc_update_info(hid_info_val, sizeof(hid_info_val));
}
void furi_hal_bt_hid_stop() {
diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt_serial.c b/firmware/targets/f7/furi_hal/furi_hal_bt_serial.c
index 2927d946f9..2539e6bd0e 100644
--- a/firmware/targets/f7/furi_hal/furi_hal_bt_serial.c
+++ b/firmware/targets/f7/furi_hal/furi_hal_bt_serial.c
@@ -1,7 +1,7 @@
#include <furi_hal_bt_serial.h>
-#include <services/dev_info_service.h>
-#include <services/battery_service.h>
-#include <services/serial_service.h>
+#include "dev_info_service.h"
+#include "battery_service.h"
+#include "serial_service.h"
#include <furi.h>
diff --git a/firmware/targets/furi_hal_include/furi_hal_bt.h b/firmware/targets/furi_hal_include/furi_hal_bt.h
index d6a6e8c42b..bfe4a67c3c 100644
--- a/firmware/targets/furi_hal_include/furi_hal_bt.h
+++ b/firmware/targets/furi_hal_include/furi_hal_bt.h
@@ -8,7 +8,7 @@
#include <furi.h>
#include <stdbool.h>
#include <gap.h>
-#include <services/serial_service.h>
+#include <serial_service.h>
#include <ble_glue.h>
#include <ble_app.h>
diff --git a/firmware/targets/furi_hal_include/furi_hal_bt_serial.h b/firmware/targets/furi_hal_include/furi_hal_bt_serial.h
index 0472d31d18..1b6e79ab07 100644
--- a/firmware/targets/furi_hal_include/furi_hal_bt_serial.h
+++ b/firmware/targets/furi_hal_include/furi_hal_bt_serial.h
@@ -1,6 +1,6 @@
#pragma once
-#include <services/serial_service.h>
+#include "serial_service.h"
#ifdef __cplusplus
extern "C" {