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