474 lines
20 KiB
C
474 lines
20 KiB
C
#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);
|
||
} |