• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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