@@ -30,6 +30,148 @@ static const char *manuf_name = "Apache Mynewt ESP32 devkitC";
3030static const char * model_num = "Mynewt HR Sensor demo" ;
3131static const char * firmware_rev = "2.0" ;
3232static const char * software_rev = "4.8" ;
33+
34+ static const uint8_t hidReportMap [] = {
35+ 0x05 , 0x01 , // Usage Page (Generic Desktop)
36+ 0x09 , 0x02 , // Usage (Mouse)
37+ 0xA1 , 0x01 , // Collection (Application)
38+ 0x85 , 0x01 , // Report Id (1)
39+ 0x09 , 0x01 , // Usage (Pointer)
40+ 0xA1 , 0x00 , // Collection (Physical)
41+ 0x05 , 0x09 , // Usage Page (Buttons)
42+ 0x19 , 0x01 , // Usage Minimum (01) - Button 1
43+ 0x29 , 0x03 , // Usage Maximum (03) - Button 3
44+ 0x15 , 0x00 , // Logical Minimum (0)
45+ 0x25 , 0x01 , // Logical Maximum (1)
46+ 0x75 , 0x01 , // Report Size (1)
47+ 0x95 , 0x03 , // Report Count (3)
48+ 0x81 , 0x02 , // Input (Data, Variable, Absolute) - Button states
49+ 0x75 , 0x05 , // Report Size (5)
50+ 0x95 , 0x01 , // Report Count (1)
51+ 0x81 , 0x01 , // Input (Constant) - Padding or Reserved bits
52+ 0x05 , 0x01 , // Usage Page (Generic Desktop)
53+ 0x09 , 0x30 , // Usage (X)
54+ 0x09 , 0x31 , // Usage (Y)
55+ 0x09 , 0x38 , // Usage (Wheel)
56+ 0x15 , 0x81 , // Logical Minimum (-127)
57+ 0x25 , 0x7F , // Logical Maximum (127)
58+ 0x75 , 0x08 , // Report Size (8)
59+ 0x95 , 0x03 , // Report Count (3)
60+ 0x81 , 0x06 , // Input (Data, Variable, Relative) - X & Y coordinate
61+ 0xC0 , // End Collection
62+ 0xC0 , // End Collection
63+
64+ 0x05 , 0x01 , // Usage Pg (Generic Desktop)
65+ 0x09 , 0x06 , // Usage (Keyboard)
66+ 0xA1 , 0x01 , // Collection: (Application)
67+ 0x85 , 0x02 , // Report Id (2)
68+ //
69+ 0x05 , 0x07 , // Usage Pg (Key Codes)
70+ 0x19 , 0xE0 , // Usage Min (224)
71+ 0x29 , 0xE7 , // Usage Max (231)
72+ 0x15 , 0x00 , // Log Min (0)
73+ 0x25 , 0x01 , // Log Max (1)
74+ //
75+ // Modifier byte
76+ 0x75 , 0x01 , // Report Size (1)
77+ 0x95 , 0x08 , // Report Count (8)
78+ 0x81 , 0x02 , // Input: (Data, Variable, Absolute)
79+ //
80+ // Reserved byte
81+ 0x95 , 0x01 , // Report Count (1)
82+ 0x75 , 0x08 , // Report Size (8)
83+ 0x81 , 0x01 , // Input: (Constant)
84+ //
85+ // LED report
86+ 0x95 , 0x05 , // Report Count (5)
87+ 0x75 , 0x01 , // Report Size (1)
88+ 0x05 , 0x08 , // Usage Pg (LEDs)
89+ 0x19 , 0x01 , // Usage Min (1)
90+ 0x29 , 0x05 , // Usage Max (5)
91+ 0x91 , 0x02 , // Output: (Data, Variable, Absolute)
92+ //
93+ // LED report padding
94+ 0x95 , 0x01 , // Report Count (1)
95+ 0x75 , 0x03 , // Report Size (3)
96+ 0x91 , 0x01 , // Output: (Constant)
97+ //
98+ // Key arrays (6 bytes)
99+ 0x95 , 0x06 , // Report Count (6)
100+ 0x75 , 0x08 , // Report Size (8)
101+ 0x15 , 0x00 , // Log Min (0)
102+ 0x25 , 0x65 , // Log Max (101)
103+ 0x05 , 0x07 , // Usage Pg (Key Codes)
104+ 0x19 , 0x00 , // Usage Min (0)
105+ 0x29 , 0x65 , // Usage Max (101)
106+ 0x81 , 0x00 , // Input: (Data, Array)
107+ //
108+ 0xC0 , // End Collection
109+ //
110+ 0x05 , 0x0C , // Usage Pg (Consumer Devices)
111+ 0x09 , 0x01 , // Usage (Consumer Control)
112+ 0xA1 , 0x01 , // Collection (Application)
113+ 0x85 , 0x03 , // Report Id (3)
114+ 0x09 , 0x02 , // Usage (Numeric Key Pad)
115+ 0xA1 , 0x02 , // Collection (Logical)
116+ 0x05 , 0x09 , // Usage Pg (Button)
117+ 0x19 , 0x01 , // Usage Min (Button 1)
118+ 0x29 , 0x0A , // Usage Max (Button 10)
119+ 0x15 , 0x01 , // Logical Min (1)
120+ 0x25 , 0x0A , // Logical Max (10)
121+ 0x75 , 0x04 , // Report Size (4)
122+ 0x95 , 0x01 , // Report Count (1)
123+ 0x81 , 0x00 , // Input (Data, Ary, Abs)
124+ 0xC0 , // End Collection
125+ 0x05 , 0x0C , // Usage Pg (Consumer Devices)
126+ 0x09 , 0x86 , // Usage (Channel)
127+ 0x15 , 0xFF , // Logical Min (-1)
128+ 0x25 , 0x01 , // Logical Max (1)
129+ 0x75 , 0x02 , // Report Size (2)
130+ 0x95 , 0x01 , // Report Count (1)
131+ 0x81 , 0x46 , // Input (Data, Var, Rel, Null)
132+ 0x09 , 0xE9 , // Usage (Volume Up)
133+ 0x09 , 0xEA , // Usage (Volume Down)
134+ 0x15 , 0x00 , // Logical Min (0)
135+ 0x75 , 0x01 , // Report Size (1)
136+ 0x95 , 0x02 , // Report Count (2)
137+ 0x81 , 0x02 , // Input (Data, Var, Abs)
138+ 0x09 , 0xE2 , // Usage (Mute)
139+ 0x09 , 0x30 , // Usage (Power)
140+ 0x09 , 0x83 , // Usage (Recall Last)
141+ 0x09 , 0x81 , // Usage (Assign Selection)
142+ 0x09 , 0xB0 , // Usage (Play)
143+ 0x09 , 0xB1 , // Usage (Pause)
144+ 0x09 , 0xB2 , // Usage (Record)
145+ 0x09 , 0xB3 , // Usage (Fast Forward)
146+ 0x09 , 0xB4 , // Usage (Rewind)
147+ 0x09 , 0xB5 , // Usage (Scan Next)
148+ 0x09 , 0xB6 , // Usage (Scan Prev)
149+ 0x09 , 0xB7 , // Usage (Stop)
150+ 0x15 , 0x01 , // Logical Min (1)
151+ 0x25 , 0x0C , // Logical Max (12)
152+ 0x75 , 0x04 , // Report Size (4)
153+ 0x95 , 0x01 , // Report Count (1)
154+ 0x81 , 0x00 , // Input (Data, Ary, Abs)
155+ 0x09 , 0x80 , // Usage (Selection)
156+ 0xA1 , 0x02 , // Collection (Logical)
157+ 0x05 , 0x09 , // Usage Pg (Button)
158+ 0x19 , 0x01 , // Usage Min (Button 1)
159+ 0x29 , 0x03 , // Usage Max (Button 3)
160+ 0x15 , 0x01 , // Logical Min (1)
161+ 0x25 , 0x03 , // Logical Max (3)
162+ 0x75 , 0x02 , // Report Size (2)
163+ 0x81 , 0x00 , // Input (Data, Ary, Abs)
164+ 0xC0 , // End Collection
165+ 0x81 , 0x03 , // Input (Const, Var, Abs)
166+ 0xC0 , // End Collectionq
167+ };
168+
169+ static const uint8_t hidInfo [HID_INFORMATION_LEN ] = {
170+ 0x11 , 0x01 , // bcdHID (USB HID version) --> Version 1.11
171+ 0x00 , // bCountryCode
172+ HID_KBD_FLAGS // Flags
173+ };
174+
33175uint16_t hrs_hrm_handle ;
34176
35177static int
@@ -40,6 +182,10 @@ static int
40182gatt_svr_chr_access_device_info (uint16_t conn_handle , uint16_t attr_handle ,
41183 struct ble_gatt_access_ctxt * ctxt , void * arg );
42184
185+ static int
186+ gatt_svr_chr_hid (uint16_t conn_handle , uint16_t attr_handle ,
187+ struct ble_gatt_access_ctxt * ctxt , void * arg );
188+
43189static const struct ble_gatt_svc_def gatt_svr_svcs [] = {
44190 {
45191 /* Service: Heart-rate */
@@ -110,11 +256,67 @@ static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
110256 }
111257 },
112258
259+ {
260+ /* Service: HID */
261+ .type = BLE_GATT_SVC_TYPE_PRIMARY ,
262+ .uuid = BLE_UUID16_DECLARE (GATT_HIDS_UUID ),
263+ .characteristics = (struct ble_gatt_chr_def [])
264+ { {
265+ /* Characteristic: Report Map */
266+ .uuid = BLE_UUID16_DECLARE (GATT_HID_REPORT_MAP_UUID ),
267+ .access_cb = gatt_svr_chr_hid ,
268+ .flags = BLE_GATT_CHR_F_READ ,
269+ }, {
270+ /* Characteristic: HID Information */
271+ .uuid = BLE_UUID16_DECLARE (GATT_HID_INFORMATION_UUID ),
272+ .access_cb = gatt_svr_chr_hid ,
273+ .flags = BLE_GATT_CHR_F_READ ,
274+ }, {
275+ /* Characteristic: HID Control Point */
276+ .uuid = BLE_UUID16_DECLARE (GATT_HID_CONTROL_POINT_UUID ),
277+ .access_cb = gatt_svr_chr_hid ,
278+ .flags = BLE_GATT_CHR_F_WRITE_NO_RSP ,
279+ }, {
280+ 0 , /* No more characteristics in this service */
281+ },
282+ }
283+ },
284+
113285 {
114286 0 , /* No more services */
115287 },
116288};
117289
290+ static int gatt_svr_chr_hid (uint16_t conn_handle , uint16_t attr_handle ,
291+ struct ble_gatt_access_ctxt * ctxt , void * arg )
292+ {
293+ uint16_t uuid ;
294+ int rc ;
295+
296+ uuid = ble_uuid_u16 (ctxt -> chr -> uuid );
297+
298+ if (uuid == GATT_HID_REPORT_MAP_UUID ) {
299+ rc = os_mbuf_append (ctxt -> om , hidReportMap , sizeof (hidReportMap )/sizeof (hidReportMap [0 ]));
300+ return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES ;
301+ }
302+
303+ if (uuid == GATT_HID_INFORMATION_UUID ) {
304+ rc = os_mbuf_append (ctxt -> om , hidInfo , sizeof (hidInfo )/sizeof (hidInfo [0 ]));
305+ return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES ;
306+ }
307+
308+ if (uuid == GATT_HID_CONTROL_POINT_UUID ) {
309+ int * test = OS_MBUF_DATA (ctxt -> om ,int * );
310+ //00 == hid host is entering the suspend state
311+ //01 == hid host is exiting the suspend state
312+ ESP_LOGW ("ASDF" , "WRITE TO CONTROL POINT %d" ,* test );
313+ return 0 ;
314+ }
315+
316+ assert (0 );
317+ return BLE_ATT_ERR_UNLIKELY ;
318+ }
319+
118320static int
119321gatt_svr_chr_access_heart_rate (uint16_t conn_handle , uint16_t attr_handle ,
120322 struct ble_gatt_access_ctxt * ctxt , void * arg )
0 commit comments