1 /******************************************************************************
2 *
3 * Copyright 2009-2013 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #define LOG_TAG "bt_bta_hh"
20
21 #include <base/bind.h>
22 #include <base/callback.h>
23
24 #include <cstdint>
25 #include <vector>
26
27 #include "bta/hh/bta_hh_int.h"
28 #include "bta/include/bta_gatt_queue.h"
29 #include "bta/include/bta_hh_co.h"
30 #include "device/include/interop.h"
31 #include "main/shim/dumpsys.h"
32 #include "main/shim/shim.h"
33 #include "osi/include/allocator.h"
34 #include "osi/include/log.h"
35 #include "osi/include/osi.h" // ARRAY_SIZE
36 #include "stack/btm/btm_sec.h" // BTM_
37 #include "stack/include/bt_hdr.h"
38 #include "stack/include/bt_octets.h"
39 #include "stack/include/btu.h" // post_on_bt_main
40 #include "stack/include/l2c_api.h" // L2CA_
41 #include "stack/include/srvc_api.h" // tDIS_VALUE
42 #include "types/bluetooth/uuid.h"
43 #include "types/raw_address.h"
44
45 using bluetooth::Uuid;
46 using std::vector;
47
48 namespace {
49
50 #ifndef BTA_HH_LE_RECONN
51 constexpr bool kBTA_HH_LE_RECONN = true;
52 #else
53 constexpr bool kBTA_HH_LE_RECONN = false;
54 #endif
55
56 } // namespace
57
58 #define BTA_HH_APP_ID_LE 0xff
59
60 #define BTA_HH_LE_PROTO_BOOT_MODE 0x00
61 #define BTA_HH_LE_PROTO_REPORT_MODE 0x01
62
63 #define BTA_LE_HID_RTP_UUID_MAX 5
64
65 namespace {
66
67 constexpr char kBtmLogTag[] = "HIDH";
68
69 }
70
71 static const uint16_t bta_hh_uuid_to_rtp_type[BTA_LE_HID_RTP_UUID_MAX][2] = {
72 {GATT_UUID_HID_REPORT, BTA_HH_RPTT_INPUT},
73 {GATT_UUID_HID_BT_KB_INPUT, BTA_HH_RPTT_INPUT},
74 {GATT_UUID_HID_BT_KB_OUTPUT, BTA_HH_RPTT_OUTPUT},
75 {GATT_UUID_HID_BT_MOUSE_INPUT, BTA_HH_RPTT_INPUT},
76 {GATT_UUID_BATTERY_LEVEL, BTA_HH_RPTT_INPUT}};
77
78 static void bta_hh_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data);
79 static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB* p_cb, bool check_bond);
80 static void bta_hh_process_cache_rpt(tBTA_HH_DEV_CB* p_cb,
81 tBTA_HH_RPT_CACHE_ENTRY* p_rpt_cache,
82 uint8_t num_rpt);
83 extern void bta_dm_process_delete_key_RC_to_unpair(const RawAddress& bd_addr);
84
85 static const char* bta_hh_le_rpt_name[4] = {"UNKNOWN", "INPUT", "OUTPUT",
86 "FEATURE"};
87
88 /*******************************************************************************
89 *
90 * Function bta_hh_le_hid_report_dbg
91 *
92 * Description debug function to print out all HID report available on
93 * remote device.
94 *
95 * Returns void
96 *
97 ******************************************************************************/
bta_hh_le_hid_report_dbg(tBTA_HH_DEV_CB * p_cb)98 static void bta_hh_le_hid_report_dbg(tBTA_HH_DEV_CB* p_cb) {
99 APPL_TRACE_DEBUG("%s: HID Report DB", __func__);
100
101 if (!p_cb->hid_srvc.in_use) return;
102
103 tBTA_HH_LE_RPT* p_rpt = &p_cb->hid_srvc.report[0];
104
105 for (int j = 0; j < BTA_HH_LE_RPT_MAX; j++, p_rpt++) {
106 const char* rpt_name = "Unknown";
107
108 if (!p_rpt->in_use) break;
109
110 if (p_rpt->uuid == GATT_UUID_HID_REPORT) rpt_name = "Report";
111 if (p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT) rpt_name = "Boot KB Input";
112 if (p_rpt->uuid == GATT_UUID_HID_BT_KB_OUTPUT) rpt_name = "Boot KB Output";
113 if (p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) rpt_name = "Boot MI Input";
114
115 APPL_TRACE_DEBUG(
116 "\t\t [%s- 0x%04x] [Type: %s], [ReportID: %d] [srvc_inst_id: %d] "
117 "[char_inst_id: %d] [Clt_cfg: %d]",
118 rpt_name, p_rpt->uuid,
119 ((p_rpt->rpt_type < 4) ? bta_hh_le_rpt_name[p_rpt->rpt_type]
120 : "UNKNOWN"),
121 p_rpt->rpt_id, p_rpt->srvc_inst_id, p_rpt->char_inst_id,
122 p_rpt->client_cfg_value);
123 }
124 }
125
126 /*******************************************************************************
127 *
128 * Function bta_hh_uuid_to_str
129 *
130 * Description
131 *
132 * Returns void
133 *
134 ******************************************************************************/
bta_hh_uuid_to_str(uint16_t uuid)135 static const char* bta_hh_uuid_to_str(uint16_t uuid) {
136 switch (uuid) {
137 case GATT_UUID_HID_INFORMATION:
138 return "GATT_UUID_HID_INFORMATION";
139 case GATT_UUID_HID_REPORT_MAP:
140 return "GATT_UUID_HID_REPORT_MAP";
141 case GATT_UUID_HID_CONTROL_POINT:
142 return "GATT_UUID_HID_CONTROL_POINT";
143 case GATT_UUID_HID_REPORT:
144 return "GATT_UUID_HID_REPORT";
145 case GATT_UUID_HID_PROTO_MODE:
146 return "GATT_UUID_HID_PROTO_MODE";
147 case GATT_UUID_HID_BT_KB_INPUT:
148 return "GATT_UUID_HID_BT_KB_INPUT";
149 case GATT_UUID_HID_BT_KB_OUTPUT:
150 return "GATT_UUID_HID_BT_KB_OUTPUT";
151 case GATT_UUID_HID_BT_MOUSE_INPUT:
152 return "GATT_UUID_HID_BT_MOUSE_INPUT";
153 case GATT_UUID_CHAR_CLIENT_CONFIG:
154 return "GATT_UUID_CHAR_CLIENT_CONFIG";
155 case GATT_UUID_EXT_RPT_REF_DESCR:
156 return "GATT_UUID_EXT_RPT_REF_DESCR";
157 case GATT_UUID_RPT_REF_DESCR:
158 return "GATT_UUID_RPT_REF_DESCR";
159 default:
160 return "Unknown UUID";
161 }
162 }
163
164 /*******************************************************************************
165 *
166 * Function bta_hh_le_enable
167 *
168 * Description initialize LE HID related functionality
169 *
170 *
171 * Returns void
172 *
173 ******************************************************************************/
bta_hh_le_enable(void)174 void bta_hh_le_enable(void) {
175 uint8_t xx;
176
177 bta_hh_cb.gatt_if = BTA_GATTS_INVALID_IF;
178
179 for (xx = 0; xx < ARRAY_SIZE(bta_hh_cb.le_cb_index); xx++)
180 bta_hh_cb.le_cb_index[xx] = BTA_HH_IDX_INVALID;
181
182 BTA_GATTC_AppRegister(bta_hh_gattc_callback,
183 base::Bind([](uint8_t client_id, uint8_t r_status) {
184 tBTA_HH bta_hh;
185 bta_hh.status = BTA_HH_ERR;
186
187 if (r_status == GATT_SUCCESS) {
188 bta_hh_cb.gatt_if = client_id;
189 bta_hh.status = BTA_HH_OK;
190 } else {
191 bta_hh_cb.gatt_if = BTA_GATTS_INVALID_IF;
192 }
193
194 /* null check is needed in case HID profile is shut
195 * down before BTA_GATTC_AppRegister is done */
196 if (bta_hh_cb.p_cback) {
197 /* signal BTA call back event */
198 (*bta_hh_cb.p_cback)(BTA_HH_ENABLE_EVT, &bta_hh);
199 }
200 }), false);
201 }
202
203 /*******************************************************************************
204 *
205 * Function bta_hh_le_is_hh_gatt_if
206 *
207 * Description Check to see if client_if is BTA HH LE GATT interface
208 *
209 *
210 * Returns whether it is HH GATT IF
211 *
212 ******************************************************************************/
bta_hh_le_is_hh_gatt_if(tGATT_IF client_if)213 bool bta_hh_le_is_hh_gatt_if(tGATT_IF client_if) {
214 return (bta_hh_cb.gatt_if == client_if);
215 }
216
217 /*******************************************************************************
218 *
219 * Function bta_hh_le_deregister
220 *
221 * Description De-register BTA HH from BTA GATTC
222 *
223 *
224 * Returns void
225 *
226 ******************************************************************************/
bta_hh_le_deregister(void)227 void bta_hh_le_deregister(void) { BTA_GATTC_AppDeregister(bta_hh_cb.gatt_if); }
228
229 /******************************************************************************
230 *
231 * Function bta_hh_le_get_le_cb
232 *
233 * Description Allocate bta_hh_cb.le_cb_index
234 *
235 * Parameters:
236 *
237 ******************************************************************************/
bta_hh_le_get_le_dev_hdl(uint8_t cb_index)238 static uint8_t bta_hh_le_get_le_dev_hdl(uint8_t cb_index) {
239 uint8_t i;
240 for (i = 0; i < ARRAY_SIZE(bta_hh_cb.le_cb_index); i++) {
241 if (bta_hh_cb.le_cb_index[i] == cb_index) return BTA_HH_GET_LE_DEV_HDL(i);
242 }
243
244 for (i = 0; i < ARRAY_SIZE(bta_hh_cb.le_cb_index); i++) {
245 if (bta_hh_cb.le_cb_index[i] == BTA_HH_IDX_INVALID)
246 return BTA_HH_GET_LE_DEV_HDL(i);
247 }
248 return BTA_HH_IDX_INVALID;
249 }
250
251 /*******************************************************************************
252 *
253 * Function bta_hh_le_open_conn
254 *
255 * Description open a GATT connection first.
256 *
257 * Parameters:
258 *
259 ******************************************************************************/
bta_hh_le_open_conn(tBTA_HH_DEV_CB * p_cb,const RawAddress & remote_bda)260 void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb, const RawAddress& remote_bda) {
261 tBTA_HH_STATUS status = BTA_HH_ERR_NO_RES;
262
263 /* update cb_index[] map */
264 p_cb->hid_handle = bta_hh_le_get_le_dev_hdl(p_cb->index);
265 if (p_cb->hid_handle == BTA_HH_IDX_INVALID) {
266 bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA*)&status);
267 return;
268 }
269
270 p_cb->addr = remote_bda;
271 bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index;
272 p_cb->in_use = true;
273
274 BTA_GATTC_Open(bta_hh_cb.gatt_if, remote_bda, BTM_BLE_DIRECT_CONNECTION,
275 false);
276 }
277
278 /*******************************************************************************
279 *
280 * Function bta_hh_le_find_dev_cb_by_conn_id
281 *
282 * Description Utility function find a device control block by connection
283 * ID.
284 *
285 ******************************************************************************/
bta_hh_le_find_dev_cb_by_conn_id(uint16_t conn_id)286 static tBTA_HH_DEV_CB* bta_hh_le_find_dev_cb_by_conn_id(uint16_t conn_id) {
287 uint8_t i;
288 tBTA_HH_DEV_CB* p_dev_cb = &bta_hh_cb.kdev[0];
289
290 for (i = 0; i < BTA_HH_MAX_DEVICE; i++, p_dev_cb++) {
291 if (p_dev_cb->in_use && p_dev_cb->conn_id == conn_id) return p_dev_cb;
292 }
293 return NULL;
294 }
295
296 /*******************************************************************************
297 *
298 * Function bta_hh_le_find_dev_cb_by_bda
299 *
300 * Description Utility function find a device control block by BD address.
301 *
302 ******************************************************************************/
bta_hh_le_find_dev_cb_by_bda(const RawAddress & bda)303 static tBTA_HH_DEV_CB* bta_hh_le_find_dev_cb_by_bda(const RawAddress& bda) {
304 uint8_t i;
305 tBTA_HH_DEV_CB* p_dev_cb = &bta_hh_cb.kdev[0];
306
307 for (i = 0; i < BTA_HH_MAX_DEVICE; i++, p_dev_cb++) {
308 if (p_dev_cb->in_use && p_dev_cb->addr == bda) return p_dev_cb;
309 }
310 return NULL;
311 }
312
313 /*******************************************************************************
314 *
315 * Function bta_hh_le_find_service_inst_by_battery_inst_id
316 *
317 * Description find HID service instance ID by battery service instance ID
318 *
319 ******************************************************************************/
bta_hh_le_find_service_inst_by_battery_inst_id(tBTA_HH_DEV_CB * p_cb,uint8_t ba_inst_id)320 static uint8_t bta_hh_le_find_service_inst_by_battery_inst_id(
321 tBTA_HH_DEV_CB* p_cb, uint8_t ba_inst_id) {
322 if (p_cb->hid_srvc.in_use && p_cb->hid_srvc.incl_srvc_inst == ba_inst_id) {
323 return p_cb->hid_srvc.srvc_inst_id;
324 }
325 return BTA_HH_IDX_INVALID;
326 }
327
328 /*******************************************************************************
329 *
330 * Function bta_hh_le_find_report_entry
331 *
332 * Description find the report entry by service instance and report UUID
333 * and instance ID
334 *
335 ******************************************************************************/
bta_hh_le_find_report_entry(tBTA_HH_DEV_CB * p_cb,uint8_t srvc_inst_id,uint16_t rpt_uuid,uint16_t char_inst_id)336 static tBTA_HH_LE_RPT* bta_hh_le_find_report_entry(
337 tBTA_HH_DEV_CB* p_cb, uint8_t srvc_inst_id, /* service instance ID */
338 uint16_t rpt_uuid, uint16_t char_inst_id) {
339 uint8_t i;
340 uint8_t hid_inst_id = srvc_inst_id;
341 tBTA_HH_LE_RPT* p_rpt;
342
343 if (rpt_uuid == GATT_UUID_BATTERY_LEVEL) {
344 hid_inst_id =
345 bta_hh_le_find_service_inst_by_battery_inst_id(p_cb, srvc_inst_id);
346
347 if (hid_inst_id == BTA_HH_IDX_INVALID) return NULL;
348 }
349
350 p_rpt = &p_cb->hid_srvc.report[0];
351
352 for (i = 0; i < BTA_HH_LE_RPT_MAX; i++, p_rpt++) {
353 if (p_rpt->uuid == rpt_uuid && p_rpt->srvc_inst_id == srvc_inst_id &&
354 p_rpt->char_inst_id == char_inst_id) {
355 return p_rpt;
356 }
357 }
358 return NULL;
359 }
360
361 /*******************************************************************************
362 *
363 * Function bta_hh_le_find_rpt_by_idtype
364 *
365 * Description find a report entry by report ID and protocol mode
366 *
367 * Returns void
368 *
369 ******************************************************************************/
bta_hh_le_find_rpt_by_idtype(tBTA_HH_LE_RPT * p_head,uint8_t mode,tBTA_HH_RPT_TYPE r_type,uint8_t rpt_id)370 static tBTA_HH_LE_RPT* bta_hh_le_find_rpt_by_idtype(tBTA_HH_LE_RPT* p_head,
371 uint8_t mode,
372 tBTA_HH_RPT_TYPE r_type,
373 uint8_t rpt_id) {
374 tBTA_HH_LE_RPT* p_rpt = p_head;
375 uint8_t i;
376
377 APPL_TRACE_DEBUG("bta_hh_le_find_rpt_by_idtype: r_type: %d rpt_id: %d",
378 r_type, rpt_id);
379
380 for (i = 0; i < BTA_HH_LE_RPT_MAX; i++, p_rpt++) {
381 if (p_rpt->in_use && p_rpt->rpt_id == rpt_id && r_type == p_rpt->rpt_type) {
382 /* return battery report w/o condition */
383 if (p_rpt->uuid == GATT_UUID_BATTERY_LEVEL) return p_rpt;
384
385 if (mode == BTA_HH_PROTO_RPT_MODE && p_rpt->uuid == GATT_UUID_HID_REPORT)
386 return p_rpt;
387
388 if (mode == BTA_HH_PROTO_BOOT_MODE &&
389 (p_rpt->uuid >= GATT_UUID_HID_BT_KB_INPUT &&
390 p_rpt->uuid <= GATT_UUID_HID_BT_MOUSE_INPUT))
391 return p_rpt;
392 }
393 }
394 return NULL;
395 }
396
397 /*******************************************************************************
398 *
399 * Function bta_hh_le_find_alloc_report_entry
400 *
401 * Description find or allocate a report entry in the HID service report
402 * list.
403 *
404 ******************************************************************************/
bta_hh_le_find_alloc_report_entry(tBTA_HH_DEV_CB * p_cb,uint8_t srvc_inst_id,uint16_t rpt_uuid,uint16_t inst_id)405 static tBTA_HH_LE_RPT* bta_hh_le_find_alloc_report_entry(tBTA_HH_DEV_CB* p_cb,
406 uint8_t srvc_inst_id,
407 uint16_t rpt_uuid,
408 uint16_t inst_id) {
409 uint8_t i, hid_inst_id = srvc_inst_id;
410 tBTA_HH_LE_RPT* p_rpt;
411
412 if (rpt_uuid == GATT_UUID_BATTERY_LEVEL) {
413 hid_inst_id =
414 bta_hh_le_find_service_inst_by_battery_inst_id(p_cb, srvc_inst_id);
415
416 if (hid_inst_id == BTA_HH_IDX_INVALID) return NULL;
417 }
418 p_rpt = &p_cb->hid_srvc.report[0];
419
420 for (i = 0; i < BTA_HH_LE_RPT_MAX; i++, p_rpt++) {
421 if (!p_rpt->in_use ||
422 (p_rpt->uuid == rpt_uuid && p_rpt->srvc_inst_id == srvc_inst_id &&
423 p_rpt->char_inst_id == inst_id)) {
424 if (!p_rpt->in_use) {
425 p_rpt->in_use = true;
426 p_rpt->index = i;
427 p_rpt->srvc_inst_id = srvc_inst_id;
428 p_rpt->char_inst_id = inst_id;
429 p_rpt->uuid = rpt_uuid;
430
431 /* assign report type */
432 for (i = 0; i < BTA_LE_HID_RTP_UUID_MAX; i++) {
433 if (bta_hh_uuid_to_rtp_type[i][0] == rpt_uuid) {
434 p_rpt->rpt_type = (tBTA_HH_RPT_TYPE)bta_hh_uuid_to_rtp_type[i][1];
435
436 if (rpt_uuid == GATT_UUID_HID_BT_KB_INPUT ||
437 rpt_uuid == GATT_UUID_HID_BT_KB_OUTPUT)
438 p_rpt->rpt_id = BTA_HH_KEYBD_RPT_ID;
439
440 if (rpt_uuid == GATT_UUID_HID_BT_MOUSE_INPUT)
441 p_rpt->rpt_id = BTA_HH_MOUSE_RPT_ID;
442
443 break;
444 }
445 }
446 }
447 return p_rpt;
448 }
449 }
450 return NULL;
451 }
452
find_descriptor_by_short_uuid(uint16_t conn_id,uint16_t char_handle,uint16_t short_uuid)453 static const gatt::Descriptor* find_descriptor_by_short_uuid(
454 uint16_t conn_id, uint16_t char_handle, uint16_t short_uuid) {
455 const gatt::Characteristic* p_char =
456 BTA_GATTC_GetCharacteristic(conn_id, char_handle);
457
458 if (!p_char) {
459 LOG_WARN("%s No such characteristic: %d", __func__, char_handle);
460 return NULL;
461 }
462
463 for (const gatt::Descriptor& desc : p_char->descriptors) {
464 if (desc.uuid == Uuid::From16Bit(short_uuid)) return &desc;
465 }
466
467 return NULL;
468 }
469
470 /*******************************************************************************
471 *
472 * Function bta_hh_le_read_char_descriptor
473 *
474 * Description read characteristic descriptor
475 *
476 ******************************************************************************/
bta_hh_le_read_char_descriptor(tBTA_HH_DEV_CB * p_cb,uint16_t char_handle,uint16_t short_uuid,GATT_READ_OP_CB cb,void * cb_data)477 static tBTA_HH_STATUS bta_hh_le_read_char_descriptor(tBTA_HH_DEV_CB* p_cb,
478 uint16_t char_handle,
479 uint16_t short_uuid,
480 GATT_READ_OP_CB cb,
481 void* cb_data) {
482 const gatt::Descriptor* p_desc =
483 find_descriptor_by_short_uuid(p_cb->conn_id, char_handle, short_uuid);
484 if (!p_desc) return BTA_HH_ERR;
485
486 BtaGattQueue::ReadDescriptor(p_cb->conn_id, p_desc->handle, cb, cb_data);
487 return BTA_HH_OK;
488 }
489
490 /*******************************************************************************
491 *
492 * Function bta_hh_le_save_report_ref
493 *
494 * Description save report reference information and move to next one.
495 *
496 * Parameters:
497 *
498 ******************************************************************************/
bta_hh_le_save_report_ref(tBTA_HH_DEV_CB * p_dev_cb,tBTA_HH_LE_RPT * p_rpt,tGATT_STATUS status,uint8_t * value,uint16_t len)499 static void bta_hh_le_save_report_ref(tBTA_HH_DEV_CB* p_dev_cb,
500 tBTA_HH_LE_RPT* p_rpt,
501 tGATT_STATUS status, uint8_t* value,
502 uint16_t len) {
503 if (status == GATT_INSUF_AUTHENTICATION) {
504 /* close connection right away */
505 p_dev_cb->status = BTA_HH_ERR_AUTH_FAILED;
506 /* close the connection and report service discovery complete with error */
507 bta_hh_le_api_disc_act(p_dev_cb);
508 return;
509 }
510
511 /* if the length of the descriptor value is right, parse it */
512 if (status == GATT_SUCCESS && len == 2) {
513 uint8_t* pp = value;
514
515 STREAM_TO_UINT8(p_rpt->rpt_id, pp);
516 STREAM_TO_UINT8(p_rpt->rpt_type, pp);
517
518 if (p_rpt->rpt_type > BTA_HH_RPTT_FEATURE) /* invalid report type */
519 p_rpt->rpt_type = BTA_HH_RPTT_RESRV;
520
521 APPL_TRACE_DEBUG("%s: report ID: %d", __func__, p_rpt->rpt_id);
522 tBTA_HH_RPT_CACHE_ENTRY rpt_entry;
523 rpt_entry.rpt_id = p_rpt->rpt_id;
524 rpt_entry.rpt_type = p_rpt->rpt_type;
525 rpt_entry.rpt_uuid = p_rpt->uuid;
526 rpt_entry.srvc_inst_id = p_rpt->srvc_inst_id;
527 rpt_entry.char_inst_id = p_rpt->char_inst_id;
528
529 bta_hh_le_co_rpt_info(p_dev_cb->addr, &rpt_entry, p_dev_cb->app_id);
530 }
531
532 if (p_rpt->index < BTA_HH_LE_RPT_MAX - 1)
533 p_rpt++;
534 else
535 p_rpt = NULL;
536 }
537
538 /*******************************************************************************
539 *
540 * Function bta_hh_le_register_input_notif
541 *
542 * Description Register for all notifications for the report applicable
543 * for the protocol mode.
544 *
545 * Parameters:
546 *
547 ******************************************************************************/
bta_hh_le_register_input_notif(tBTA_HH_DEV_CB * p_dev_cb,uint8_t proto_mode,bool register_ba)548 static void bta_hh_le_register_input_notif(tBTA_HH_DEV_CB* p_dev_cb,
549 uint8_t proto_mode,
550 bool register_ba) {
551 tBTA_HH_LE_RPT* p_rpt = &p_dev_cb->hid_srvc.report[0];
552
553 APPL_TRACE_DEBUG("%s: bta_hh_le_register_input_notif mode: %d", __func__,
554 proto_mode);
555
556 for (int i = 0; i < BTA_HH_LE_RPT_MAX; i++, p_rpt++) {
557 if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT) {
558 if (register_ba && p_rpt->uuid == GATT_UUID_BATTERY_LEVEL) {
559 BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr,
560 p_rpt->char_inst_id);
561 }
562 /* boot mode, deregister report input notification */
563 else if (proto_mode == BTA_HH_PROTO_BOOT_MODE) {
564 if (p_rpt->uuid == GATT_UUID_HID_REPORT &&
565 p_rpt->client_cfg_value == GATT_CLT_CONFIG_NOTIFICATION) {
566 APPL_TRACE_DEBUG("%s ---> Deregister Report ID: %d", __func__,
567 p_rpt->rpt_id);
568 BTA_GATTC_DeregisterForNotifications(
569 bta_hh_cb.gatt_if, p_dev_cb->addr, p_rpt->char_inst_id);
570 }
571 /* register boot reports notification */
572 else if (p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT ||
573 p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) {
574 APPL_TRACE_DEBUG("%s <--- Register Boot Report ID: %d", __func__,
575 p_rpt->rpt_id);
576 BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr,
577 p_rpt->char_inst_id);
578 }
579 } else if (proto_mode == BTA_HH_PROTO_RPT_MODE) {
580 if ((p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT ||
581 p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) &&
582 p_rpt->client_cfg_value == GATT_CLT_CONFIG_NOTIFICATION) {
583 APPL_TRACE_DEBUG("%s ---> Deregister Boot Report ID: %d", __func__,
584 p_rpt->rpt_id);
585 BTA_GATTC_DeregisterForNotifications(
586 bta_hh_cb.gatt_if, p_dev_cb->addr, p_rpt->char_inst_id);
587 } else if (p_rpt->uuid == GATT_UUID_HID_REPORT &&
588 p_rpt->client_cfg_value == GATT_CLT_CONFIG_NOTIFICATION) {
589 APPL_TRACE_DEBUG("%s <--- Register Report ID: %d", __func__,
590 p_rpt->rpt_id);
591 BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr,
592 p_rpt->char_inst_id);
593 }
594 }
595 /*
596 else unknow protocol mode */
597 }
598 }
599 }
600
601 /*******************************************************************************
602 *
603 * Function bta_hh_le_deregister_input_notif
604 *
605 * Description Deregister all notifications
606 *
607 ******************************************************************************/
bta_hh_le_deregister_input_notif(tBTA_HH_DEV_CB * p_dev_cb)608 static void bta_hh_le_deregister_input_notif(tBTA_HH_DEV_CB* p_dev_cb) {
609 tBTA_HH_LE_RPT* p_rpt = &p_dev_cb->hid_srvc.report[0];
610
611 for (uint8_t i = 0; i < BTA_HH_LE_RPT_MAX; i++, p_rpt++) {
612 if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT) {
613 if (p_rpt->uuid == GATT_UUID_HID_REPORT &&
614 p_rpt->client_cfg_value == GATT_CLT_CONFIG_NOTIFICATION) {
615 APPL_TRACE_DEBUG("%s ---> Deregister Report ID: %d", __func__,
616 p_rpt->rpt_id);
617 BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr,
618 p_rpt->char_inst_id);
619 } else if ((p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT ||
620 p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) &&
621 p_rpt->client_cfg_value == GATT_CLT_CONFIG_NOTIFICATION) {
622 APPL_TRACE_DEBUG("%s ---> Deregister Boot Report ID: %d", __func__,
623 p_rpt->rpt_id);
624 BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr,
625 p_rpt->char_inst_id);
626 }
627 }
628 }
629 }
630
631 /*******************************************************************************
632 *
633 * Function bta_hh_le_open_cmpl
634 *
635 * Description HID over GATT connection sucessfully opened
636 *
637 ******************************************************************************/
bta_hh_le_open_cmpl(tBTA_HH_DEV_CB * p_cb)638 static void bta_hh_le_open_cmpl(tBTA_HH_DEV_CB* p_cb) {
639 if (p_cb->disc_active == BTA_HH_LE_DISC_NONE) {
640 bta_hh_le_hid_report_dbg(p_cb);
641 bta_hh_le_register_input_notif(p_cb, p_cb->mode, true);
642 bta_hh_sm_execute(p_cb, BTA_HH_OPEN_CMPL_EVT, NULL);
643
644 if (kBTA_HH_LE_RECONN && p_cb->status == BTA_HH_OK) {
645 bta_hh_le_add_dev_bg_conn(p_cb, true);
646 }
647 }
648 }
649
650 /*******************************************************************************
651 *
652 * Function bta_hh_le_write_ccc
653 *
654 * Description Utility function to find and write client configuration of
655 * a characteristic
656 *
657 ******************************************************************************/
bta_hh_le_write_ccc(tBTA_HH_DEV_CB * p_cb,uint16_t char_handle,uint16_t clt_cfg_value,GATT_WRITE_OP_CB cb,void * cb_data)658 static bool bta_hh_le_write_ccc(tBTA_HH_DEV_CB* p_cb, uint16_t char_handle,
659 uint16_t clt_cfg_value, GATT_WRITE_OP_CB cb,
660 void* cb_data) {
661 const gatt::Descriptor* p_desc = find_descriptor_by_short_uuid(
662 p_cb->conn_id, char_handle, GATT_UUID_CHAR_CLIENT_CONFIG);
663 if (!p_desc) return false;
664
665 vector<uint8_t> value(2);
666 uint8_t* ptr = value.data();
667 UINT16_TO_STREAM(ptr, clt_cfg_value);
668
669 BtaGattQueue::WriteDescriptor(p_cb->conn_id, p_desc->handle, std::move(value),
670 GATT_WRITE, cb, cb_data);
671 return true;
672 }
673
674 static bool bta_hh_le_write_rpt_clt_cfg(tBTA_HH_DEV_CB* p_cb);
675
write_rpt_ctl_cfg_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t * value,void * data)676 static void write_rpt_ctl_cfg_cb(uint16_t conn_id, tGATT_STATUS status,
677 uint16_t handle, uint16_t len,
678 const uint8_t* value, void* data) {
679 uint8_t srvc_inst_id;
680
681 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
682 const gatt::Characteristic* characteristic =
683 BTA_GATTC_GetOwningCharacteristic(conn_id, handle);
684 uint16_t char_uuid = characteristic->uuid.As16Bit();
685
686 srvc_inst_id = BTA_GATTC_GetOwningService(conn_id, handle)->handle;
687 switch (char_uuid) {
688 case GATT_UUID_BATTERY_LEVEL: /* battery level clt cfg registered */
689 bta_hh_le_find_service_inst_by_battery_inst_id(p_dev_cb, srvc_inst_id);
690 FALLTHROUGH_INTENDED; /* FALLTHROUGH */
691 case GATT_UUID_HID_BT_KB_INPUT:
692 case GATT_UUID_HID_BT_MOUSE_INPUT:
693 case GATT_UUID_HID_REPORT:
694 if (status == GATT_SUCCESS)
695 p_dev_cb->hid_srvc.report[p_dev_cb->clt_cfg_idx].client_cfg_value =
696 GATT_CLT_CONFIG_NOTIFICATION;
697 p_dev_cb->clt_cfg_idx++;
698 bta_hh_le_write_rpt_clt_cfg(p_dev_cb);
699 break;
700
701 default:
702 APPL_TRACE_ERROR("Unknown char ID clt cfg: 0x%04x", char_uuid);
703 }
704 }
705 /*******************************************************************************
706 *
707 * Function bta_hh_le_write_rpt_clt_cfg
708 *
709 * Description write client configuration. This is only for input report
710 * enable all input notification upon connection open.
711 *
712 ******************************************************************************/
bta_hh_le_write_rpt_clt_cfg(tBTA_HH_DEV_CB * p_cb)713 static bool bta_hh_le_write_rpt_clt_cfg(tBTA_HH_DEV_CB* p_cb) {
714 uint8_t i;
715 tBTA_HH_LE_RPT* p_rpt = &p_cb->hid_srvc.report[p_cb->clt_cfg_idx];
716
717 for (i = p_cb->clt_cfg_idx; i < BTA_HH_LE_RPT_MAX && p_rpt->in_use;
718 i++, p_rpt++) {
719 /* enable notification for all input report, regardless mode */
720 if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT) {
721 if (bta_hh_le_write_ccc(p_cb, p_rpt->char_inst_id,
722 GATT_CLT_CONFIG_NOTIFICATION,
723 write_rpt_ctl_cfg_cb, p_cb)) {
724 p_cb->clt_cfg_idx = i;
725 return true;
726 }
727 }
728 }
729 p_cb->clt_cfg_idx = 0;
730
731 /* client configuration is completed, send open callback */
732 if (p_cb->state == BTA_HH_W4_CONN_ST) {
733 p_cb->disc_active &= ~BTA_HH_LE_DISC_HIDS;
734
735 bta_hh_le_open_cmpl(p_cb);
736 }
737 return false;
738 }
739
write_proto_mode_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t * value,void * data)740 static void write_proto_mode_cb(uint16_t conn_id, tGATT_STATUS status,
741 uint16_t handle, uint16_t len,
742 const uint8_t* value, void* data) {
743 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
744
745 if (p_dev_cb->state == BTA_HH_CONN_ST) {
746 /* Set protocol finished in CONN state*/
747
748 uint16_t cb_evt = p_dev_cb->w4_evt;
749 if (cb_evt == 0) return;
750
751 tBTA_HH_CBDATA cback_data;
752
753 cback_data.handle = p_dev_cb->hid_handle;
754 cback_data.status = (status == GATT_SUCCESS) ? BTA_HH_OK : BTA_HH_ERR;
755
756 if (status == GATT_SUCCESS)
757 bta_hh_le_register_input_notif(p_dev_cb, p_dev_cb->mode, false);
758
759 p_dev_cb->w4_evt = 0;
760 (*bta_hh_cb.p_cback)(cb_evt, (tBTA_HH*)&cback_data);
761 } else if (p_dev_cb->state == BTA_HH_W4_CONN_ST) {
762 p_dev_cb->status = (status == GATT_SUCCESS) ? BTA_HH_OK : BTA_HH_ERR_PROTO;
763
764 if ((p_dev_cb->disc_active & BTA_HH_LE_DISC_HIDS) == 0)
765 bta_hh_le_open_cmpl(p_dev_cb);
766 }
767 }
768
769 /*******************************************************************************
770 *
771 * Function bta_hh_le_set_protocol_mode
772 *
773 * Description Set remote device protocol mode.
774 *
775 ******************************************************************************/
bta_hh_le_set_protocol_mode(tBTA_HH_DEV_CB * p_cb,tBTA_HH_PROTO_MODE mode)776 static bool bta_hh_le_set_protocol_mode(tBTA_HH_DEV_CB* p_cb,
777 tBTA_HH_PROTO_MODE mode) {
778 tBTA_HH_CBDATA cback_data;
779
780 APPL_TRACE_DEBUG("%s attempt mode: %s", __func__,
781 (mode == BTA_HH_PROTO_RPT_MODE) ? "Report" : "Boot");
782
783 cback_data.handle = p_cb->hid_handle;
784 /* boot mode is not supported in the remote device */
785 if (p_cb->hid_srvc.proto_mode_handle == 0) {
786 p_cb->mode = BTA_HH_PROTO_RPT_MODE;
787
788 if (mode == BTA_HH_PROTO_BOOT_MODE) {
789 APPL_TRACE_ERROR("Set Boot Mode failed!! No PROTO_MODE Char!");
790 cback_data.status = BTA_HH_ERR;
791 } else {
792 /* if set to report mode, need to de-register all input report
793 * notification */
794 bta_hh_le_register_input_notif(p_cb, p_cb->mode, false);
795 cback_data.status = BTA_HH_OK;
796 }
797 if (p_cb->state == BTA_HH_W4_CONN_ST) {
798 p_cb->status =
799 (cback_data.status == BTA_HH_OK) ? BTA_HH_OK : BTA_HH_ERR_PROTO;
800 } else
801 (*bta_hh_cb.p_cback)(BTA_HH_SET_PROTO_EVT, (tBTA_HH*)&cback_data);
802 } else if (p_cb->mode != mode) {
803 p_cb->mode = mode;
804 mode = (mode == BTA_HH_PROTO_BOOT_MODE) ? BTA_HH_LE_PROTO_BOOT_MODE
805 : BTA_HH_LE_PROTO_REPORT_MODE;
806
807 BtaGattQueue::WriteCharacteristic(
808 p_cb->conn_id, p_cb->hid_srvc.proto_mode_handle, {mode},
809 GATT_WRITE_NO_RSP, write_proto_mode_cb, p_cb);
810 return true;
811 }
812
813 return false;
814 }
815
816 /*******************************************************************************
817 * Function get_protocol_mode_cb
818 *
819 * Description Process the Read protocol mode, send GET_PROTO_EVT to
820 * application with the protocol mode.
821 *
822 ******************************************************************************/
get_protocol_mode_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)823 static void get_protocol_mode_cb(uint16_t conn_id, tGATT_STATUS status,
824 uint16_t handle, uint16_t len, uint8_t* value,
825 void* data) {
826 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
827 tBTA_HH_HSDATA hs_data;
828
829 hs_data.status = BTA_HH_ERR;
830 hs_data.handle = p_dev_cb->hid_handle;
831 hs_data.rsp_data.proto_mode = p_dev_cb->mode;
832
833 if (status == GATT_SUCCESS && len) {
834 hs_data.status = BTA_HH_OK;
835 /* match up BTE/BTA report/boot mode def*/
836 hs_data.rsp_data.proto_mode = *(value);
837 /* LE repot mode is the opposite value of BR/EDR report mode, flip it here
838 */
839 if (hs_data.rsp_data.proto_mode == 0)
840 hs_data.rsp_data.proto_mode = BTA_HH_PROTO_BOOT_MODE;
841 else
842 hs_data.rsp_data.proto_mode = BTA_HH_PROTO_RPT_MODE;
843
844 p_dev_cb->mode = hs_data.rsp_data.proto_mode;
845 }
846
847 APPL_TRACE_DEBUG("LE GET_PROTOCOL Mode = [%s]",
848 (hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE)
849 ? "Report"
850 : "Boot");
851
852 p_dev_cb->w4_evt = 0;
853 (*bta_hh_cb.p_cback)(BTA_HH_GET_PROTO_EVT, (tBTA_HH*)&hs_data);
854 }
855
856 /*******************************************************************************
857 *
858 * Function bta_hh_le_get_protocol_mode
859 *
860 * Description Get remote device protocol mode.
861 *
862 ******************************************************************************/
bta_hh_le_get_protocol_mode(tBTA_HH_DEV_CB * p_cb)863 static void bta_hh_le_get_protocol_mode(tBTA_HH_DEV_CB* p_cb) {
864 tBTA_HH_HSDATA hs_data;
865 p_cb->w4_evt = BTA_HH_GET_PROTO_EVT;
866
867 if (p_cb->hid_srvc.in_use && p_cb->hid_srvc.proto_mode_handle != 0) {
868 BtaGattQueue::ReadCharacteristic(p_cb->conn_id,
869 p_cb->hid_srvc.proto_mode_handle,
870 get_protocol_mode_cb, p_cb);
871 return;
872 }
873
874 /* no service support protocol_mode, by default report mode */
875 hs_data.status = BTA_HH_OK;
876 hs_data.handle = p_cb->hid_handle;
877 hs_data.rsp_data.proto_mode = BTA_HH_PROTO_RPT_MODE;
878 p_cb->w4_evt = 0;
879 (*bta_hh_cb.p_cback)(BTA_HH_GET_PROTO_EVT, (tBTA_HH*)&hs_data);
880 }
881
882 /*******************************************************************************
883 *
884 * Function bta_hh_le_dis_cback
885 *
886 * Description DIS read complete callback
887 *
888 * Parameters:
889 *
890 ******************************************************************************/
bta_hh_le_dis_cback(const RawAddress & addr,tDIS_VALUE * p_dis_value)891 static void bta_hh_le_dis_cback(const RawAddress& addr,
892 tDIS_VALUE* p_dis_value) {
893 tBTA_HH_DEV_CB* p_cb = bta_hh_le_find_dev_cb_by_bda(addr);
894
895 if (p_cb == NULL || p_dis_value == NULL) {
896 APPL_TRACE_ERROR("received unexpected/error DIS callback");
897 return;
898 }
899
900 p_cb->disc_active &= ~BTA_HH_LE_DISC_DIS;
901 /* plug in the PnP info for this device */
902 if (p_dis_value->attr_mask & DIS_ATTR_PNP_ID_BIT) {
903 APPL_TRACE_DEBUG(
904 "Plug in PnP info: product_id = %02x, vendor_id = %04x, version = %04x",
905 p_dis_value->pnp_id.product_id, p_dis_value->pnp_id.vendor_id,
906 p_dis_value->pnp_id.product_version);
907 p_cb->dscp_info.product_id = p_dis_value->pnp_id.product_id;
908 p_cb->dscp_info.vendor_id = p_dis_value->pnp_id.vendor_id;
909 p_cb->dscp_info.version = p_dis_value->pnp_id.product_version;
910 }
911 bta_hh_le_open_cmpl(p_cb);
912 }
913
914 /*******************************************************************************
915 *
916 * Function bta_hh_le_pri_service_discovery
917 *
918 * Description Initialize GATT discovery on the remote LE HID device by
919 * opening a GATT connection first.
920 *
921 * Parameters:
922 *
923 ******************************************************************************/
bta_hh_le_pri_service_discovery(tBTA_HH_DEV_CB * p_cb)924 static void bta_hh_le_pri_service_discovery(tBTA_HH_DEV_CB* p_cb) {
925 bta_hh_le_co_reset_rpt_cache(p_cb->addr, p_cb->app_id);
926
927 p_cb->disc_active |= (BTA_HH_LE_DISC_HIDS | BTA_HH_LE_DISC_DIS);
928
929 /* read DIS info */
930 if (!DIS_ReadDISInfo(p_cb->addr, bta_hh_le_dis_cback, DIS_ATTR_PNP_ID_BIT)) {
931 APPL_TRACE_ERROR("read DIS failed");
932 p_cb->disc_active &= ~BTA_HH_LE_DISC_DIS;
933 }
934
935 /* in parallel */
936 /* start primary service discovery for HID service */
937 Uuid pri_srvc = Uuid::From16Bit(UUID_SERVCLASS_LE_HID);
938 BTA_GATTC_ServiceSearchRequest(p_cb->conn_id, &pri_srvc);
939 return;
940 }
941
942 /*******************************************************************************
943 *
944 * Function bta_hh_le_encrypt_cback
945 *
946 * Description link encryption complete callback for bond verification.
947 *
948 * Returns None
949 *
950 ******************************************************************************/
bta_hh_le_encrypt_cback(const RawAddress * bd_addr,UNUSED_ATTR tBT_TRANSPORT transport,UNUSED_ATTR void * p_ref_data,tBTM_STATUS result)951 static void bta_hh_le_encrypt_cback(const RawAddress* bd_addr,
952 UNUSED_ATTR tBT_TRANSPORT transport,
953 UNUSED_ATTR void* p_ref_data,
954 tBTM_STATUS result) {
955 tBTA_HH_DEV_CB* p_dev_cb = bta_hh_get_cb(*bd_addr);
956 if (p_dev_cb == nullptr) {
957 LOG_ERROR("unexpected encryption callback, ignore");
958 return;
959 }
960
961 // TODO Collapse the duplicated status values
962 p_dev_cb->status = (result == BTM_SUCCESS) ? BTA_HH_OK : BTA_HH_ERR_SEC;
963 p_dev_cb->btm_status = result;
964
965 bta_hh_sm_execute(p_dev_cb, BTA_HH_ENC_CMPL_EVT, NULL);
966 }
967
968 /*******************************************************************************
969 *
970 * Function bta_hh_security_cmpl
971 *
972 * Description Security check completed, start the service discovery
973 * if no cache available, otherwise report connection open
974 * completed
975 *
976 * Parameters:
977 *
978 ******************************************************************************/
bta_hh_security_cmpl(tBTA_HH_DEV_CB * p_cb,UNUSED_ATTR const tBTA_HH_DATA * p_buf)979 void bta_hh_security_cmpl(tBTA_HH_DEV_CB* p_cb,
980 UNUSED_ATTR const tBTA_HH_DATA* p_buf) {
981 APPL_TRACE_DEBUG("%s", __func__);
982 if (p_cb->status == BTA_HH_OK) {
983 if (!p_cb->hid_srvc.in_use) {
984 APPL_TRACE_DEBUG("bta_hh_security_cmpl no reports loaded, try to load");
985
986 /* start loading the cache if not in stack */
987 tBTA_HH_RPT_CACHE_ENTRY* p_rpt_cache;
988 uint8_t num_rpt = 0;
989 if ((p_rpt_cache = bta_hh_le_co_cache_load(p_cb->addr, &num_rpt,
990 p_cb->app_id)) != NULL) {
991 bta_hh_process_cache_rpt(p_cb, p_rpt_cache, num_rpt);
992 }
993 }
994 /* discovery has been done for HID service */
995 if (p_cb->app_id != 0 && p_cb->hid_srvc.in_use) {
996 APPL_TRACE_DEBUG("%s: discovery has been done for HID service", __func__);
997 /* configure protocol mode */
998 if (!bta_hh_le_set_protocol_mode(p_cb, p_cb->mode)) {
999 bta_hh_le_open_cmpl(p_cb);
1000 }
1001 }
1002 /* start primary service discovery for HID service */
1003 else {
1004 APPL_TRACE_DEBUG("%s: Starting service discovery", __func__);
1005 bta_hh_le_pri_service_discovery(p_cb);
1006 }
1007 }
1008 else if(p_cb->btm_status == BTM_ERR_KEY_MISSING) {
1009 LOG_ERROR("Received encryption failed status:%s btm_status:%s",
1010 bta_hh_status_text(p_cb->status).c_str(),
1011 btm_status_text(p_cb->btm_status).c_str());
1012 bta_dm_process_delete_key_RC_to_unpair(p_cb->addr);
1013 } else {
1014 LOG_ERROR("Encryption failed status:%s btm_status:%s",
1015 bta_hh_status_text(p_cb->status).c_str(),
1016 btm_status_text(p_cb->btm_status).c_str());
1017 if (!(p_cb->status == BTA_HH_ERR_SEC &&
1018 p_cb->btm_status == BTM_ERR_PROCESSING))
1019 bta_hh_le_api_disc_act(p_cb);
1020 }
1021 }
1022
1023 /*******************************************************************************
1024 *
1025 * Function bta_hh_le_notify_enc_cmpl
1026 *
1027 * Description process GATT encryption complete event
1028 *
1029 * Returns
1030 *
1031 ******************************************************************************/
bta_hh_le_notify_enc_cmpl(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_buf)1032 void bta_hh_le_notify_enc_cmpl(tBTA_HH_DEV_CB* p_cb,
1033 const tBTA_HH_DATA* p_buf) {
1034 if (p_cb == NULL || !p_cb->security_pending || p_buf == NULL ||
1035 p_buf->le_enc_cmpl.client_if != bta_hh_cb.gatt_if) {
1036 return;
1037 }
1038
1039 p_cb->security_pending = false;
1040 bta_hh_start_security(p_cb, NULL);
1041 }
1042
1043 /*******************************************************************************
1044 *
1045 * Function bta_hh_clear_service_cache
1046 *
1047 * Description clear the service cache
1048 *
1049 * Parameters:
1050 *
1051 ******************************************************************************/
bta_hh_clear_service_cache(tBTA_HH_DEV_CB * p_cb)1052 static void bta_hh_clear_service_cache(tBTA_HH_DEV_CB* p_cb) {
1053 tBTA_HH_LE_HID_SRVC* p_hid_srvc = &p_cb->hid_srvc;
1054
1055 p_cb->app_id = 0;
1056 p_cb->dscp_info.descriptor.dsc_list = NULL;
1057
1058 osi_free_and_reset((void**)&p_hid_srvc->rpt_map);
1059 memset(p_hid_srvc, 0, sizeof(tBTA_HH_LE_HID_SRVC));
1060 }
1061
1062 /*******************************************************************************
1063 *
1064 * Function bta_hh_start_security
1065 *
1066 * Description start the security check of the established connection
1067 *
1068 * Parameters:
1069 *
1070 ******************************************************************************/
bta_hh_start_security(tBTA_HH_DEV_CB * p_cb,UNUSED_ATTR const tBTA_HH_DATA * p_buf)1071 void bta_hh_start_security(tBTA_HH_DEV_CB* p_cb,
1072 UNUSED_ATTR const tBTA_HH_DATA* p_buf) {
1073 if (BTM_SecIsSecurityPending(p_cb->addr)) {
1074 /* if security collision happened, wait for encryption done */
1075 p_cb->security_pending = true;
1076 return;
1077 }
1078
1079 /* if link has been encrypted */
1080 if (BTM_IsEncrypted(p_cb->addr, BT_TRANSPORT_LE)) {
1081 p_cb->status = BTA_HH_OK;
1082 bta_hh_sm_execute(p_cb, BTA_HH_ENC_CMPL_EVT, NULL);
1083 }
1084 /* if bonded and link not encrypted */
1085 else if (BTM_IsLinkKeyKnown(p_cb->addr, BT_TRANSPORT_LE)) {
1086 p_cb->status = BTA_HH_ERR_AUTH_FAILED;
1087 BTM_SetEncryption(p_cb->addr, BT_TRANSPORT_LE, bta_hh_le_encrypt_cback,
1088 NULL, BTM_BLE_SEC_ENCRYPT);
1089 }
1090 /* unbonded device, report security error here */
1091 else {
1092 p_cb->status = BTA_HH_ERR_AUTH_FAILED;
1093 bta_hh_clear_service_cache(p_cb);
1094 BTM_SetEncryption(p_cb->addr, BT_TRANSPORT_LE, bta_hh_le_encrypt_cback,
1095 NULL, BTM_BLE_SEC_ENCRYPT_NO_MITM);
1096 }
1097 }
1098
1099 /*******************************************************************************
1100 *
1101 * Function bta_hh_gatt_open
1102 *
1103 * Description process GATT open event.
1104 *
1105 * Parameters:
1106 *
1107 ******************************************************************************/
bta_hh_gatt_open(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_buf)1108 void bta_hh_gatt_open(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_buf) {
1109 const tBTA_GATTC_OPEN* p_data = &p_buf->le_open;
1110 const uint8_t* p2;
1111
1112 /* if received invalid callback data , ignore it */
1113 if (p_cb == NULL || p_data == NULL) return;
1114
1115 p2 = p_data->remote_bda.address;
1116
1117 APPL_TRACE_DEBUG(
1118 "bta_hh_gatt_open BTA_GATTC_OPEN_EVT bda= [%08x%04x] status =%d",
1119 ((p2[0]) << 24) + ((p2[1]) << 16) + ((p2[2]) << 8) + (p2[3]),
1120 ((p2[4]) << 8) + p2[5], p_data->status);
1121
1122 if (p_data->status == GATT_SUCCESS) {
1123 p_cb->hid_handle = bta_hh_le_get_le_dev_hdl(p_cb->index);
1124 if (p_cb->hid_handle == BTA_HH_IDX_INVALID) {
1125 p_cb->conn_id = p_data->conn_id;
1126 bta_hh_le_api_disc_act(p_cb);
1127 return;
1128 }
1129 p_cb->is_le_device = true;
1130 p_cb->in_use = true;
1131 p_cb->conn_id = p_data->conn_id;
1132
1133 bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index;
1134
1135 BtaGattQueue::Clean(p_cb->conn_id);
1136
1137 APPL_TRACE_DEBUG("hid_handle = %2x conn_id = %04x cb_index = %d",
1138 p_cb->hid_handle, p_cb->conn_id, p_cb->index);
1139
1140 bta_hh_sm_execute(p_cb, BTA_HH_START_ENC_EVT, NULL);
1141
1142 } else {
1143 /* open failure */
1144 tBTA_HH_DATA bta_hh_data;
1145 bta_hh_data.status = BTA_HH_ERR;
1146 bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data);
1147 }
1148 }
1149
1150 /*******************************************************************************
1151 *
1152 * Function bta_hh_le_close
1153 *
1154 * Description This function converts the GATT close event and post it as a
1155 * BTA HH internal event.
1156 *
1157 ******************************************************************************/
bta_hh_le_close(const tBTA_GATTC_CLOSE & gattc_data)1158 static void bta_hh_le_close(const tBTA_GATTC_CLOSE& gattc_data) {
1159 tBTA_HH_DEV_CB* p_cb = bta_hh_le_find_dev_cb_by_bda(gattc_data.remote_bda);
1160 if (p_cb == nullptr) {
1161 LOG_WARN("Received close event with unknown device:%s",
1162 PRIVATE_ADDRESS(gattc_data.remote_bda));
1163 return;
1164 }
1165 p_cb->conn_id = GATT_INVALID_CONN_ID;
1166 p_cb->security_pending = false;
1167
1168 post_on_bt_main([=]() {
1169 const tBTA_HH_DATA data = {
1170 .le_close =
1171 {
1172 .conn_id = gattc_data.conn_id,
1173 .reason = gattc_data.reason,
1174 .hdr =
1175 {
1176 .event = BTA_HH_GATT_CLOSE_EVT,
1177 .layer_specific =
1178 static_cast<uint16_t>(p_cb->hid_handle),
1179 },
1180 },
1181 };
1182 bta_hh_sm_execute(p_cb, BTA_HH_GATT_CLOSE_EVT, &data);
1183 });
1184 }
1185
1186 /*******************************************************************************
1187 *
1188 * Function bta_hh_le_gatt_disc_cmpl
1189 *
1190 * Description Check to see if the remote device is a LE only device
1191 *
1192 * Parameters:
1193 *
1194 ******************************************************************************/
bta_hh_le_gatt_disc_cmpl(tBTA_HH_DEV_CB * p_cb,tBTA_HH_STATUS status)1195 static void bta_hh_le_gatt_disc_cmpl(tBTA_HH_DEV_CB* p_cb,
1196 tBTA_HH_STATUS status) {
1197 APPL_TRACE_DEBUG("bta_hh_le_gatt_disc_cmpl ");
1198
1199 /* if open sucessful or protocol mode not desired, keep the connection open
1200 * but inform app */
1201 if (status == BTA_HH_OK || status == BTA_HH_ERR_PROTO) {
1202 /* assign a special APP ID temp, since device type unknown */
1203 p_cb->app_id = BTA_HH_APP_ID_LE;
1204
1205 /* set report notification configuration */
1206 p_cb->clt_cfg_idx = 0;
1207 bta_hh_le_write_rpt_clt_cfg(p_cb);
1208 } else /* error, close the GATT connection */
1209 {
1210 /* close GATT connection if it's on */
1211 bta_hh_le_api_disc_act(p_cb);
1212 }
1213 }
1214
read_hid_info_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)1215 static void read_hid_info_cb(uint16_t conn_id, tGATT_STATUS status,
1216 uint16_t handle, uint16_t len, uint8_t* value,
1217 void* data) {
1218 if (status != GATT_SUCCESS) {
1219 APPL_TRACE_ERROR("%s: error: %d", __func__, status);
1220 return;
1221 }
1222
1223 if (len != 4) {
1224 APPL_TRACE_ERROR("%s: wrong length: %d", __func__, len);
1225 return;
1226 }
1227
1228 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
1229 uint8_t* pp = value;
1230 /* save device information */
1231 STREAM_TO_UINT16(p_dev_cb->dscp_info.version, pp);
1232 STREAM_TO_UINT8(p_dev_cb->dscp_info.ctry_code, pp);
1233 STREAM_TO_UINT8(p_dev_cb->dscp_info.flag, pp);
1234 }
1235
read_hid_report_map_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)1236 static void read_hid_report_map_cb(uint16_t conn_id, tGATT_STATUS status,
1237 uint16_t handle, uint16_t len,
1238 uint8_t* value, void* data) {
1239 if (status != GATT_SUCCESS) {
1240 APPL_TRACE_ERROR("%s: error reading characteristic: %d", __func__, status);
1241 return;
1242 }
1243
1244 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
1245 tBTA_HH_LE_HID_SRVC* p_srvc = &p_dev_cb->hid_srvc;
1246
1247 osi_free_and_reset((void**)&p_srvc->rpt_map);
1248
1249 if (len > 0) {
1250 p_srvc->rpt_map = (uint8_t*)osi_malloc(len);
1251
1252 uint8_t* pp = value;
1253 STREAM_TO_ARRAY(p_srvc->rpt_map, pp, len);
1254 p_srvc->descriptor.dl_len = len;
1255 p_srvc->descriptor.dsc_list = p_dev_cb->hid_srvc.rpt_map;
1256 }
1257 }
1258
read_ext_rpt_ref_desc_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)1259 static void read_ext_rpt_ref_desc_cb(uint16_t conn_id, tGATT_STATUS status,
1260 uint16_t handle, uint16_t len,
1261 uint8_t* value, void* data) {
1262 if (status != GATT_SUCCESS) {
1263 APPL_TRACE_ERROR("%s: error: %d", __func__, status);
1264 return;
1265 }
1266
1267 /* if the length of the descriptor value is right, parse it assume it's a 16
1268 * bits UUID */
1269 if (len != Uuid::kNumBytes16) {
1270 APPL_TRACE_ERROR("%s: we support only 16bit UUID: %d", __func__, len);
1271 return;
1272 }
1273
1274 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
1275 uint8_t* pp = value;
1276
1277 STREAM_TO_UINT16(p_dev_cb->hid_srvc.ext_rpt_ref, pp);
1278
1279 APPL_TRACE_DEBUG("%s: External Report Reference UUID 0x%04x", __func__,
1280 p_dev_cb->hid_srvc.ext_rpt_ref);
1281 }
1282
read_report_ref_desc_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)1283 static void read_report_ref_desc_cb(uint16_t conn_id, tGATT_STATUS status,
1284 uint16_t handle, uint16_t len,
1285 uint8_t* value, void* data) {
1286 if (status != GATT_SUCCESS) {
1287 APPL_TRACE_ERROR("%s: error: %d", __func__, status);
1288 return;
1289 }
1290
1291 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
1292 const gatt::Descriptor* p_desc = BTA_GATTC_GetDescriptor(conn_id, handle);
1293
1294 if (!p_desc) {
1295 APPL_TRACE_ERROR("%s: error: descriptor is null!", __func__);
1296 return;
1297 }
1298
1299 const gatt::Characteristic* characteristic =
1300 BTA_GATTC_GetOwningCharacteristic(conn_id, handle);
1301 const gatt::Service* service =
1302 BTA_GATTC_GetOwningService(conn_id, characteristic->value_handle);
1303
1304 tBTA_HH_LE_RPT* p_rpt;
1305 p_rpt = bta_hh_le_find_report_entry(p_dev_cb, service->handle,
1306 GATT_UUID_HID_REPORT,
1307 characteristic->value_handle);
1308 if (p_rpt) bta_hh_le_save_report_ref(p_dev_cb, p_rpt, status, value, len);
1309 }
1310
read_pref_conn_params_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)1311 static void read_pref_conn_params_cb(uint16_t conn_id, tGATT_STATUS status,
1312 uint16_t handle, uint16_t len,
1313 uint8_t* value, void* data) {
1314 if (status != GATT_SUCCESS) {
1315 APPL_TRACE_ERROR("%s: error: %d", __func__, status);
1316 return;
1317 }
1318
1319 if (len != 8) {
1320 APPL_TRACE_ERROR("%s: we support only 16bit UUID: %d", __func__, len);
1321 return;
1322 }
1323
1324 // TODO(jpawlowski): this should be done by GAP profile, remove when GAP is
1325 // fixed.
1326 uint8_t* pp = value;
1327 uint16_t min_interval, max_interval, latency, timeout;
1328 STREAM_TO_UINT16(min_interval, pp);
1329 STREAM_TO_UINT16(max_interval, pp);
1330 STREAM_TO_UINT16(latency, pp);
1331 STREAM_TO_UINT16(timeout, pp);
1332
1333 // Make sure both min, and max are bigger than 11.25ms, lower values can
1334 // introduce audio issues if A2DP is also active.
1335 L2CA_AdjustConnectionIntervals(&min_interval, &max_interval,
1336 BTM_BLE_CONN_INT_MIN_LIMIT);
1337
1338 // If the device has no preferred connection timeout, use the default.
1339 if (timeout == BTM_BLE_CONN_PARAM_UNDEF) timeout = BTM_BLE_CONN_TIMEOUT_DEF;
1340
1341 if (min_interval < BTM_BLE_CONN_INT_MIN ||
1342 min_interval > BTM_BLE_CONN_INT_MAX ||
1343 max_interval < BTM_BLE_CONN_INT_MIN ||
1344 max_interval > BTM_BLE_CONN_INT_MAX ||
1345 latency > BTM_BLE_CONN_LATENCY_MAX ||
1346 timeout < BTM_BLE_CONN_SUP_TOUT_MIN ||
1347 timeout > BTM_BLE_CONN_SUP_TOUT_MAX || max_interval < min_interval) {
1348 APPL_TRACE_ERROR(
1349 "%s: Invalid connection parameters. min=%d, max=%d, latency=%d, "
1350 "timeout=%d",
1351 __func__, min_interval, max_interval, latency, timeout);
1352 return;
1353 }
1354
1355 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
1356
1357 if (interop_match_addr(INTEROP_HID_PREF_CONN_SUP_TIMEOUT_3S,
1358 (RawAddress*)&p_dev_cb->addr)) {
1359 if (timeout < 300) timeout = 300;
1360 }
1361
1362 BTM_BleSetPrefConnParams(p_dev_cb->addr, min_interval, max_interval, latency,
1363 timeout);
1364 L2CA_UpdateBleConnParams(p_dev_cb->addr, min_interval, max_interval, latency,
1365 timeout, 0, 0);
1366 }
1367
1368 /*******************************************************************************
1369 *
1370 * Function bta_hh_le_search_hid_chars
1371 *
1372 * Description This function discover all characteristics a service and
1373 * all descriptors available.
1374 *
1375 * Parameters:
1376 *
1377 ******************************************************************************/
bta_hh_le_search_hid_chars(tBTA_HH_DEV_CB * p_dev_cb,const gatt::Service * service)1378 static void bta_hh_le_search_hid_chars(tBTA_HH_DEV_CB* p_dev_cb,
1379 const gatt::Service* service) {
1380 tBTA_HH_LE_RPT* p_rpt;
1381
1382 for (const gatt::Characteristic& charac : service->characteristics) {
1383 if (!charac.uuid.Is16Bit()) continue;
1384
1385 uint16_t uuid16 = charac.uuid.As16Bit();
1386 LOG_INFO("%s: %s %s", __func__, bta_hh_uuid_to_str(uuid16),
1387 charac.uuid.ToString().c_str());
1388
1389 switch (uuid16) {
1390 case GATT_UUID_HID_CONTROL_POINT:
1391 p_dev_cb->hid_srvc.control_point_handle = charac.value_handle;
1392 break;
1393 case GATT_UUID_HID_INFORMATION:
1394 /* only one instance per HID service */
1395 BtaGattQueue::ReadCharacteristic(p_dev_cb->conn_id, charac.value_handle,
1396 read_hid_info_cb, p_dev_cb);
1397 break;
1398 case GATT_UUID_HID_REPORT_MAP:
1399 /* only one instance per HID service */
1400 BtaGattQueue::ReadCharacteristic(p_dev_cb->conn_id, charac.value_handle,
1401 read_hid_report_map_cb, p_dev_cb);
1402 /* descriptor is optional */
1403 bta_hh_le_read_char_descriptor(p_dev_cb, charac.value_handle,
1404 GATT_UUID_EXT_RPT_REF_DESCR,
1405 read_ext_rpt_ref_desc_cb, p_dev_cb);
1406 break;
1407
1408 case GATT_UUID_HID_REPORT:
1409 p_rpt = bta_hh_le_find_alloc_report_entry(
1410 p_dev_cb, p_dev_cb->hid_srvc.srvc_inst_id, GATT_UUID_HID_REPORT,
1411 charac.value_handle);
1412 if (p_rpt == NULL) {
1413 APPL_TRACE_ERROR("%s: Add report entry failed !!!", __func__);
1414 break;
1415 }
1416
1417 if (p_rpt->rpt_type != BTA_HH_RPTT_INPUT) break;
1418
1419 bta_hh_le_read_char_descriptor(p_dev_cb, charac.value_handle,
1420 GATT_UUID_RPT_REF_DESCR,
1421 read_report_ref_desc_cb, p_dev_cb);
1422 break;
1423
1424 /* found boot mode report types */
1425 case GATT_UUID_HID_BT_KB_OUTPUT:
1426 case GATT_UUID_HID_BT_MOUSE_INPUT:
1427 case GATT_UUID_HID_BT_KB_INPUT:
1428 if (bta_hh_le_find_alloc_report_entry(p_dev_cb, service->handle, uuid16,
1429 charac.value_handle) == NULL)
1430 APPL_TRACE_ERROR("%s: Add report entry failed !!!", __func__);
1431
1432 break;
1433
1434 default:
1435 APPL_TRACE_DEBUG("%s: not processing %s 0x%04d", __func__,
1436 bta_hh_uuid_to_str(uuid16), uuid16);
1437 }
1438 }
1439
1440 /* Make sure PROTO_MODE is processed as last */
1441 for (const gatt::Characteristic& charac : service->characteristics) {
1442 if (charac.uuid == Uuid::From16Bit(GATT_UUID_HID_PROTO_MODE)) {
1443 p_dev_cb->hid_srvc.proto_mode_handle = charac.value_handle;
1444 bta_hh_le_set_protocol_mode(p_dev_cb, p_dev_cb->mode);
1445 break;
1446 }
1447 }
1448 }
1449
1450 /*******************************************************************************
1451 *
1452 * Function bta_hh_le_srvc_search_cmpl
1453 *
1454 * Description This function process the GATT service search complete.
1455 *
1456 * Parameters:
1457 *
1458 ******************************************************************************/
bta_hh_le_srvc_search_cmpl(tBTA_GATTC_SEARCH_CMPL * p_data)1459 static void bta_hh_le_srvc_search_cmpl(tBTA_GATTC_SEARCH_CMPL* p_data) {
1460 tBTA_HH_DEV_CB* p_dev_cb = bta_hh_le_find_dev_cb_by_conn_id(p_data->conn_id);
1461
1462 /* service search exception or no HID service is supported on remote */
1463 if (p_dev_cb == NULL) return;
1464
1465 if (p_data->status != GATT_SUCCESS) {
1466 p_dev_cb->status = BTA_HH_ERR_SDP;
1467 /* close the connection and report service discovery complete with error */
1468 bta_hh_le_api_disc_act(p_dev_cb);
1469 return;
1470 }
1471
1472 const std::list<gatt::Service>* services =
1473 BTA_GATTC_GetServices(p_data->conn_id);
1474
1475 bool have_hid = false;
1476 for (const gatt::Service& service : *services) {
1477 if (service.uuid == Uuid::From16Bit(UUID_SERVCLASS_LE_HID) &&
1478 service.is_primary && !have_hid) {
1479 have_hid = true;
1480
1481 /* found HID primamry service */
1482 p_dev_cb->hid_srvc.in_use = true;
1483 p_dev_cb->hid_srvc.srvc_inst_id = service.handle;
1484 p_dev_cb->hid_srvc.proto_mode_handle = 0;
1485 p_dev_cb->hid_srvc.control_point_handle = 0;
1486
1487 bta_hh_le_search_hid_chars(p_dev_cb, &service);
1488
1489 APPL_TRACE_DEBUG("%s: have HID service inst_id= %d", __func__,
1490 p_dev_cb->hid_srvc.srvc_inst_id);
1491 } else if (service.uuid == Uuid::From16Bit(UUID_SERVCLASS_SCAN_PARAM)) {
1492
1493 for (const gatt::Characteristic& charac : service.characteristics) {
1494 if (charac.uuid == Uuid::From16Bit(GATT_UUID_SCAN_REFRESH)) {
1495
1496 if (charac.properties & GATT_CHAR_PROP_BIT_NOTIFY)
1497 p_dev_cb->scps_notify |= BTA_HH_LE_SCPS_NOTIFY_SPT;
1498 else
1499 p_dev_cb->scps_notify = BTA_HH_LE_SCPS_NOTIFY_NONE;
1500
1501 break;
1502 }
1503 }
1504 } else if (service.uuid == Uuid::From16Bit(UUID_SERVCLASS_GAP_SERVER)) {
1505 // TODO(jpawlowski): this should be done by GAP profile, remove when GAP
1506 // is fixed.
1507 for (const gatt::Characteristic& charac : service.characteristics) {
1508 if (charac.uuid == Uuid::From16Bit(GATT_UUID_GAP_PREF_CONN_PARAM)) {
1509 /* read the char value */
1510 BtaGattQueue::ReadCharacteristic(p_dev_cb->conn_id,
1511 charac.value_handle,
1512 read_pref_conn_params_cb, p_dev_cb);
1513 break;
1514 }
1515 }
1516 }
1517 }
1518
1519 bta_hh_le_gatt_disc_cmpl(p_dev_cb, p_dev_cb->status);
1520 }
1521
1522 /*******************************************************************************
1523 *
1524 * Function bta_hh_le_input_rpt_notify
1525 *
1526 * Description process the notificaton event, most likely for input report.
1527 *
1528 * Parameters:
1529 *
1530 ******************************************************************************/
bta_hh_le_input_rpt_notify(tBTA_GATTC_NOTIFY * p_data)1531 static void bta_hh_le_input_rpt_notify(tBTA_GATTC_NOTIFY* p_data) {
1532 tBTA_HH_DEV_CB* p_dev_cb = bta_hh_le_find_dev_cb_by_conn_id(p_data->conn_id);
1533 uint8_t app_id;
1534 uint8_t* p_buf;
1535 tBTA_HH_LE_RPT* p_rpt;
1536
1537 if (p_dev_cb == NULL) {
1538 APPL_TRACE_ERROR(
1539 "%s: notification received from Unknown device, conn_id: 0x%04x",
1540 __func__, p_data->conn_id);
1541 return;
1542 }
1543
1544 const gatt::Characteristic* p_char =
1545 BTA_GATTC_GetCharacteristic(p_dev_cb->conn_id, p_data->handle);
1546 if (p_char == NULL) {
1547 APPL_TRACE_ERROR(
1548 "%s: notification received for Unknown Characteristic, conn_id: "
1549 "0x%04x, handle: 0x%04x",
1550 __func__, p_dev_cb->conn_id, p_data->handle);
1551 return;
1552 }
1553
1554 app_id = p_dev_cb->app_id;
1555
1556 const gatt::Service* p_svc =
1557 BTA_GATTC_GetOwningService(p_dev_cb->conn_id, p_char->value_handle);
1558
1559 p_rpt = bta_hh_le_find_report_entry(
1560 p_dev_cb, p_svc->handle, p_char->uuid.As16Bit(), p_char->value_handle);
1561 if (p_rpt == NULL) {
1562 APPL_TRACE_ERROR(
1563 "%s: notification received for Unknown Report, uuid: %s, handle: "
1564 "0x%04x",
1565 __func__, p_char->uuid.ToString().c_str(), p_char->value_handle);
1566 return;
1567 }
1568
1569 if (p_char->uuid == Uuid::From16Bit(GATT_UUID_HID_BT_MOUSE_INPUT))
1570 app_id = BTA_HH_APP_ID_MI;
1571 else if (p_char->uuid == Uuid::From16Bit(GATT_UUID_HID_BT_KB_INPUT))
1572 app_id = BTA_HH_APP_ID_KB;
1573
1574 APPL_TRACE_DEBUG("Notification received on report ID: %d", p_rpt->rpt_id);
1575
1576 /* need to append report ID to the head of data */
1577 if (p_rpt->rpt_id != 0) {
1578 p_buf = (uint8_t*)osi_malloc(p_data->len + 1);
1579
1580 p_buf[0] = p_rpt->rpt_id;
1581 memcpy(&p_buf[1], p_data->value, p_data->len);
1582 ++p_data->len;
1583 } else {
1584 p_buf = p_data->value;
1585 }
1586
1587 bta_hh_co_data((uint8_t)p_dev_cb->hid_handle, p_buf, p_data->len,
1588 p_dev_cb->mode, 0, /* no sub class*/
1589 p_dev_cb->dscp_info.ctry_code, p_dev_cb->addr, app_id);
1590
1591 if (p_buf != p_data->value) osi_free(p_buf);
1592 }
1593
1594 /*******************************************************************************
1595 *
1596 * Function bta_hh_gatt_open_fail
1597 *
1598 * Description action function to process the open fail
1599 *
1600 * Returns void
1601 *
1602 ******************************************************************************/
bta_hh_le_open_fail(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)1603 void bta_hh_le_open_fail(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
1604 const tBTA_HH_LE_CLOSE* le_close = &p_data->le_close;
1605
1606 BTM_LogHistory(kBtmLogTag, p_cb->addr, "Open failed",
1607 base::StringPrintf(
1608 "%s reason %s", (p_cb->is_le_device) ? "le" : "classic",
1609 gatt_disconnection_reason_text(le_close->reason).c_str()));
1610 LOG_WARN("Open failed for device:%s", PRIVATE_ADDRESS(p_cb->addr));
1611
1612 /* open failure in the middle of service discovery, clear all services */
1613 if (p_cb->disc_active & BTA_HH_LE_DISC_HIDS) {
1614 bta_hh_clear_service_cache(p_cb);
1615 }
1616
1617 if (p_cb->is_le_device) {
1618 LOG_DEBUG("gd_acl: Re-adding HID device to acceptlist");
1619 // gd removes from bg list after failed connection
1620 // Correct the cached state to allow re-add to acceptlist.
1621 p_cb->in_bg_conn = false;
1622 bta_hh_le_add_dev_bg_conn(p_cb, false);
1623 }
1624
1625 p_cb->disc_active = BTA_HH_LE_DISC_NONE;
1626 /* Failure in opening connection or GATT discovery failure */
1627 tBTA_HH data = {
1628 .conn =
1629 {
1630 .handle = p_cb->hid_handle,
1631 .bda = p_cb->addr,
1632 .le_hid = true,
1633 .scps_supported = p_cb->scps_supported,
1634 .status = (le_close->reason != GATT_CONN_OK) ? BTA_HH_ERR
1635 : p_cb->status,
1636 },
1637 };
1638
1639 /* Report OPEN fail event */
1640 (*bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, &data);
1641 }
1642
1643 /*******************************************************************************
1644 *
1645 * Function bta_hh_gatt_close
1646 *
1647 * Description action function to process the GATT close in the state
1648 * machine.
1649 *
1650 * Returns void
1651 *
1652 ******************************************************************************/
bta_hh_gatt_close(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)1653 void bta_hh_gatt_close(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
1654 const tBTA_HH_LE_CLOSE* le_close = &p_data->le_close;
1655
1656 BTM_LogHistory(kBtmLogTag, p_cb->addr, "Closed",
1657 base::StringPrintf(
1658 "%s reason %s", (p_cb->is_le_device) ? "le" : "classic",
1659 gatt_disconnection_reason_text(le_close->reason).c_str()));
1660
1661 /* deregister all notification */
1662 bta_hh_le_deregister_input_notif(p_cb);
1663 /* finaliza device driver */
1664 bta_hh_co_close(p_cb->hid_handle, p_cb->app_id);
1665 /* update total conn number */
1666 bta_hh_cb.cnt_num--;
1667
1668 tBTA_HH_CBDATA disc_dat = {
1669 .status = p_cb->status,
1670 .handle = p_cb->hid_handle,
1671 };
1672 (*bta_hh_cb.p_cback)(BTA_HH_CLOSE_EVT, (tBTA_HH*)&disc_dat);
1673
1674 /* if no connection is active and HH disable is signaled, disable service */
1675 if (bta_hh_cb.cnt_num == 0 && bta_hh_cb.w4_disable) {
1676 bta_hh_disc_cmpl();
1677 } else {
1678 switch (le_close->reason) {
1679 case GATT_CONN_FAILED_ESTABLISHMENT:
1680 case GATT_CONN_TERMINATE_PEER_USER:
1681 case GATT_CONN_TIMEOUT:
1682 LOG_DEBUG(
1683 "gd_acl: add into acceptlist for reconnection device:%s reason:%s",
1684 PRIVATE_ADDRESS(p_cb->addr),
1685 gatt_disconnection_reason_text(le_close->reason).c_str());
1686 // gd removes from bg list after successful connection
1687 // Correct the cached state to allow re-add to acceptlist.
1688 p_cb->in_bg_conn = false;
1689 bta_hh_le_add_dev_bg_conn(p_cb, false);
1690 break;
1691
1692 case BTA_GATT_CONN_NONE:
1693 case GATT_CONN_L2C_FAILURE:
1694 case GATT_CONN_LMP_TIMEOUT:
1695 case GATT_CONN_OK:
1696 case GATT_CONN_TERMINATE_LOCAL_HOST:
1697 default:
1698 LOG_DEBUG(
1699 "gd_acl: SKIP add into acceptlist for reconnection device:%s "
1700 "reason:%s",
1701 PRIVATE_ADDRESS(p_cb->addr),
1702 gatt_disconnection_reason_text(le_close->reason).c_str());
1703 break;
1704 }
1705 }
1706 }
1707
1708 /*******************************************************************************
1709 *
1710 * Function bta_hh_le_api_disc_act
1711 *
1712 * Description initaite a Close API to a remote HID device
1713 *
1714 * Returns void
1715 *
1716 ******************************************************************************/
bta_hh_le_api_disc_act(tBTA_HH_DEV_CB * p_cb)1717 void bta_hh_le_api_disc_act(tBTA_HH_DEV_CB* p_cb) {
1718 if (p_cb->conn_id == GATT_INVALID_CONN_ID) {
1719 LOG_ERROR("Tried to disconnect HID device with invalid id");
1720 return;
1721 }
1722
1723 BtaGattQueue::Clean(p_cb->conn_id);
1724 BTA_GATTC_Close(p_cb->conn_id);
1725 /* remove device from background connection if intended to disconnect,
1726 do not allow reconnection */
1727 bta_hh_le_remove_dev_bg_conn(p_cb);
1728 }
1729
1730 /*******************************************************************************
1731 *
1732 * Function read_report_cb
1733 *
1734 * Description Process the Read report complete, send GET_REPORT_EVT to
1735 * application with the report data.
1736 *
1737 * Parameters:
1738 *
1739 ******************************************************************************/
read_report_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)1740 static void read_report_cb(uint16_t conn_id, tGATT_STATUS status,
1741 uint16_t handle, uint16_t len, uint8_t* value,
1742 void* data) {
1743 const gatt::Characteristic* p_char =
1744 BTA_GATTC_GetCharacteristic(conn_id, handle);
1745
1746 if (p_char == NULL) return;
1747
1748 uint16_t char_uuid = p_char->uuid.As16Bit();
1749
1750 if (char_uuid != GATT_UUID_HID_REPORT &&
1751 char_uuid != GATT_UUID_HID_BT_KB_INPUT &&
1752 char_uuid != GATT_UUID_HID_BT_KB_OUTPUT &&
1753 char_uuid != GATT_UUID_HID_BT_MOUSE_INPUT &&
1754 char_uuid != GATT_UUID_BATTERY_LEVEL) {
1755 APPL_TRACE_ERROR("%s: Unexpected Read UUID: 0x%04x", __func__, char_uuid);
1756 return;
1757 }
1758
1759 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
1760 if (p_dev_cb->w4_evt != BTA_HH_GET_RPT_EVT) {
1761 APPL_TRACE_ERROR("Unexpected READ cmpl, w4_evt = %d", p_dev_cb->w4_evt);
1762 return;
1763 }
1764
1765 /* GET_REPORT */
1766 BT_HDR* p_buf = NULL;
1767 tBTA_HH_LE_RPT* p_rpt;
1768 tBTA_HH_HSDATA hs_data;
1769 uint8_t* pp;
1770
1771 memset(&hs_data, 0, sizeof(hs_data));
1772 hs_data.status = BTA_HH_ERR;
1773 hs_data.handle = p_dev_cb->hid_handle;
1774
1775 if (status == GATT_SUCCESS) {
1776 const gatt::Service* p_svc =
1777 BTA_GATTC_GetOwningService(conn_id, p_char->value_handle);
1778
1779 p_rpt = bta_hh_le_find_report_entry(p_dev_cb, p_svc->handle, char_uuid,
1780 p_char->value_handle);
1781
1782 if (p_rpt != NULL && len) {
1783 p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + len + 1);
1784 /* pack data send to app */
1785 hs_data.status = BTA_HH_OK;
1786 p_buf->len = len + 1;
1787 p_buf->layer_specific = 0;
1788 p_buf->offset = 0;
1789
1790 /* attach report ID as the first byte of the report before sending it to
1791 * USB HID driver */
1792 pp = (uint8_t*)(p_buf + 1);
1793 UINT8_TO_STREAM(pp, p_rpt->rpt_id);
1794 memcpy(pp, value, len);
1795
1796 hs_data.rsp_data.p_rpt_data = p_buf;
1797 }
1798 }
1799
1800 p_dev_cb->w4_evt = 0;
1801 (*bta_hh_cb.p_cback)(BTA_HH_GET_RPT_EVT, (tBTA_HH*)&hs_data);
1802
1803 osi_free_and_reset((void**)&p_buf);
1804 }
1805
1806 /*******************************************************************************
1807 *
1808 * Function bta_hh_le_get_rpt
1809 *
1810 * Description GET_REPORT on a LE HID Report
1811 *
1812 * Returns void
1813 *
1814 ******************************************************************************/
bta_hh_le_get_rpt(tBTA_HH_DEV_CB * p_cb,tBTA_HH_RPT_TYPE r_type,uint8_t rpt_id)1815 static void bta_hh_le_get_rpt(tBTA_HH_DEV_CB* p_cb, tBTA_HH_RPT_TYPE r_type,
1816 uint8_t rpt_id) {
1817 tBTA_HH_LE_RPT* p_rpt = bta_hh_le_find_rpt_by_idtype(
1818 p_cb->hid_srvc.report, p_cb->mode, r_type, rpt_id);
1819
1820 if (p_rpt == NULL) {
1821 APPL_TRACE_ERROR("%s: no matching report", __func__);
1822 return;
1823 }
1824
1825 p_cb->w4_evt = BTA_HH_GET_RPT_EVT;
1826 BtaGattQueue::ReadCharacteristic(p_cb->conn_id, p_rpt->char_inst_id,
1827 read_report_cb, p_cb);
1828 }
1829
write_report_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t * value,void * data)1830 static void write_report_cb(uint16_t conn_id, tGATT_STATUS status,
1831 uint16_t handle, uint16_t len, const uint8_t* value,
1832 void* data) {
1833 tBTA_HH_CBDATA cback_data;
1834 tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
1835 uint16_t cb_evt = p_dev_cb->w4_evt;
1836
1837 if (cb_evt == 0) return;
1838
1839 APPL_TRACE_DEBUG("bta_hh_le_write_cmpl w4_evt: %d", p_dev_cb->w4_evt);
1840
1841 const gatt::Characteristic* p_char =
1842 BTA_GATTC_GetCharacteristic(conn_id, handle);
1843
1844 if (p_char == nullptr) return;
1845
1846 uint16_t uuid = p_char->uuid.As16Bit();
1847 if (uuid != GATT_UUID_HID_REPORT && uuid != GATT_UUID_HID_BT_KB_INPUT &&
1848 uuid != GATT_UUID_HID_BT_MOUSE_INPUT &&
1849 uuid != GATT_UUID_HID_BT_KB_OUTPUT) {
1850 return;
1851 }
1852
1853 /* Set Report finished */
1854 cback_data.handle = p_dev_cb->hid_handle;
1855 cback_data.status = (status == GATT_SUCCESS) ? BTA_HH_OK : BTA_HH_ERR;
1856 p_dev_cb->w4_evt = 0;
1857 (*bta_hh_cb.p_cback)(cb_evt, (tBTA_HH*)&cback_data);
1858 }
1859 /*******************************************************************************
1860 *
1861 * Function bta_hh_le_write_rpt
1862 *
1863 * Description SET_REPORT/or DATA output on a LE HID Report
1864 *
1865 * Returns void
1866 *
1867 ******************************************************************************/
bta_hh_le_write_rpt(tBTA_HH_DEV_CB * p_cb,tBTA_HH_RPT_TYPE r_type,BT_HDR * p_buf,uint16_t w4_evt)1868 static void bta_hh_le_write_rpt(tBTA_HH_DEV_CB* p_cb, tBTA_HH_RPT_TYPE r_type,
1869 BT_HDR* p_buf, uint16_t w4_evt) {
1870 tBTA_HH_LE_RPT* p_rpt;
1871 uint8_t rpt_id;
1872
1873 if (p_buf == NULL || p_buf->len == 0) {
1874 APPL_TRACE_ERROR("%s: Illegal data", __func__);
1875 return;
1876 }
1877
1878 /* strip report ID from the data */
1879 uint8_t* vec_start = (uint8_t*)(p_buf + 1) + p_buf->offset;
1880 STREAM_TO_UINT8(rpt_id, vec_start);
1881 vector<uint8_t> value(vec_start, vec_start + p_buf->len - 1);
1882
1883 p_rpt = bta_hh_le_find_rpt_by_idtype(p_cb->hid_srvc.report, p_cb->mode,
1884 r_type, rpt_id);
1885 if (p_rpt == NULL) {
1886 APPL_TRACE_ERROR("%s: no matching report", __func__);
1887 osi_free(p_buf);
1888 return;
1889 }
1890
1891 p_cb->w4_evt = w4_evt;
1892
1893 const gatt::Characteristic* p_char =
1894 BTA_GATTC_GetCharacteristic(p_cb->conn_id, p_rpt->char_inst_id);
1895
1896 tGATT_WRITE_TYPE write_type = GATT_WRITE;
1897 if (p_char && (p_char->properties & GATT_CHAR_PROP_BIT_WRITE_NR))
1898 write_type = GATT_WRITE_NO_RSP;
1899
1900 BtaGattQueue::WriteCharacteristic(p_cb->conn_id, p_rpt->char_inst_id,
1901 std::move(value), write_type,
1902 write_report_cb, p_cb);
1903 }
1904
1905 /*******************************************************************************
1906 *
1907 * Function bta_hh_le_suspend
1908 *
1909 * Description send LE suspend or exit suspend mode to remote device.
1910 *
1911 * Returns void
1912 *
1913 ******************************************************************************/
bta_hh_le_suspend(tBTA_HH_DEV_CB * p_cb,tBTA_HH_TRANS_CTRL_TYPE ctrl_type)1914 static void bta_hh_le_suspend(tBTA_HH_DEV_CB* p_cb,
1915 tBTA_HH_TRANS_CTRL_TYPE ctrl_type) {
1916 ctrl_type -= BTA_HH_CTRL_SUSPEND;
1917
1918 // We don't care about response
1919 BtaGattQueue::WriteCharacteristic(
1920 p_cb->conn_id, p_cb->hid_srvc.control_point_handle, {(uint8_t)ctrl_type},
1921 GATT_WRITE_NO_RSP, NULL, NULL);
1922 }
1923
1924 /*******************************************************************************
1925 *
1926 * Function bta_hh_le_write_dev_act
1927 *
1928 * Description Write LE device action. can be SET/GET/DATA transaction.
1929 *
1930 * Returns void
1931 *
1932 ******************************************************************************/
bta_hh_le_write_dev_act(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)1933 void bta_hh_le_write_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
1934 switch (p_data->api_sndcmd.t_type) {
1935 case HID_TRANS_SET_PROTOCOL:
1936 p_cb->w4_evt = BTA_HH_SET_PROTO_EVT;
1937 bta_hh_le_set_protocol_mode(p_cb, p_data->api_sndcmd.param);
1938 break;
1939
1940 case HID_TRANS_GET_PROTOCOL:
1941 bta_hh_le_get_protocol_mode(p_cb);
1942 break;
1943
1944 case HID_TRANS_GET_REPORT:
1945 bta_hh_le_get_rpt(p_cb, p_data->api_sndcmd.param,
1946 p_data->api_sndcmd.rpt_id);
1947 break;
1948
1949 case HID_TRANS_SET_REPORT:
1950 bta_hh_le_write_rpt(p_cb, p_data->api_sndcmd.param,
1951 p_data->api_sndcmd.p_data, BTA_HH_SET_RPT_EVT);
1952 break;
1953
1954 case HID_TRANS_DATA: /* output report */
1955
1956 bta_hh_le_write_rpt(p_cb, p_data->api_sndcmd.param,
1957 p_data->api_sndcmd.p_data, BTA_HH_DATA_EVT);
1958 break;
1959
1960 case HID_TRANS_CONTROL:
1961 /* no handshake event will be generated */
1962 /* if VC_UNPLUG is issued, set flag */
1963 if (p_data->api_sndcmd.param == BTA_HH_CTRL_SUSPEND ||
1964 p_data->api_sndcmd.param == BTA_HH_CTRL_EXIT_SUSPEND) {
1965 bta_hh_le_suspend(p_cb, p_data->api_sndcmd.param);
1966 }
1967 break;
1968
1969 default:
1970 APPL_TRACE_ERROR("%s unsupported transaction for BLE HID device: %d",
1971 __func__, p_data->api_sndcmd.t_type);
1972 break;
1973 }
1974 }
1975
1976 /*******************************************************************************
1977 *
1978 * Function bta_hh_le_get_dscp_act
1979 *
1980 * Description Send ReportDescriptor to application for all HID services.
1981 *
1982 * Returns void
1983 *
1984 ******************************************************************************/
bta_hh_le_get_dscp_act(tBTA_HH_DEV_CB * p_cb)1985 void bta_hh_le_get_dscp_act(tBTA_HH_DEV_CB* p_cb) {
1986 if (p_cb->hid_srvc.in_use) {
1987 p_cb->dscp_info.descriptor.dl_len = p_cb->hid_srvc.descriptor.dl_len;
1988 p_cb->dscp_info.descriptor.dsc_list = p_cb->hid_srvc.descriptor.dsc_list;
1989
1990 (*bta_hh_cb.p_cback)(BTA_HH_GET_DSCP_EVT, (tBTA_HH*)&p_cb->dscp_info);
1991 }
1992 }
1993
1994 /*******************************************************************************
1995 *
1996 * Function bta_hh_le_add_dev_bg_conn
1997 *
1998 * Description Remove a LE HID device from back ground connection
1999 * procedure.
2000 *
2001 * Returns void
2002 *
2003 ******************************************************************************/
bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB * p_cb,bool check_bond)2004 static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB* p_cb, bool check_bond) {
2005 bool to_add = true;
2006
2007 if (check_bond) {
2008 /* start reconnection if remote is a bonded device */
2009 if (!BTM_IsLinkKeyKnown(p_cb->addr, BT_TRANSPORT_LE)) to_add = false;
2010 }
2011
2012 if (!p_cb->in_bg_conn && to_add) {
2013 /* add device into BG connection to accept remote initiated connection */
2014 BTA_GATTC_Open(bta_hh_cb.gatt_if, p_cb->addr,
2015 BTM_BLE_BKG_CONNECT_ALLOW_LIST, false);
2016 p_cb->in_bg_conn = true;
2017 } else {
2018 // Let the lower layers manage acceptlist and do not cache
2019 // at the higher layer
2020 p_cb->in_bg_conn = true;
2021 BTA_GATTC_Open(bta_hh_cb.gatt_if, p_cb->addr,
2022 BTM_BLE_BKG_CONNECT_ALLOW_LIST, false);
2023 }
2024 }
2025
2026 /*******************************************************************************
2027 *
2028 * Function bta_hh_le_add_device
2029 *
2030 * Description Add a LE HID device as a known device, and also add the
2031 * address
2032 * into back ground connection WL for incoming connection.
2033 *
2034 * Returns void
2035 *
2036 ******************************************************************************/
bta_hh_le_add_device(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_MAINT_DEV * p_dev_info)2037 uint8_t bta_hh_le_add_device(tBTA_HH_DEV_CB* p_cb,
2038 const tBTA_HH_MAINT_DEV* p_dev_info) {
2039 p_cb->hid_handle = bta_hh_le_get_le_dev_hdl(p_cb->index);
2040 if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) return BTA_HH_INVALID_HANDLE;
2041 bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index;
2042
2043 /* update DI information */
2044 bta_hh_update_di_info(
2045 p_cb, p_dev_info->dscp_info.vendor_id, p_dev_info->dscp_info.product_id,
2046 p_dev_info->dscp_info.version, p_dev_info->dscp_info.flag);
2047
2048 /* add to BTA device list */
2049 bta_hh_add_device_to_list(
2050 p_cb, p_cb->hid_handle, p_dev_info->attr_mask,
2051 &p_dev_info->dscp_info.descriptor, p_dev_info->sub_class,
2052 p_dev_info->dscp_info.ssr_max_latency, p_dev_info->dscp_info.ssr_min_tout,
2053 p_dev_info->app_id);
2054
2055 bta_hh_le_add_dev_bg_conn(p_cb, false);
2056
2057 return p_cb->hid_handle;
2058 }
2059
2060 /*******************************************************************************
2061 *
2062 * Function bta_hh_le_remove_dev_bg_conn
2063 *
2064 * Description Remove a LE HID device from back ground connection
2065 * procedure.
2066 *
2067 * Returns void
2068 *
2069 ******************************************************************************/
bta_hh_le_remove_dev_bg_conn(tBTA_HH_DEV_CB * p_dev_cb)2070 void bta_hh_le_remove_dev_bg_conn(tBTA_HH_DEV_CB* p_dev_cb) {
2071 if (p_dev_cb->in_bg_conn) {
2072 LOG_DEBUG("Removing from background connection device:%s",
2073 PRIVATE_ADDRESS(p_dev_cb->addr));
2074 p_dev_cb->in_bg_conn = false;
2075
2076 BTA_GATTC_CancelOpen(bta_hh_cb.gatt_if, p_dev_cb->addr, false);
2077 }
2078
2079 /* deregister all notifications */
2080 bta_hh_le_deregister_input_notif(p_dev_cb);
2081 }
2082
2083 /*******************************************************************************
2084 *
2085 * Function bta_hh_gattc_callback
2086 *
2087 * Description This is GATT client callback function used in BTA HH.
2088 *
2089 * Parameters:
2090 *
2091 ******************************************************************************/
bta_hh_gattc_callback(tBTA_GATTC_EVT event,tBTA_GATTC * p_data)2092 static void bta_hh_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
2093 tBTA_HH_DEV_CB* p_dev_cb;
2094 APPL_TRACE_DEBUG("bta_hh_gattc_callback event:%s",
2095 gatt_client_event_text(event).c_str());
2096 if (p_data == NULL) return;
2097
2098 switch (event) {
2099 case BTA_GATTC_DEREG_EVT: /* 1 */
2100 bta_hh_cleanup_disable(
2101 static_cast<tBTA_HH_STATUS>(p_data->reg_oper.status));
2102 break;
2103
2104 case BTA_GATTC_OPEN_EVT: /* 2 */
2105 p_dev_cb = bta_hh_le_find_dev_cb_by_bda(p_data->open.remote_bda);
2106 if (p_dev_cb) {
2107 bta_hh_sm_execute(p_dev_cb, BTA_HH_GATT_OPEN_EVT,
2108 (tBTA_HH_DATA*)&p_data->open);
2109 }
2110 break;
2111
2112 case BTA_GATTC_CLOSE_EVT: /* 5 */
2113 bta_hh_le_close(p_data->close);
2114 break;
2115
2116 case BTA_GATTC_SEARCH_CMPL_EVT: /* 6 */
2117 bta_hh_le_srvc_search_cmpl(&p_data->search_cmpl);
2118 break;
2119
2120 case BTA_GATTC_NOTIF_EVT: /* 10 */
2121 bta_hh_le_input_rpt_notify(&p_data->notify);
2122 break;
2123
2124 case BTA_GATTC_ENC_CMPL_CB_EVT: /* 17 */
2125 p_dev_cb = bta_hh_le_find_dev_cb_by_bda(p_data->enc_cmpl.remote_bda);
2126 if (p_dev_cb) {
2127 bta_hh_sm_execute(p_dev_cb, BTA_HH_GATT_ENC_CMPL_EVT,
2128 (tBTA_HH_DATA*)&p_data->enc_cmpl);
2129 }
2130 break;
2131
2132 default:
2133 break;
2134 }
2135 }
2136
2137 /*******************************************************************************
2138 *
2139 * Function bta_hh_process_cache_rpt
2140 *
2141 * Description Process the cached reports
2142 *
2143 * Parameters:
2144 *
2145 ******************************************************************************/
bta_hh_process_cache_rpt(tBTA_HH_DEV_CB * p_cb,tBTA_HH_RPT_CACHE_ENTRY * p_rpt_cache,uint8_t num_rpt)2146 static void bta_hh_process_cache_rpt(tBTA_HH_DEV_CB* p_cb,
2147 tBTA_HH_RPT_CACHE_ENTRY* p_rpt_cache,
2148 uint8_t num_rpt) {
2149 uint8_t i = 0;
2150 tBTA_HH_LE_RPT* p_rpt;
2151
2152 if (num_rpt != 0) /* no cache is found */
2153 {
2154 p_cb->hid_srvc.in_use = true;
2155
2156 /* set the descriptor info */
2157 p_cb->hid_srvc.descriptor.dl_len = p_cb->dscp_info.descriptor.dl_len;
2158 p_cb->hid_srvc.descriptor.dsc_list = p_cb->dscp_info.descriptor.dsc_list;
2159
2160 for (; i < num_rpt; i++, p_rpt_cache++) {
2161 if ((p_rpt = bta_hh_le_find_alloc_report_entry(
2162 p_cb, p_rpt_cache->srvc_inst_id, p_rpt_cache->rpt_uuid,
2163 p_rpt_cache->char_inst_id)) == NULL) {
2164 APPL_TRACE_ERROR(
2165 "bta_hh_process_cache_rpt: allocation report entry failure");
2166 break;
2167 } else {
2168 p_rpt->rpt_type = p_rpt_cache->rpt_type;
2169 p_rpt->rpt_id = p_rpt_cache->rpt_id;
2170
2171 if (p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT ||
2172 p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT ||
2173 (p_rpt->uuid == GATT_UUID_HID_REPORT &&
2174 p_rpt->rpt_type == BTA_HH_RPTT_INPUT)) {
2175 p_rpt->client_cfg_value = GATT_CLT_CONFIG_NOTIFICATION;
2176 }
2177 }
2178 }
2179 }
2180 }
2181