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