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