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