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