mcu_hi3321_watch/tjd/ble/ble_port_hid_service.c
2025-05-26 20:15:20 +08:00

474 lines
20 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "ble_port_hid_service.h"
/* Human Interface Device UUID */
#define BLE_UUID_HUMAN_INTERFACE_DEVICE 0x1812
/* HID Information UUID */
#define BLE_UUID_HID_INFORMATION 0x2A4A
/* Report Map UUID */
#define BLE_UUID_REPORT_MAP 0x2A4B
/* HID Control Point UUID */
#define BLE_UUID_HID_CONTROL_POINT 0x2A4C
/* Boot Keyboard Input Report UUID */
#define BLE_UUID_BOOT_KEYBOARD_INPUT_REPORT 0x2A22
/* Boot Keyboard Output Report UUID */
#define BLE_UUID_BOOT_KEYBOARD_OUTPUT_REPORT 0x2A32
/* Report UUID */
#define BLE_UUID_REPORT 0x2A4D
/* Protocol Mode UUID */
#define BLE_UUID_PROTOCOL_MODE 0x2A4E
/* Client Characteristic Configuration UUID */
#define BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION 0x2902
/* External Report Reference UUID */
#define BLE_UUID_EXTERNAL_REPORT_REFERENCE 0x2907
/* Report Reference UUID */
#define BLE_UUID_REPORT_REFERENCE 0x2908
/* HID character value handle offset */
#define BLE_HID_CHARACTER_INPUT_REPORT_VALUE_HANDLE_OFFSET 8
/* HID information flag remote wakeup */
#define BLE_HID_INFO_FLAG_REMOTE_WAKE_UP_MSK 0x01
/* HID information flag normally connectable */
#define BLE_HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK 0x02
/* HID information country code */
#define BLE_HID_INFO_COUNTRY_CODE 0x00
/* HID spec version 1.11 */
#define BLE_HID_VERSION 0x0101
/* HID input report id */
#define BLE_HID_REPORT_ID 1
/* HID input report id 2*/
#define BLE_HID_REPORT_ID_2 2
/* HID input report id 3*/
#define BLE_HID_REPORT_ID_3 3
/* HID input report type */
#define BLE_REPORT_REFERENCE_REPORT_TYPE_INPUT_REPORT 1
/* HID output report type */
#define BLE_REPORT_REFERENCE_REPORT_TYPE_OUTPUT_REPORT 2
/* HID gatt server id */
#define BLE_HID_SERVER_ID 1
/* HID ble connect id */
#define BLE_SINGLE_LINK_CONNECT_ID 1
/* HID gatt attribute num */
#define BLE_HID_ATTRIBUTE_NUM 10
/* HID gatt notification flag, do not need confirm */
#define GATT_NOTIFICATION_FLAG 0
/* HID gatt indication flag, need confirm */
#define GATT_INDICATION_FLAG 1
#define uint16_to_byte(n) ((uint8_t)(n)), ((uint8_t)((n) >> 8))
#define ENABLE_PRINT_INFO 1
#if ENABLE_PRINT_INFO
#define static_print_debug(...) sys_bt_log_d(__VA_ARGS__) // 一般信息打印宏控制
#define static_print_warn(...) sys_bt_log_w(__VA_ARGS__) // 警告信息打印一般常开
#define static_print_error(...) sys_bt_log_e(__VA_ARGS__) // 错误信息打印一般常开
#else
#define static_print_debug(...)
#define static_print_warn(...)
#define static_print_error(...)
#endif
enum
{
/* HID information characteristic properties */
HID_INFORMATION_PROPERTIES = GATT_CHARACTER_PROPERTY_BIT_READ,
/* HID protocol mode characteristic properties */
HID_PROTOCOL_MODE_PROPERTIES = GATT_CHARACTER_PROPERTY_BIT_READ | GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP,
/* HID report map characteristic properties */
HID_REPORT_MAP_PROPERTIES = GATT_CHARACTER_PROPERTY_BIT_READ,
/* HID input report characteristic properties */
HID_INPUT_REPORT_PROPERTIES =
GATT_CHARACTER_PROPERTY_BIT_READ | GATT_CHARACTER_PROPERTY_BIT_NOTIFY | GATT_CHARACTER_PROPERTY_BIT_WRITE,
/* HID output report characteristic properties */
HID_OUTPUT_REPORT_PROPERTIES =
GATT_CHARACTER_PROPERTY_BIT_READ | GATT_CHARACTER_PROPERTY_BIT_WRITE | GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP,
/* HID control point characteristic properties */
HID_CONTROL_POINT_PROPERTIES = GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP,
};
// const uint8_t tjd_srv_hid_report_map[] = {
// 0x05, 0x0C, // 用法页(消费者设备)
// 0x09, 0x01, // 用法(消费者控制)
// 0xA1, 0x01, // 集合(应用)
// 0x15, 0x00, // 逻辑最小值0
// 0x25, 0x01, // 逻辑最大值1
// 0x09, 0xCD, // 用法(播放/暂停)
// 0x09, 0xB5, // 用法(下一曲目)
// 0x09, 0xB6, // 用法(上一曲目)
// 0x09, 0xE9, // 用法(音量增加)
// 0x09, 0xEA, // 用法(音量减少)
// 0x95, 0x05, // 报告计数5
// 0x75, 0x01, // 报告大小1
// 0x81, 0x02, // 输入(数据,变量,绝对)
// 0x95, 0x01, // 报告计数1
// 0x75, 0x03, // 报告大小3
// 0x81, 0x03, // 输入(常量,变量,绝对)
// 0xC0 // 结束集合
// };
// const uint8_t tjd_srv_hid_report_map[] = {
// 0x05, 0x0C, // Usage Page (Consumer)
// 0x09, 0x01, // Usage (Consumer Control)
// 0xA1, 0x01, // Collection (Application)
// 0x85, 0x01, // Report Id (1)
// 0x15, 0x00, // Logical minimum (0)
// 0x25, 0x01, // Logical maximum (1)
// 0x75, 0x01, // Report Size (1)
// 0x95, 0x01, // Report Count (1)
// 0x09, 0xCD, // Usage (Play/Pause)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x0A, 0x83, 0x01, // Usage (AL Consumer Control Configuration)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xB5, // Usage (Scan Next Track)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xB6, // Usage (Scan Previous Track)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xEA, // Usage (Volume Down)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xE9, // Usage (Volume Up)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x0A, 0x25, 0x02, // Usage (AC Forward)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x0A, 0x24, 0x02, // Usage (AC Back)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0xC0 // End Collection
// };
// const uint8_t tjd_srv_hid_report_map[] = {
// // Report ID 1: Advanced buttons
// 0x05, 0x0C, // Usage Page (Consumer)
// 0x09, 0x01, // Usage (Consumer Control)
// 0xA1, 0x01, // Collection (Application)
// 0x85, 0x01, // Report Id (1)
// 0x15, 0x00, // Logical minimum (0)
// 0x25, 0x01, // Logical maximum (1)
// 0x75, 0x01, // Report Size (1)
// 0x95, 0x01, // Report Count (1)
// 0x09, 0x94, // (Quit)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0x95, // (Help)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xEA, // (Volume Down)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xE9, // (Volume Up)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xCB, // (Tracking Decrement)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xCA, // (tracking Increment)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xB6, // (Scan Previous Track)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xB5, // (Scan Next Track)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xB1, // (Pause)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xB0, // (Play)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x75, 0x01, // Report Size (1)
// 0x95, 0x06, // Report Count (6)
// 0x81, 0x07, // Input (Data,Value,Relative,Bit Field)
// 0xC0 // End Collection
// };
// const uint8_t tjd_srv_hid_report_map[] = {
// 0x05,0x0c, //USAGE PAGE(Consumer Devices
// 0x09,0x01, //USAGE (Consumer Control)
// 0xA1,0x01, //COLLECTION (Application)
// 0x85,0x01, //REPORT ID (1)
// 0x15,0x00, //LOGICAL MINIMUM(0)
// 0x25,0x01, //LOGICAL MAXIMUM(1)
// 0x75,0x01, //REPORT SIZE (1)
// 0x95,0x01, //REPORT COUNT (1)
// 0x09,0xcd, //USAGE(Play/Pause)
// 0x81,0x06, //INPUT(Data,Var,Rel)
// 0x09,0x6f, //USAGE(Display Brightness Increment)
// 0x81,0x06, //INPUT(Data,Var,Rel
// 0x09,0x70, //USAGE(Display BrightnessDecrement)
// 0x81,0x06, //INPUT(Data,Var,Rel)
// 0x09,0xb5, //USAGE(Scan Next Track)
// 0x81,0x06, //INPUT(Data,Var,Rel)
// 0x09,0xb6, //USAGE(Scan Previous Track)
// 0x81,0x06, //INPUT(Data,Var,Rel)
// 0x09,0xe9, //USAGE(Volume Up)
// 0x81,0x06, //INPUT(Data,Var,Rel)
// 0x09,0xEA, //USAGE(Volume Down)
// 0x81,0x06, //INPUT(Data,Var,Rel)
// 0x95,0x01, //REPORT COUNT(1)
// 0x75,0x01, //REPORT SIZE(1)
// 0x81,0x01, //INPUT(Cnst,Ary,Abs)
// 0xc0 //END COLLECTION
// };
// static const uint8_t tjd_srv_hid_report_map[] = {
// // Report ID 1: Advanced buttons
// 0x05, 0x0C, // Usage Page (Consumer)
// 0x09, 0x01, // Usage (Consumer Control)
// 0xA1, 0x01, // Collection (Application)
// 0x85, 0x01, // Report Id (1)
// 0x15, 0x00, // Logical minimum (0)
// 0x25, 0x01, // Logical maximum (1)
// 0x75, 0x01, // Report Size (1)
// 0x95, 0x01, // Report Count (1)
// 0x09, 0x94, // (Quit)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0x95, // (Help)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xEA, // (Volume Down)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xE9, // (Volume Up)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xCB, // (Tracking Decrement)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xCA, // (tracking Increment)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xB6, // (Scan Previous Track)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xB5, // (Scan Next Track)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xB1, // (Pause)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x09, 0xB0, // (Play)
// 0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
// 0x75, 0x01, // Report Size (1)
// 0x95, 0x06, // Report Count (6)
// 0x81, 0x07, // Input (Data,Value,Relative,Bit Field)
// 0xC0 // End Collection
// };
static const uint8_t tjd_srv_hid_report_map[] = {
0x05, 0x01,// Usage Page (Generic Desktop)
0x09, 0x02,// Usage (Mouse)
0xA1, 0x01, // Collection (Application)
// Report ID 1: Mouse buttons + scroll/ pan
0x85, 0x01, // Report Id 1
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection (Physical)
0x95, 0x05, // Report Count (3)
0x75, 0x01, // Report Size (1)
0x05, 0x09, // Usage Page (Buttons)
0x19, 0x01, // Usage Minimum (01)
0x29, 0x05, // Usage Maximum (05)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x81, 0x02, // Input (Data, Variable, Absolute)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x81, 0x01, // Input (Constant) for padding
0x75, 0x08, // Report Size (8)
0x95, 0x01, // Report Count (1)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x38, // Usage (Wheel)
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Loaical Maximum (127)
0x81, 0x06, // Input (Data, Variable, Relative)
0x05, 0x0C, // Usage Page (Consumer)
0x0A, 0x38, 0x02, //Usage(AC Pan)
0x95, 0x01, // Report Count (1)
0x81, 0x06, // Input (Data, Value, Relative, Bit Field)
0xC0, //End Collection(Physical)
// Report ID 2: Mouse motion
0x85, 0x02, // Report Id 2
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection (Physical)
0x75, 0x0c, // Report Size (12)
0x95, 0x02, // Report Count (2)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x25, 0x7F, // Logical maximum (2047)
0x15, 0x81, // Logical minimum (-2047)
0x81, 0x06, // Input (Data, Variable, Relative)
0xC0, // End Collection (Physical)
0xC0, // End Collection (Application)
// Report ID 3: Advanced buttons
0x05, 0x0C, // Usage Page (Consumer)
0x09, 0x01, // Usage (Consumer Control)
0xA1, 0x01, // Collection (Application)
0x85, 0x03, // Report Id (3)
0x15, 0x00, // Logical minimum (0)
0x25, 0x01, // Logical maximum(1)
0x75, 0x01, // Report Size (1)
0x95, 0x01, // Report Count (1)
0x09, 0xCD, // Usage (Play/ Pause)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0x0A, 0x83, 0x01, // Usage (AL Consumer Control Configuration)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0x09, 0xB5, // Usage (Scan Next Track)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0x09, 0xB6, // Usage (Scan Previous Track)
0x81, 0x06, // Input (Data,Value,Relative,Bit Fieid)
0x09, 0xEA, // Usage (Volume Down)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0x09, 0xE9, // Usage (Volume Up)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0x0A, 0x25, 0x02, // Usage (AC Forward)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0x0A, 0x24, 0x02,// Usage (AC Back)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0xC0 // End Collection
};
// /* Hid Report Map (Descriptor) */
// uint8_t tjd_srv_hid_report_map[] = {
// 0x05, 0x0C, /* Usage Page (Consumer) */
// 0x09, 0x01, /* Usage (Consumer Control) */
// 0xA1, 0x01, /* Collection (Application) */
// 0x85, 0x01, /* Report ID (1) */
// 0x09, 0xE9, /* Usage (Volume Increment) */
// 0x09, 0xEA, /* Usage (Volume Decrement) */
// 0x09, 0xE2, /* Usage (Mute) */
// 0x09, 0x30, /* Usage (Power) */
// 0x15, 0x01, /* Logical minimum (1) */
// 0x25, 0x0C, /* Logical maximum (12) */
// 0x75, 0x10, /* Report Size (16) */
// 0x95, 0x01, /* Report Count (1) */
// 0x81, 0x00, /* INPUT (Data,Array,Absolute,Bit Field) */
// 0xC0, /* End Collection */
// };
// /* 添加特征HID information */
static void tjd_ble_hid_add_character_hid_information(uint8_t server_id, uint16_t srvc_handle)
{
/* HID information value for test */
static uint8_t hid_information_val[] = {uint16_to_byte(BLE_HID_VERSION), BLE_HID_INFO_COUNTRY_CODE,
BLE_HID_INFO_FLAG_REMOTE_WAKE_UP_MSK |
BLE_HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK};
gatts_add_chara_info_t character;
bts_data_to_uuid_len2(BLE_UUID_HID_INFORMATION, &character.chara_uuid);
character.permissions = GATT_ATTRIBUTE_PERMISSION_READ;
character.properties = HID_INFORMATION_PROPERTIES;
// character.properties = GATT_CHARACTER_PROPERTY_BIT_READ;
character.value_len = (uint16_t)sizeof(hid_information_val);
character.value = hid_information_val;
gatts_add_characteristic(server_id, srvc_handle, &character);
}
// /* 添加特征HID report map */
static void tjd_ble_hid_add_character_report_map(uint8_t server_id, uint16_t srvc_handle)
{
gatts_add_chara_info_t character;
bts_data_to_uuid_len2(BLE_UUID_REPORT_MAP, &character.chara_uuid);
character.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_AUTHENTICATION_NEED;
character.properties = HID_REPORT_MAP_PROPERTIES;
character.value_len = (uint16_t)sizeof(tjd_srv_hid_report_map);
character.value = tjd_srv_hid_report_map;
gatts_add_characteristic(server_id, srvc_handle, &character);
}
// /* 添加特征HID control point */
static void tjd_ble_hid_add_character_hid_control_point(uint8_t server_id, uint16_t srvc_handle)
{
/* HID control point value for test */
static uint8_t control_point_val[] = {0x00, 0x00};
gatts_add_chara_info_t character;
bts_data_to_uuid_len2(BLE_UUID_HID_CONTROL_POINT, &character.chara_uuid);
character.permissions = GATT_ATTRIBUTE_PERMISSION_READ;
character.properties = HID_CONTROL_POINT_PROPERTIES;
character.value_len = (uint16_t)sizeof(control_point_val);
character.value = control_point_val;
gatts_add_characteristic(server_id, srvc_handle, &character);
}
// /* 添加描述符:客户端特性配置 */
static void tjd_ble_hid_add_descriptor_ccc(uint8_t server_id, uint16_t srvc_handle)
{
/* HID client characteristic configuration value for test */
static uint8_t ccc_val[] = {0x00, 0x00};
gatts_add_desc_info_t descriptor;
bts_data_to_uuid_len2(BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION, &descriptor.desc_uuid);
descriptor.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE;
descriptor.value_len = (uint16_t)sizeof(ccc_val);
descriptor.value = ccc_val;
gatts_add_descriptor(server_id, srvc_handle, &descriptor);
}
// /* 添加描述符HID report reference */
static void tjd_ble_hid_add_descriptor_report_reference(uint8_t server_id, uint16_t srvc_handle, bool is_input_flag)
{
/* HID output report reference value for test [report id 1, output] */
static uint8_t report_reference_val_output[] = {BLE_HID_REPORT_ID, BLE_REPORT_REFERENCE_REPORT_TYPE_OUTPUT_REPORT};
/* HID input report reference value for test [report id 1, input] */
static uint8_t report_reference_val_input[] = {BLE_HID_REPORT_ID, BLE_REPORT_REFERENCE_REPORT_TYPE_INPUT_REPORT,
BLE_HID_REPORT_ID_2,BLE_REPORT_REFERENCE_REPORT_TYPE_INPUT_REPORT,
BLE_HID_REPORT_ID_3,BLE_REPORT_REFERENCE_REPORT_TYPE_INPUT_REPORT};
gatts_add_desc_info_t descriptor;
bts_data_to_uuid_len2(BLE_UUID_REPORT_REFERENCE, &descriptor.desc_uuid);
descriptor.permissions = GATT_ATTRIBUTE_PERMISSION_READ;
if (is_input_flag) {
descriptor.value = report_reference_val_input;
descriptor.value_len = (uint16_t)sizeof(report_reference_val_input);
} else {
descriptor.value = report_reference_val_output;
descriptor.value_len = (uint16_t)sizeof(report_reference_val_output);
}
gatts_add_descriptor(server_id, srvc_handle, &descriptor);
}
// /* 添加特征HID input report(device to host) */
static void tjd_ble_hid_add_character_input_report(uint8_t server_id, uint16_t srvc_handle)
{
// static uint8_t input_report_value[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static uint8_t input_report_value[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
gatts_add_chara_info_t character;
bts_data_to_uuid_len2(BLE_UUID_REPORT, &character.chara_uuid);
character.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE;
character.properties = HID_INPUT_REPORT_PROPERTIES;
// character.properties =
// GATT_CHARACTER_PROPERTY_BIT_READ | GATT_CHARACTER_PROPERTY_BIT_NOTIFY | GATT_CHARACTER_PROPERTY_BIT_WRITE;
character.value_len = (uint16_t)sizeof(input_report_value);
character.value = input_report_value;
gatts_add_characteristic(server_id, srvc_handle, &character);
tjd_ble_hid_add_descriptor_ccc(server_id, srvc_handle);
tjd_ble_hid_add_descriptor_report_reference(server_id, srvc_handle, true);
}
// /* 添加特征HID output report(host to device) */
static void tjd_ble_hid_add_character_output_report(uint8_t server_id, uint16_t srvc_handle)
{
/* HID output report value for test */
static uint8_t output_report_value[] = {0x00};
gatts_add_chara_info_t character;
bts_data_to_uuid_len2(BLE_UUID_REPORT, &character.chara_uuid);
character.permissions = GATT_ATTRIBUTE_PERMISSION_READ;
character.properties = HID_OUTPUT_REPORT_PROPERTIES;
character.value_len = (uint16_t)sizeof(output_report_value);
character.value = output_report_value;
gatts_add_characteristic(server_id, srvc_handle, &character);
tjd_ble_hid_add_descriptor_report_reference(server_id, srvc_handle, false);
}
// /* 添加特征HID protocol mode */
static void tjd_ble_hid_add_character_protocol_mode(uint8_t server_id, uint16_t srvc_handle)
{
/* HID protocol mode value for test */
static uint8_t protocol_mode_val[] = {0x00, 0x00};
// static uint8_t protocol_mode_val[] = {0x00,0x01};
gatts_add_chara_info_t character;
bts_data_to_uuid_len2(BLE_UUID_PROTOCOL_MODE, &character.chara_uuid);
character.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE;
character.properties = HID_PROTOCOL_MODE_PROPERTIES;
character.value_len = (uint16_t)sizeof(protocol_mode_val);
character.value = protocol_mode_val;
gatts_add_characteristic(server_id, srvc_handle, &character);
}
// /* 添加HID服务的所有特征和描述符 */
void tjd_ble_hid_add_characters_and_descriptors(uint8_t server_id, uint16_t srvc_handle)
{
/* HID Information */
tjd_ble_hid_add_character_hid_information(server_id, srvc_handle);
/* Report Map */
tjd_ble_hid_add_character_report_map(server_id, srvc_handle);
/* Protocol Mode */
tjd_ble_hid_add_character_protocol_mode(server_id, srvc_handle);
/* Input Report */
tjd_ble_hid_add_character_input_report(server_id, srvc_handle);
/* Output Report */
tjd_ble_hid_add_character_output_report(server_id, srvc_handle);
/* HID Control Point */
tjd_ble_hid_add_character_hid_control_point(server_id, srvc_handle);
}