2018-03-09 08:25:23 +00:00
|
|
|
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
#include "hidd_le_prf_int.h"
|
|
|
|
#include <string.h>
|
2018-04-26 12:02:14 +00:00
|
|
|
#include "esp_log.h"
|
2018-03-09 08:25:23 +00:00
|
|
|
|
|
|
|
/// characteristic presentation information
|
|
|
|
struct prf_char_pres_fmt
|
|
|
|
{
|
|
|
|
/// Unit (The Unit is a UUID)
|
|
|
|
uint16_t unit;
|
|
|
|
/// Description
|
|
|
|
uint16_t description;
|
|
|
|
/// Format
|
|
|
|
uint8_t format;
|
|
|
|
/// Exponent
|
|
|
|
uint8_t exponent;
|
|
|
|
/// Name space
|
|
|
|
uint8_t name_space;
|
|
|
|
};
|
|
|
|
|
|
|
|
// HID report mapping table
|
|
|
|
static hid_report_map_t hid_rpt_map[HID_NUM_REPORTS];
|
|
|
|
|
|
|
|
// HID Report Map characteristic value
|
|
|
|
// Keyboard report descriptor (using format for Boot interface descriptor)
|
|
|
|
static const uint8_t hidReportMap[] = {
|
|
|
|
0x05, 0x01, // Usage Page (Generic Desktop)
|
|
|
|
0x09, 0x02, // Usage (Mouse)
|
|
|
|
0xA1, 0x01, // Collection (Application)
|
|
|
|
0x85, 0x01, // Report Id (1)
|
|
|
|
0x09, 0x01, // Usage (Pointer)
|
|
|
|
0xA1, 0x00, // Collection (Physical)
|
|
|
|
0x05, 0x09, // Usage Page (Buttons)
|
|
|
|
0x19, 0x01, // Usage Minimum (01) - Button 1
|
|
|
|
0x29, 0x03, // Usage Maximum (03) - Button 3
|
|
|
|
0x15, 0x00, // Logical Minimum (0)
|
|
|
|
0x25, 0x01, // Logical Maximum (1)
|
|
|
|
0x75, 0x01, // Report Size (1)
|
|
|
|
0x95, 0x03, // Report Count (3)
|
|
|
|
0x81, 0x02, // Input (Data, Variable, Absolute) - Button states
|
|
|
|
0x75, 0x05, // Report Size (5)
|
|
|
|
0x95, 0x01, // Report Count (1)
|
|
|
|
0x81, 0x01, // Input (Constant) - Padding or Reserved bits
|
|
|
|
0x05, 0x01, // Usage Page (Generic Desktop)
|
|
|
|
0x09, 0x30, // Usage (X)
|
|
|
|
0x09, 0x31, // Usage (Y)
|
|
|
|
0x09, 0x38, // Usage (Wheel)
|
|
|
|
0x15, 0x81, // Logical Minimum (-127)
|
|
|
|
0x25, 0x7F, // Logical Maximum (127)
|
|
|
|
0x75, 0x08, // Report Size (8)
|
|
|
|
0x95, 0x03, // Report Count (3)
|
|
|
|
0x81, 0x06, // Input (Data, Variable, Relative) - X & Y coordinate
|
|
|
|
0xC0, // End Collection
|
|
|
|
0xC0, // End Collection
|
|
|
|
|
|
|
|
0x05, 0x01, // Usage Pg (Generic Desktop)
|
|
|
|
0x09, 0x06, // Usage (Keyboard)
|
|
|
|
0xA1, 0x01, // Collection: (Application)
|
|
|
|
0x85, 0x02, // Report Id (2)
|
|
|
|
//
|
|
|
|
0x05, 0x07, // Usage Pg (Key Codes)
|
|
|
|
0x19, 0xE0, // Usage Min (224)
|
|
|
|
0x29, 0xE7, // Usage Max (231)
|
|
|
|
0x15, 0x00, // Log Min (0)
|
|
|
|
0x25, 0x01, // Log Max (1)
|
|
|
|
//
|
|
|
|
// Modifier byte
|
|
|
|
0x75, 0x01, // Report Size (1)
|
|
|
|
0x95, 0x08, // Report Count (8)
|
|
|
|
0x81, 0x02, // Input: (Data, Variable, Absolute)
|
|
|
|
//
|
|
|
|
// Reserved byte
|
|
|
|
0x95, 0x01, // Report Count (1)
|
|
|
|
0x75, 0x08, // Report Size (8)
|
|
|
|
0x81, 0x01, // Input: (Constant)
|
|
|
|
//
|
|
|
|
// LED report
|
|
|
|
0x95, 0x05, // Report Count (5)
|
|
|
|
0x75, 0x01, // Report Size (1)
|
|
|
|
0x05, 0x08, // Usage Pg (LEDs)
|
|
|
|
0x19, 0x01, // Usage Min (1)
|
|
|
|
0x29, 0x05, // Usage Max (5)
|
|
|
|
0x91, 0x02, // Output: (Data, Variable, Absolute)
|
|
|
|
//
|
|
|
|
// LED report padding
|
|
|
|
0x95, 0x01, // Report Count (1)
|
|
|
|
0x75, 0x03, // Report Size (3)
|
|
|
|
0x91, 0x01, // Output: (Constant)
|
|
|
|
//
|
|
|
|
// Key arrays (6 bytes)
|
|
|
|
0x95, 0x06, // Report Count (6)
|
|
|
|
0x75, 0x08, // Report Size (8)
|
|
|
|
0x15, 0x00, // Log Min (0)
|
|
|
|
0x25, 0x65, // Log Max (101)
|
|
|
|
0x05, 0x07, // Usage Pg (Key Codes)
|
|
|
|
0x19, 0x00, // Usage Min (0)
|
|
|
|
0x29, 0x65, // Usage Max (101)
|
|
|
|
0x81, 0x00, // Input: (Data, Array)
|
|
|
|
//
|
|
|
|
0xC0, // End Collection
|
|
|
|
//
|
|
|
|
0x05, 0x0C, // Usage Pg (Consumer Devices)
|
|
|
|
0x09, 0x01, // Usage (Consumer Control)
|
|
|
|
0xA1, 0x01, // Collection (Application)
|
|
|
|
0x85, 0x03, // Report Id (3)
|
|
|
|
0x09, 0x02, // Usage (Numeric Key Pad)
|
|
|
|
0xA1, 0x02, // Collection (Logical)
|
|
|
|
0x05, 0x09, // Usage Pg (Button)
|
|
|
|
0x19, 0x01, // Usage Min (Button 1)
|
|
|
|
0x29, 0x0A, // Usage Max (Button 10)
|
|
|
|
0x15, 0x01, // Logical Min (1)
|
|
|
|
0x25, 0x0A, // Logical Max (10)
|
|
|
|
0x75, 0x04, // Report Size (4)
|
|
|
|
0x95, 0x01, // Report Count (1)
|
|
|
|
0x81, 0x00, // Input (Data, Ary, Abs)
|
|
|
|
0xC0, // End Collection
|
|
|
|
0x05, 0x0C, // Usage Pg (Consumer Devices)
|
|
|
|
0x09, 0x86, // Usage (Channel)
|
|
|
|
0x15, 0xFF, // Logical Min (-1)
|
|
|
|
0x25, 0x01, // Logical Max (1)
|
|
|
|
0x75, 0x02, // Report Size (2)
|
|
|
|
0x95, 0x01, // Report Count (1)
|
|
|
|
0x81, 0x46, // Input (Data, Var, Rel, Null)
|
|
|
|
0x09, 0xE9, // Usage (Volume Up)
|
|
|
|
0x09, 0xEA, // Usage (Volume Down)
|
|
|
|
0x15, 0x00, // Logical Min (0)
|
|
|
|
0x75, 0x01, // Report Size (1)
|
|
|
|
0x95, 0x02, // Report Count (2)
|
|
|
|
0x81, 0x02, // Input (Data, Var, Abs)
|
|
|
|
0x09, 0xE2, // Usage (Mute)
|
|
|
|
0x09, 0x30, // Usage (Power)
|
|
|
|
0x09, 0x83, // Usage (Recall Last)
|
|
|
|
0x09, 0x81, // Usage (Assign Selection)
|
|
|
|
0x09, 0xB0, // Usage (Play)
|
|
|
|
0x09, 0xB1, // Usage (Pause)
|
|
|
|
0x09, 0xB2, // Usage (Record)
|
|
|
|
0x09, 0xB3, // Usage (Fast Forward)
|
|
|
|
0x09, 0xB4, // Usage (Rewind)
|
|
|
|
0x09, 0xB5, // Usage (Scan Next)
|
|
|
|
0x09, 0xB6, // Usage (Scan Prev)
|
|
|
|
0x09, 0xB7, // Usage (Stop)
|
|
|
|
0x15, 0x01, // Logical Min (1)
|
|
|
|
0x25, 0x0C, // Logical Max (12)
|
|
|
|
0x75, 0x04, // Report Size (4)
|
|
|
|
0x95, 0x01, // Report Count (1)
|
|
|
|
0x81, 0x00, // Input (Data, Ary, Abs)
|
|
|
|
0x09, 0x80, // Usage (Selection)
|
|
|
|
0xA1, 0x02, // Collection (Logical)
|
|
|
|
0x05, 0x09, // Usage Pg (Button)
|
|
|
|
0x19, 0x01, // Usage Min (Button 1)
|
|
|
|
0x29, 0x03, // Usage Max (Button 3)
|
|
|
|
0x15, 0x01, // Logical Min (1)
|
|
|
|
0x25, 0x03, // Logical Max (3)
|
|
|
|
0x75, 0x02, // Report Size (2)
|
|
|
|
0x81, 0x00, // Input (Data, Ary, Abs)
|
|
|
|
0xC0, // End Collection
|
|
|
|
0x81, 0x03, // Input (Const, Var, Abs)
|
2019-02-28 12:39:12 +00:00
|
|
|
0xC0, // End Collectionq
|
|
|
|
|
|
|
|
#if (SUPPORT_REPORT_VENDOR == true)
|
2018-03-09 08:25:23 +00:00
|
|
|
0x06, 0xFF, 0xFF, // Usage Page(Vendor defined)
|
|
|
|
0x09, 0xA5, // Usage(Vendor Defined)
|
|
|
|
0xA1, 0x01, // Collection(Application)
|
|
|
|
0x85, 0x04, // Report Id (4)
|
|
|
|
0x09, 0xA6, // Usage(Vendor defined)
|
|
|
|
0x09, 0xA9, // Usage(Vendor defined)
|
|
|
|
0x75, 0x08, // Report Size
|
|
|
|
0x95, 0x7F, // Report Count = 127 Btyes
|
|
|
|
0x91, 0x02, // Output(Data, Variable, Absolute)
|
|
|
|
0xC0, // End Collection
|
2019-02-28 12:39:12 +00:00
|
|
|
#endif
|
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Battery Service Attributes Indexes
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
BAS_IDX_SVC,
|
|
|
|
|
|
|
|
BAS_IDX_BATT_LVL_CHAR,
|
|
|
|
BAS_IDX_BATT_LVL_VAL,
|
|
|
|
BAS_IDX_BATT_LVL_NTF_CFG,
|
|
|
|
BAS_IDX_BATT_LVL_PRES_FMT,
|
|
|
|
|
|
|
|
BAS_IDX_NB,
|
|
|
|
};
|
|
|
|
|
|
|
|
#define HI_UINT16(a) (((a) >> 8) & 0xFF)
|
|
|
|
#define LO_UINT16(a) ((a) & 0xFF)
|
2018-07-31 07:20:27 +00:00
|
|
|
#define PROFILE_NUM 1
|
|
|
|
#define PROFILE_APP_IDX 0
|
|
|
|
|
|
|
|
struct gatts_profile_inst {
|
|
|
|
esp_gatts_cb_t gatts_cb;
|
|
|
|
uint16_t gatts_if;
|
|
|
|
uint16_t app_id;
|
|
|
|
uint16_t conn_id;
|
|
|
|
};
|
2018-03-09 08:25:23 +00:00
|
|
|
|
|
|
|
hidd_le_env_t hidd_le_env;
|
|
|
|
|
|
|
|
// HID report map length
|
|
|
|
uint8_t hidReportMapLen = sizeof(hidReportMap);
|
|
|
|
uint8_t hidProtocolMode = HID_PROTOCOL_MODE_REPORT;
|
|
|
|
|
|
|
|
// HID report mapping table
|
|
|
|
//static hidRptMap_t hidRptMap[HID_NUM_REPORTS];
|
|
|
|
|
|
|
|
// HID Information characteristic value
|
|
|
|
static const uint8_t hidInfo[HID_INFORMATION_LEN] = {
|
|
|
|
LO_UINT16(0x0111), HI_UINT16(0x0111), // bcdHID (USB HID version)
|
|
|
|
0x00, // bCountryCode
|
|
|
|
HID_KBD_FLAGS // Flags
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// HID External Report Reference Descriptor
|
|
|
|
static uint16_t hidExtReportRefDesc = ESP_GATT_UUID_BATTERY_LEVEL;
|
|
|
|
|
|
|
|
// HID Report Reference characteristic descriptor, mouse input
|
|
|
|
static uint8_t hidReportRefMouseIn[HID_REPORT_REF_LEN] =
|
|
|
|
{ HID_RPT_ID_MOUSE_IN, HID_REPORT_TYPE_INPUT };
|
|
|
|
|
|
|
|
|
|
|
|
// HID Report Reference characteristic descriptor, key input
|
|
|
|
static uint8_t hidReportRefKeyIn[HID_REPORT_REF_LEN] =
|
|
|
|
{ HID_RPT_ID_KEY_IN, HID_REPORT_TYPE_INPUT };
|
|
|
|
|
|
|
|
// HID Report Reference characteristic descriptor, LED output
|
|
|
|
static uint8_t hidReportRefLedOut[HID_REPORT_REF_LEN] =
|
|
|
|
{ HID_RPT_ID_LED_OUT, HID_REPORT_TYPE_OUTPUT };
|
|
|
|
|
2019-02-28 12:39:12 +00:00
|
|
|
#if (SUPPORT_REPORT_VENDOR == true)
|
|
|
|
|
2018-06-26 09:48:07 +00:00
|
|
|
static uint8_t hidReportRefVendorOut[HID_REPORT_REF_LEN] =
|
2018-03-09 08:25:23 +00:00
|
|
|
{HID_RPT_ID_VENDOR_OUT, HID_REPORT_TYPE_OUTPUT};
|
2019-02-28 12:39:12 +00:00
|
|
|
#endif
|
2018-03-09 08:25:23 +00:00
|
|
|
|
|
|
|
// HID Report Reference characteristic descriptor, Feature
|
|
|
|
static uint8_t hidReportRefFeature[HID_REPORT_REF_LEN] =
|
|
|
|
{ HID_RPT_ID_FEATURE, HID_REPORT_TYPE_FEATURE };
|
|
|
|
|
|
|
|
// HID Report Reference characteristic descriptor, consumer control input
|
|
|
|
static uint8_t hidReportRefCCIn[HID_REPORT_REF_LEN] =
|
|
|
|
{ HID_RPT_ID_CC_IN, HID_REPORT_TYPE_INPUT };
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Heart Rate PROFILE ATTRIBUTES
|
|
|
|
****************************************************************************************
|
|
|
|
*/
|
|
|
|
|
|
|
|
/// hid Service uuid
|
|
|
|
static uint16_t hid_le_svc = ATT_SVC_HID;
|
|
|
|
uint16_t hid_count = 0;
|
|
|
|
esp_gatts_incl_svc_desc_t incl_svc = {0};
|
|
|
|
|
|
|
|
#define CHAR_DECLARATION_SIZE (sizeof(uint8_t))
|
|
|
|
///the uuid definition
|
|
|
|
static const uint16_t primary_service_uuid = ESP_GATT_UUID_PRI_SERVICE;
|
|
|
|
static const uint16_t include_service_uuid = ESP_GATT_UUID_INCLUDE_SERVICE;
|
|
|
|
static const uint16_t character_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE;
|
|
|
|
static const uint16_t character_client_config_uuid = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
|
|
|
|
static const uint16_t hid_info_char_uuid = ESP_GATT_UUID_HID_INFORMATION;
|
|
|
|
static const uint16_t hid_report_map_uuid = ESP_GATT_UUID_HID_REPORT_MAP;
|
|
|
|
static const uint16_t hid_control_point_uuid = ESP_GATT_UUID_HID_CONTROL_POINT;
|
|
|
|
static const uint16_t hid_report_uuid = ESP_GATT_UUID_HID_REPORT;
|
|
|
|
static const uint16_t hid_proto_mode_uuid = ESP_GATT_UUID_HID_PROTO_MODE;
|
|
|
|
static const uint16_t hid_kb_input_uuid = ESP_GATT_UUID_HID_BT_KB_INPUT;
|
|
|
|
static const uint16_t hid_kb_output_uuid = ESP_GATT_UUID_HID_BT_KB_OUTPUT;
|
|
|
|
static const uint16_t hid_mouse_input_uuid = ESP_GATT_UUID_HID_BT_MOUSE_INPUT;
|
|
|
|
static const uint16_t hid_repot_map_ext_desc_uuid = ESP_GATT_UUID_EXT_RPT_REF_DESCR;
|
|
|
|
static const uint16_t hid_report_ref_descr_uuid = ESP_GATT_UUID_RPT_REF_DESCR;
|
|
|
|
///the propoty definition
|
|
|
|
static const uint8_t char_prop_notify = ESP_GATT_CHAR_PROP_BIT_NOTIFY;
|
|
|
|
static const uint8_t char_prop_read = ESP_GATT_CHAR_PROP_BIT_READ;
|
2018-06-26 09:48:07 +00:00
|
|
|
static const uint8_t char_prop_write_nr = ESP_GATT_CHAR_PROP_BIT_WRITE_NR;
|
2018-03-09 08:25:23 +00:00
|
|
|
static const uint8_t char_prop_read_write = ESP_GATT_CHAR_PROP_BIT_WRITE|ESP_GATT_CHAR_PROP_BIT_READ;
|
|
|
|
static const uint8_t char_prop_read_notify = ESP_GATT_CHAR_PROP_BIT_READ|ESP_GATT_CHAR_PROP_BIT_NOTIFY;
|
|
|
|
static const uint8_t char_prop_read_write_notify = ESP_GATT_CHAR_PROP_BIT_READ|ESP_GATT_CHAR_PROP_BIT_WRITE|ESP_GATT_CHAR_PROP_BIT_NOTIFY;
|
|
|
|
|
|
|
|
/// battary Service
|
|
|
|
static const uint16_t battary_svc = ESP_GATT_UUID_BATTERY_SERVICE_SVC;
|
|
|
|
|
|
|
|
static const uint16_t bat_lev_uuid = ESP_GATT_UUID_BATTERY_LEVEL;
|
|
|
|
static const uint8_t bat_lev_ccc[2] ={ 0x00, 0x00};
|
|
|
|
static const uint16_t char_format_uuid = ESP_GATT_UUID_CHAR_PRESENT_FORMAT;
|
|
|
|
|
|
|
|
static uint8_t battary_lev = 50;
|
|
|
|
/// Full HRS Database Description - Used to add attributes into the database
|
|
|
|
static const esp_gatts_attr_db_t bas_att_db[BAS_IDX_NB] =
|
|
|
|
{
|
|
|
|
// Battary Service Declaration
|
|
|
|
[BAS_IDX_SVC] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&primary_service_uuid, ESP_GATT_PERM_READ,
|
|
|
|
sizeof(uint16_t), sizeof(battary_svc), (uint8_t *)&battary_svc}},
|
|
|
|
|
|
|
|
// Battary level Characteristic Declaration
|
|
|
|
[BAS_IDX_BATT_LVL_CHAR] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ,
|
|
|
|
CHAR_DECLARATION_SIZE,CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_notify}},
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
// Battary level Characteristic Value
|
|
|
|
[BAS_IDX_BATT_LVL_VAL] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&bat_lev_uuid, ESP_GATT_PERM_READ,
|
|
|
|
sizeof(uint8_t),sizeof(uint8_t), &battary_lev}},
|
|
|
|
|
|
|
|
// Battary level Characteristic - Client Characteristic Configuration Descriptor
|
|
|
|
[BAS_IDX_BATT_LVL_NTF_CFG] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE,
|
|
|
|
sizeof(uint16_t),sizeof(bat_lev_ccc), (uint8_t *)bat_lev_ccc}},
|
|
|
|
|
|
|
|
// Battary level report Characteristic Declaration
|
|
|
|
[BAS_IDX_BATT_LVL_PRES_FMT] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&char_format_uuid, ESP_GATT_PERM_READ,
|
|
|
|
sizeof(struct prf_char_pres_fmt), 0, NULL}},
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// Full Hid device Database Description - Used to add attributes into the database
|
|
|
|
static esp_gatts_attr_db_t hidd_le_gatt_db[HIDD_LE_IDX_NB] =
|
|
|
|
{
|
|
|
|
// HID Service Declaration
|
2018-06-26 09:48:07 +00:00
|
|
|
[HIDD_LE_IDX_SVC] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&primary_service_uuid,
|
|
|
|
ESP_GATT_PERM_READ_ENCRYPTED, sizeof(uint16_t), sizeof(hid_le_svc),
|
2018-03-09 08:25:23 +00:00
|
|
|
(uint8_t *)&hid_le_svc}},
|
|
|
|
|
|
|
|
// HID Service Declaration
|
|
|
|
[HIDD_LE_IDX_INCL_SVC] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&include_service_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
sizeof(esp_gatts_incl_svc_desc_t), sizeof(esp_gatts_incl_svc_desc_t),
|
|
|
|
(uint8_t *)&incl_svc}},
|
|
|
|
|
|
|
|
// HID Information Characteristic Declaration
|
|
|
|
[HIDD_LE_IDX_HID_INFO_CHAR] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE,
|
2018-06-26 09:48:07 +00:00
|
|
|
(uint8_t *)&char_prop_read}},
|
2018-03-09 08:25:23 +00:00
|
|
|
// HID Information Characteristic Value
|
|
|
|
[HIDD_LE_IDX_HID_INFO_VAL] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_info_char_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
sizeof(hids_hid_info_t), sizeof(hidInfo),
|
|
|
|
(uint8_t *)&hidInfo}},
|
|
|
|
|
|
|
|
// HID Control Point Characteristic Declaration
|
|
|
|
[HIDD_LE_IDX_HID_CTNL_PT_CHAR] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE,
|
2018-06-26 09:48:07 +00:00
|
|
|
(uint8_t *)&char_prop_write_nr}},
|
2018-03-09 08:25:23 +00:00
|
|
|
// HID Control Point Characteristic Value
|
|
|
|
[HIDD_LE_IDX_HID_CTNL_PT_VAL] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_control_point_uuid,
|
|
|
|
ESP_GATT_PERM_WRITE,
|
|
|
|
sizeof(uint8_t), 0,
|
|
|
|
NULL}},
|
|
|
|
|
|
|
|
// Report Map Characteristic Declaration
|
|
|
|
[HIDD_LE_IDX_REPORT_MAP_CHAR] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE,
|
|
|
|
(uint8_t *)&char_prop_read}},
|
|
|
|
// Report Map Characteristic Value
|
|
|
|
[HIDD_LE_IDX_REPORT_MAP_VAL] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_report_map_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
HIDD_LE_REPORT_MAP_MAX_LEN, sizeof(hidReportMap),
|
|
|
|
(uint8_t *)&hidReportMap}},
|
|
|
|
|
|
|
|
// Report Map Characteristic - External Report Reference Descriptor
|
|
|
|
[HIDD_LE_IDX_REPORT_MAP_EXT_REP_REF] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_repot_map_ext_desc_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
sizeof(uint16_t), sizeof(uint16_t),
|
|
|
|
(uint8_t *)&hidExtReportRefDesc}},
|
|
|
|
|
|
|
|
// Protocol Mode Characteristic Declaration
|
|
|
|
[HIDD_LE_IDX_PROTO_MODE_CHAR] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE,
|
|
|
|
(uint8_t *)&char_prop_read_write}},
|
|
|
|
// Protocol Mode Characteristic Value
|
|
|
|
[HIDD_LE_IDX_PROTO_MODE_VAL] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_proto_mode_uuid,
|
|
|
|
(ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE),
|
|
|
|
sizeof(uint8_t), sizeof(hidProtocolMode),
|
|
|
|
(uint8_t *)&hidProtocolMode}},
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
[HIDD_LE_IDX_REPORT_MOUSE_IN_CHAR] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE,
|
|
|
|
(uint8_t *)&char_prop_read_notify}},
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
[HIDD_LE_IDX_REPORT_MOUSE_IN_VAL] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_report_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
HIDD_LE_REPORT_MAX_LEN, 0,
|
|
|
|
NULL}},
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
[HIDD_LE_IDX_REPORT_MOUSE_IN_CCC] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid,
|
|
|
|
(ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE),
|
|
|
|
sizeof(uint16_t), 0,
|
|
|
|
NULL}},
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
[HIDD_LE_IDX_REPORT_MOUSE_REP_REF] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_report_ref_descr_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
sizeof(hidReportRefMouseIn), sizeof(hidReportRefMouseIn),
|
|
|
|
hidReportRefMouseIn}},
|
|
|
|
// Report Characteristic Declaration
|
|
|
|
[HIDD_LE_IDX_REPORT_KEY_IN_CHAR] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE,
|
|
|
|
(uint8_t *)&char_prop_read_notify}},
|
|
|
|
// Report Characteristic Value
|
|
|
|
[HIDD_LE_IDX_REPORT_KEY_IN_VAL] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_report_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
HIDD_LE_REPORT_MAX_LEN, 0,
|
|
|
|
NULL}},
|
|
|
|
// Report KEY INPUT Characteristic - Client Characteristic Configuration Descriptor
|
|
|
|
[HIDD_LE_IDX_REPORT_KEY_IN_CCC] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid,
|
|
|
|
(ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE),
|
|
|
|
sizeof(uint16_t), 0,
|
|
|
|
NULL}},
|
|
|
|
// Report Characteristic - Report Reference Descriptor
|
|
|
|
[HIDD_LE_IDX_REPORT_KEY_IN_REP_REF] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_report_ref_descr_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
sizeof(hidReportRefKeyIn), sizeof(hidReportRefKeyIn),
|
|
|
|
hidReportRefKeyIn}},
|
|
|
|
|
|
|
|
// Report Characteristic Declaration
|
|
|
|
[HIDD_LE_IDX_REPORT_LED_OUT_CHAR] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE,
|
|
|
|
(uint8_t *)&char_prop_read_write}},
|
|
|
|
|
|
|
|
[HIDD_LE_IDX_REPORT_LED_OUT_VAL] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_report_uuid,
|
|
|
|
ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE,
|
|
|
|
HIDD_LE_REPORT_MAX_LEN, 0,
|
|
|
|
NULL}},
|
|
|
|
[HIDD_LE_IDX_REPORT_LED_OUT_REP_REF] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_report_ref_descr_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
sizeof(hidReportRefLedOut), sizeof(hidReportRefLedOut),
|
|
|
|
hidReportRefLedOut}},
|
2019-02-28 12:39:12 +00:00
|
|
|
#if (SUPPORT_REPORT_VENDOR == true)
|
2018-03-09 08:25:23 +00:00
|
|
|
// Report Characteristic Declaration
|
|
|
|
[HIDD_LE_IDX_REPORT_VENDOR_OUT_CHAR] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE,
|
|
|
|
(uint8_t *)&char_prop_read_write_notify}},
|
|
|
|
[HIDD_LE_IDX_REPORT_VENDOR_OUT_VAL] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_report_uuid,
|
|
|
|
ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE,
|
|
|
|
HIDD_LE_REPORT_MAX_LEN, 0,
|
|
|
|
NULL}},
|
|
|
|
[HIDD_LE_IDX_REPORT_VENDOR_OUT_REP_REF] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_report_ref_descr_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
sizeof(hidReportRefVendorOut), sizeof(hidReportRefVendorOut),
|
|
|
|
hidReportRefVendorOut}},
|
2019-02-28 12:39:12 +00:00
|
|
|
#endif
|
|
|
|
// Report Characteristic Declaration
|
2018-03-09 08:25:23 +00:00
|
|
|
[HIDD_LE_IDX_REPORT_CC_IN_CHAR] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE,
|
|
|
|
(uint8_t *)&char_prop_read_notify}},
|
|
|
|
// Report Characteristic Value
|
|
|
|
[HIDD_LE_IDX_REPORT_CC_IN_VAL] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_report_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
HIDD_LE_REPORT_MAX_LEN, 0,
|
|
|
|
NULL}},
|
|
|
|
// Report KEY INPUT Characteristic - Client Characteristic Configuration Descriptor
|
|
|
|
[HIDD_LE_IDX_REPORT_CC_IN_CCC] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid,
|
2019-02-28 12:39:12 +00:00
|
|
|
(ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE_ENCRYPTED),
|
2018-03-09 08:25:23 +00:00
|
|
|
sizeof(uint16_t), 0,
|
|
|
|
NULL}},
|
|
|
|
// Report Characteristic - Report Reference Descriptor
|
|
|
|
[HIDD_LE_IDX_REPORT_CC_IN_REP_REF] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_report_ref_descr_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
sizeof(hidReportRefCCIn), sizeof(hidReportRefCCIn),
|
|
|
|
hidReportRefCCIn}},
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
// Boot Keyboard Input Report Characteristic Declaration
|
|
|
|
[HIDD_LE_IDX_BOOT_KB_IN_REPORT_CHAR] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE,
|
|
|
|
(uint8_t *)&char_prop_read_notify}},
|
|
|
|
// Boot Keyboard Input Report Characteristic Value
|
|
|
|
[HIDD_LE_IDX_BOOT_KB_IN_REPORT_VAL] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_kb_input_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
HIDD_LE_BOOT_REPORT_MAX_LEN, 0,
|
|
|
|
NULL}},
|
|
|
|
// Boot Keyboard Input Report Characteristic - Client Characteristic Configuration Descriptor
|
|
|
|
[HIDD_LE_IDX_BOOT_KB_IN_REPORT_NTF_CFG] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid,
|
|
|
|
(ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE),
|
|
|
|
sizeof(uint16_t), 0,
|
|
|
|
NULL}},
|
|
|
|
|
|
|
|
// Boot Keyboard Output Report Characteristic Declaration
|
|
|
|
[HIDD_LE_IDX_BOOT_KB_OUT_REPORT_CHAR] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE,
|
|
|
|
(uint8_t *)&char_prop_read_write}},
|
|
|
|
// Boot Keyboard Output Report Characteristic Value
|
|
|
|
[HIDD_LE_IDX_BOOT_KB_OUT_REPORT_VAL] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_kb_output_uuid,
|
|
|
|
(ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE),
|
|
|
|
HIDD_LE_BOOT_REPORT_MAX_LEN, 0,
|
|
|
|
NULL}},
|
|
|
|
|
|
|
|
// Boot Mouse Input Report Characteristic Declaration
|
|
|
|
[HIDD_LE_IDX_BOOT_MOUSE_IN_REPORT_CHAR] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE,
|
|
|
|
(uint8_t *)&char_prop_read_notify}},
|
|
|
|
// Boot Mouse Input Report Characteristic Value
|
|
|
|
[HIDD_LE_IDX_BOOT_MOUSE_IN_REPORT_VAL] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_mouse_input_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
HIDD_LE_BOOT_REPORT_MAX_LEN, 0,
|
|
|
|
NULL}},
|
|
|
|
// Boot Mouse Input Report Characteristic - Client Characteristic Configuration Descriptor
|
|
|
|
[HIDD_LE_IDX_BOOT_MOUSE_IN_REPORT_NTF_CFG] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid,
|
|
|
|
(ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE),
|
|
|
|
sizeof(uint16_t), 0,
|
|
|
|
NULL}},
|
|
|
|
|
|
|
|
// Report Characteristic Declaration
|
|
|
|
[HIDD_LE_IDX_REPORT_CHAR] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE,
|
|
|
|
(uint8_t *)&char_prop_read_write}},
|
|
|
|
// Report Characteristic Value
|
|
|
|
[HIDD_LE_IDX_REPORT_VAL] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_report_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
HIDD_LE_REPORT_MAX_LEN, 0,
|
|
|
|
NULL}},
|
|
|
|
// Report Characteristic - Report Reference Descriptor
|
|
|
|
[HIDD_LE_IDX_REPORT_REP_REF] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&hid_report_ref_descr_uuid,
|
|
|
|
ESP_GATT_PERM_READ,
|
|
|
|
sizeof(hidReportRefFeature), sizeof(hidReportRefFeature),
|
|
|
|
hidReportRefFeature}},
|
|
|
|
};
|
|
|
|
|
|
|
|
static void hid_add_id_tbl(void);
|
|
|
|
|
2018-06-26 09:48:07 +00:00
|
|
|
void esp_hidd_prf_cb_hdl(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
2018-03-09 08:25:23 +00:00
|
|
|
esp_ble_gatts_cb_param_t *param)
|
|
|
|
{
|
|
|
|
switch(event) {
|
|
|
|
case ESP_GATTS_REG_EVT: {
|
2019-02-28 12:39:12 +00:00
|
|
|
esp_ble_gap_config_local_icon (ESP_BLE_APPEARANCE_GENERIC_HID);
|
2018-03-09 08:25:23 +00:00
|
|
|
esp_hidd_cb_param_t hidd_param;
|
|
|
|
hidd_param.init_finish.state = param->reg.status;
|
|
|
|
if(param->reg.app_id == HIDD_APP_ID) {
|
|
|
|
hidd_le_env.gatt_if = gatts_if;
|
|
|
|
if(hidd_le_env.hidd_cb != NULL) {
|
|
|
|
(hidd_le_env.hidd_cb)(ESP_HIDD_EVENT_REG_FINISH, &hidd_param);
|
|
|
|
hidd_le_create_service(hidd_le_env.gatt_if);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(param->reg.app_id == BATTRAY_APP_ID) {
|
|
|
|
hidd_param.init_finish.gatts_if = gatts_if;
|
|
|
|
if(hidd_le_env.hidd_cb != NULL) {
|
|
|
|
(hidd_le_env.hidd_cb)(ESP_BAT_EVENT_REG, &hidd_param);
|
|
|
|
}
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
}
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ESP_GATTS_CONF_EVT: {
|
|
|
|
break;
|
2018-06-26 09:48:07 +00:00
|
|
|
}
|
2018-03-09 08:25:23 +00:00
|
|
|
case ESP_GATTS_CREATE_EVT:
|
|
|
|
break;
|
|
|
|
case ESP_GATTS_CONNECT_EVT: {
|
|
|
|
esp_hidd_cb_param_t cb_param = {0};
|
2018-07-31 07:20:27 +00:00
|
|
|
ESP_LOGI(HID_LE_PRF_TAG, "HID connection establish, conn_id = %x",param->connect.conn_id);
|
2018-03-09 08:25:23 +00:00
|
|
|
memcpy(cb_param.connect.remote_bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
|
|
|
|
cb_param.connect.conn_id = param->connect.conn_id;
|
|
|
|
hidd_clcb_alloc(param->connect.conn_id, param->connect.remote_bda);
|
2018-07-31 07:20:27 +00:00
|
|
|
esp_ble_set_encryption(param->connect.remote_bda, ESP_BLE_SEC_ENCRYPT_NO_MITM);
|
2018-03-09 08:25:23 +00:00
|
|
|
if(hidd_le_env.hidd_cb != NULL) {
|
|
|
|
(hidd_le_env.hidd_cb)(ESP_HIDD_EVENT_BLE_CONNECT, &cb_param);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ESP_GATTS_DISCONNECT_EVT: {
|
|
|
|
if(hidd_le_env.hidd_cb != NULL) {
|
|
|
|
(hidd_le_env.hidd_cb)(ESP_HIDD_EVENT_BLE_DISCONNECT, NULL);
|
|
|
|
}
|
|
|
|
hidd_clcb_dealloc(param->disconnect.conn_id);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ESP_GATTS_CLOSE_EVT:
|
|
|
|
break;
|
|
|
|
case ESP_GATTS_WRITE_EVT: {
|
2019-02-28 12:39:12 +00:00
|
|
|
#if (SUPPORT_REPORT_VENDOR == true)
|
2018-03-09 08:25:23 +00:00
|
|
|
esp_hidd_cb_param_t cb_param = {0};
|
|
|
|
if (param->write.handle == hidd_le_env.hidd_inst.att_tbl[HIDD_LE_IDX_REPORT_VENDOR_OUT_VAL] &&
|
|
|
|
hidd_le_env.hidd_cb != NULL) {
|
|
|
|
cb_param.vendor_write.conn_id = param->write.conn_id;
|
|
|
|
cb_param.vendor_write.report_id = HID_RPT_ID_VENDOR_OUT;
|
|
|
|
cb_param.vendor_write.length = param->write.len;
|
|
|
|
cb_param.vendor_write.data = param->write.value;
|
|
|
|
(hidd_le_env.hidd_cb)(ESP_HIDD_EVENT_BLE_VENDOR_REPORT_WRITE_EVT, &cb_param);
|
|
|
|
}
|
2019-02-28 12:39:12 +00:00
|
|
|
#endif
|
2018-03-09 08:25:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ESP_GATTS_CREAT_ATTR_TAB_EVT: {
|
2018-06-26 09:48:07 +00:00
|
|
|
if (param->add_attr_tab.num_handle == BAS_IDX_NB &&
|
2018-03-09 08:25:23 +00:00
|
|
|
param->add_attr_tab.svc_uuid.uuid.uuid16 == ESP_GATT_UUID_BATTERY_SERVICE_SVC &&
|
|
|
|
param->add_attr_tab.status == ESP_GATT_OK) {
|
|
|
|
incl_svc.start_hdl = param->add_attr_tab.handles[BAS_IDX_SVC];
|
|
|
|
incl_svc.end_hdl = incl_svc.start_hdl + BAS_IDX_NB -1;
|
2018-07-31 07:20:27 +00:00
|
|
|
ESP_LOGI(HID_LE_PRF_TAG, "%s(), start added the hid service to the stack database. incl_handle = %d",
|
2018-03-09 08:25:23 +00:00
|
|
|
__func__, incl_svc.start_hdl);
|
|
|
|
esp_ble_gatts_create_attr_tab(hidd_le_gatt_db, gatts_if, HIDD_LE_IDX_NB, 0);
|
|
|
|
}
|
2018-06-26 09:48:07 +00:00
|
|
|
if (param->add_attr_tab.num_handle == HIDD_LE_IDX_NB &&
|
2018-03-09 08:25:23 +00:00
|
|
|
param->add_attr_tab.status == ESP_GATT_OK) {
|
2018-06-26 09:48:07 +00:00
|
|
|
memcpy(hidd_le_env.hidd_inst.att_tbl, param->add_attr_tab.handles,
|
2018-03-09 08:25:23 +00:00
|
|
|
HIDD_LE_IDX_NB*sizeof(uint16_t));
|
2018-07-31 07:20:27 +00:00
|
|
|
ESP_LOGI(HID_LE_PRF_TAG, "hid svc handle = %x",hidd_le_env.hidd_inst.att_tbl[HIDD_LE_IDX_SVC]);
|
2018-03-09 08:25:23 +00:00
|
|
|
hid_add_id_tbl();
|
|
|
|
esp_ble_gatts_start_service(hidd_le_env.hidd_inst.att_tbl[HIDD_LE_IDX_SVC]);
|
|
|
|
} else {
|
|
|
|
esp_ble_gatts_start_service(param->add_attr_tab.handles[0]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void hidd_le_create_service(esp_gatt_if_t gatts_if)
|
|
|
|
{
|
|
|
|
/* Here should added the battery service first, because the hid service should include the battery service.
|
|
|
|
After finish to added the battery service then can added the hid service. */
|
|
|
|
esp_ble_gatts_create_attr_tab(bas_att_db, gatts_if, BAS_IDX_NB, 0);
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void hidd_le_init(void)
|
2018-06-26 09:48:07 +00:00
|
|
|
{
|
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
// Reset the hid device target environment
|
|
|
|
memset(&hidd_le_env, 0, sizeof(hidd_le_env_t));
|
|
|
|
}
|
|
|
|
|
|
|
|
void hidd_clcb_alloc (uint16_t conn_id, esp_bd_addr_t bda)
|
|
|
|
{
|
|
|
|
uint8_t i_clcb = 0;
|
|
|
|
hidd_clcb_t *p_clcb = NULL;
|
|
|
|
|
|
|
|
for (i_clcb = 0, p_clcb= hidd_le_env.hidd_clcb; i_clcb < HID_MAX_APPS; i_clcb++, p_clcb++) {
|
|
|
|
if (!p_clcb->in_use) {
|
2018-04-26 12:02:14 +00:00
|
|
|
p_clcb->in_use = true;
|
2018-03-09 08:25:23 +00:00
|
|
|
p_clcb->conn_id = conn_id;
|
2018-04-26 12:02:14 +00:00
|
|
|
p_clcb->connected = true;
|
2018-03-09 08:25:23 +00:00
|
|
|
memcpy (p_clcb->remote_bda, bda, ESP_BD_ADDR_LEN);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hidd_clcb_dealloc (uint16_t conn_id)
|
|
|
|
{
|
|
|
|
uint8_t i_clcb = 0;
|
|
|
|
hidd_clcb_t *p_clcb = NULL;
|
|
|
|
|
|
|
|
for (i_clcb = 0, p_clcb= hidd_le_env.hidd_clcb; i_clcb < HID_MAX_APPS; i_clcb++, p_clcb++) {
|
|
|
|
memset(p_clcb, 0, sizeof(hidd_clcb_t));
|
2018-04-26 12:02:14 +00:00
|
|
|
return true;
|
2018-03-09 08:25:23 +00:00
|
|
|
}
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-04-26 12:02:14 +00:00
|
|
|
return false;
|
2018-03-09 08:25:23 +00:00
|
|
|
}
|
|
|
|
|
2018-07-31 07:20:27 +00:00
|
|
|
static struct gatts_profile_inst heart_rate_profile_tab[PROFILE_NUM] = {
|
|
|
|
[PROFILE_APP_IDX] = {
|
|
|
|
.gatts_cb = esp_hidd_prf_cb_hdl,
|
|
|
|
.gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
|
|
|
|
},
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
|
|
|
esp_ble_gatts_cb_param_t *param)
|
|
|
|
{
|
|
|
|
/* If event is register event, store the gatts_if for each profile */
|
|
|
|
if (event == ESP_GATTS_REG_EVT) {
|
|
|
|
if (param->reg.status == ESP_GATT_OK) {
|
|
|
|
heart_rate_profile_tab[PROFILE_APP_IDX].gatts_if = gatts_if;
|
|
|
|
} else {
|
|
|
|
ESP_LOGI(HID_LE_PRF_TAG, "Reg app failed, app_id %04x, status %d\n",
|
|
|
|
param->reg.app_id,
|
|
|
|
param->reg.status);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
do {
|
|
|
|
int idx;
|
|
|
|
for (idx = 0; idx < PROFILE_NUM; idx++) {
|
|
|
|
if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
|
|
|
|
gatts_if == heart_rate_profile_tab[idx].gatts_if) {
|
|
|
|
if (heart_rate_profile_tab[idx].gatts_cb) {
|
|
|
|
heart_rate_profile_tab[idx].gatts_cb(event, gatts_if, param);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} while (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
esp_err_t hidd_register_cb(void)
|
|
|
|
{
|
|
|
|
esp_err_t status;
|
2018-07-31 07:20:27 +00:00
|
|
|
status = esp_ble_gatts_register_callback(gatts_event_handler);
|
2018-03-09 08:25:23 +00:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hidd_set_attr_value(uint16_t handle, uint16_t val_len, const uint8_t *value)
|
|
|
|
{
|
|
|
|
hidd_inst_t *hidd_inst = &hidd_le_env.hidd_inst;
|
2018-06-26 09:48:07 +00:00
|
|
|
if(hidd_inst->att_tbl[HIDD_LE_IDX_HID_INFO_VAL] <= handle &&
|
2018-03-09 08:25:23 +00:00
|
|
|
hidd_inst->att_tbl[HIDD_LE_IDX_REPORT_REP_REF] >= handle) {
|
|
|
|
esp_ble_gatts_set_attr_value(handle, val_len, value);
|
|
|
|
} else {
|
2018-04-26 12:02:14 +00:00
|
|
|
ESP_LOGE(HID_LE_PRF_TAG, "%s error:Invalid handle value.",__func__);
|
2018-03-09 08:25:23 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hidd_get_attr_value(uint16_t handle, uint16_t *length, uint8_t **value)
|
|
|
|
{
|
|
|
|
hidd_inst_t *hidd_inst = &hidd_le_env.hidd_inst;
|
2018-06-26 09:48:07 +00:00
|
|
|
if(hidd_inst->att_tbl[HIDD_LE_IDX_HID_INFO_VAL] <= handle &&
|
2018-03-09 08:25:23 +00:00
|
|
|
hidd_inst->att_tbl[HIDD_LE_IDX_REPORT_REP_REF] >= handle){
|
|
|
|
esp_ble_gatts_get_attr_value(handle, length, (const uint8_t **)value);
|
|
|
|
} else {
|
2018-04-26 12:02:14 +00:00
|
|
|
ESP_LOGE(HID_LE_PRF_TAG, "%s error:Invalid handle value.", __func__);
|
2018-03-09 08:25:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void hid_add_id_tbl(void)
|
|
|
|
{
|
|
|
|
// Mouse input report
|
|
|
|
hid_rpt_map[0].id = hidReportRefMouseIn[0];
|
|
|
|
hid_rpt_map[0].type = hidReportRefMouseIn[1];
|
|
|
|
hid_rpt_map[0].handle = hidd_le_env.hidd_inst.att_tbl[HIDD_LE_IDX_REPORT_MOUSE_IN_VAL];
|
|
|
|
hid_rpt_map[0].cccdHandle = hidd_le_env.hidd_inst.att_tbl[HIDD_LE_IDX_REPORT_MOUSE_IN_VAL];
|
|
|
|
hid_rpt_map[0].mode = HID_PROTOCOL_MODE_REPORT;
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
// Key input report
|
|
|
|
hid_rpt_map[1].id = hidReportRefKeyIn[0];
|
|
|
|
hid_rpt_map[1].type = hidReportRefKeyIn[1];
|
|
|
|
hid_rpt_map[1].handle = hidd_le_env.hidd_inst.att_tbl[HIDD_LE_IDX_REPORT_KEY_IN_VAL];
|
|
|
|
hid_rpt_map[1].cccdHandle = hidd_le_env.hidd_inst.att_tbl[HIDD_LE_IDX_REPORT_KEY_IN_CCC];
|
|
|
|
hid_rpt_map[1].mode = HID_PROTOCOL_MODE_REPORT;
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
// Consumer Control input report
|
|
|
|
hid_rpt_map[2].id = hidReportRefCCIn[0];
|
|
|
|
hid_rpt_map[2].type = hidReportRefCCIn[1];
|
|
|
|
hid_rpt_map[2].handle = hidd_le_env.hidd_inst.att_tbl[HIDD_LE_IDX_REPORT_CC_IN_VAL];
|
|
|
|
hid_rpt_map[2].cccdHandle = hidd_le_env.hidd_inst.att_tbl[HIDD_LE_IDX_REPORT_CC_IN_CCC];
|
|
|
|
hid_rpt_map[2].mode = HID_PROTOCOL_MODE_REPORT;
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
// LED output report
|
|
|
|
hid_rpt_map[3].id = hidReportRefLedOut[0];
|
|
|
|
hid_rpt_map[3].type = hidReportRefLedOut[1];
|
|
|
|
hid_rpt_map[3].handle = hidd_le_env.hidd_inst.att_tbl[HIDD_LE_IDX_REPORT_LED_OUT_VAL];
|
|
|
|
hid_rpt_map[3].cccdHandle = 0;
|
|
|
|
hid_rpt_map[3].mode = HID_PROTOCOL_MODE_REPORT;
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
// Boot keyboard input report
|
|
|
|
// Use same ID and type as key input report
|
|
|
|
hid_rpt_map[4].id = hidReportRefKeyIn[0];
|
|
|
|
hid_rpt_map[4].type = hidReportRefKeyIn[1];
|
|
|
|
hid_rpt_map[4].handle = hidd_le_env.hidd_inst.att_tbl[HIDD_LE_IDX_BOOT_KB_IN_REPORT_VAL];
|
|
|
|
hid_rpt_map[4].cccdHandle = 0;
|
|
|
|
hid_rpt_map[4].mode = HID_PROTOCOL_MODE_BOOT;
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
// Boot keyboard output report
|
|
|
|
// Use same ID and type as LED output report
|
|
|
|
hid_rpt_map[5].id = hidReportRefLedOut[0];
|
|
|
|
hid_rpt_map[5].type = hidReportRefLedOut[1];
|
|
|
|
hid_rpt_map[5].handle = hidd_le_env.hidd_inst.att_tbl[HIDD_LE_IDX_BOOT_KB_OUT_REPORT_VAL];
|
|
|
|
hid_rpt_map[5].cccdHandle = 0;
|
|
|
|
hid_rpt_map[5].mode = HID_PROTOCOL_MODE_BOOT;
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
// Boot mouse input report
|
|
|
|
// Use same ID and type as mouse input report
|
|
|
|
hid_rpt_map[6].id = hidReportRefMouseIn[0];
|
|
|
|
hid_rpt_map[6].type = hidReportRefMouseIn[1];
|
|
|
|
hid_rpt_map[6].handle = hidd_le_env.hidd_inst.att_tbl[HIDD_LE_IDX_BOOT_MOUSE_IN_REPORT_VAL];
|
|
|
|
hid_rpt_map[6].cccdHandle = 0;
|
|
|
|
hid_rpt_map[6].mode = HID_PROTOCOL_MODE_BOOT;
|
2018-06-26 09:48:07 +00:00
|
|
|
|
2018-03-09 08:25:23 +00:00
|
|
|
// Feature report
|
|
|
|
hid_rpt_map[7].id = hidReportRefFeature[0];
|
|
|
|
hid_rpt_map[7].type = hidReportRefFeature[1];
|
|
|
|
hid_rpt_map[7].handle = hidd_le_env.hidd_inst.att_tbl[HIDD_LE_IDX_REPORT_VAL];
|
|
|
|
hid_rpt_map[7].cccdHandle = 0;
|
|
|
|
hid_rpt_map[7].mode = HID_PROTOCOL_MODE_REPORT;
|
|
|
|
|
|
|
|
|
|
|
|
// Setup report ID map
|
|
|
|
hid_dev_register_reports(HID_NUM_REPORTS, hid_rpt_map);
|
|
|
|
}
|
|
|
|
|