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