• 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 #include <cstdint>
24 #include <vector>
25 
26 #include "bta/hh/bta_hh_int.h"
27 #include "bta/include/bta_gatt_queue.h"
28 #include "bta/include/bta_hh_co.h"
29 #include "device/include/interop.h"
30 #include "main/shim/dumpsys.h"
31 #include "osi/include/log.h"
32 #include "osi/include/osi.h"         // ARRAY_SIZE
33 #include "stack/btm/btm_sec.h"       // BTM_
34 #include "stack/include/btu.h"       // post_on_bt_main
35 #include "stack/include/l2c_api.h"   // L2CA_
36 #include "stack/include/srvc_api.h"  // tDIS_VALUE
37 #include "types/bluetooth/uuid.h"
38 #include "types/raw_address.h"
39 
40 using bluetooth::Uuid;
41 using std::vector;
42 
43 namespace {
44 
45 #ifndef BTA_HH_LE_RECONN
46 constexpr bool kBTA_HH_LE_RECONN = true;
47 #else
48 constexpr bool kBTA_HH_LE_RECONN = false;
49 #endif
50 
51 }  // namespace
52 
53 #define BTA_HH_APP_ID_LE 0xff
54 
55 #define BTA_HH_LE_PROTO_BOOT_MODE 0x00
56 #define BTA_HH_LE_PROTO_REPORT_MODE 0x01
57 
58 #define BTA_LE_HID_RTP_UUID_MAX 5
59 static const uint16_t bta_hh_uuid_to_rtp_type[BTA_LE_HID_RTP_UUID_MAX][2] = {
60     {GATT_UUID_HID_REPORT, BTA_HH_RPTT_INPUT},
61     {GATT_UUID_HID_BT_KB_INPUT, BTA_HH_RPTT_INPUT},
62     {GATT_UUID_HID_BT_KB_OUTPUT, BTA_HH_RPTT_OUTPUT},
63     {GATT_UUID_HID_BT_MOUSE_INPUT, BTA_HH_RPTT_INPUT},
64     {GATT_UUID_BATTERY_LEVEL, BTA_HH_RPTT_INPUT}};
65 
66 static void bta_hh_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data);
67 static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB* p_cb, bool check_bond);
68 static void bta_hh_process_cache_rpt(tBTA_HH_DEV_CB* p_cb,
69                                      tBTA_HH_RPT_CACHE_ENTRY* p_rpt_cache,
70                                      uint8_t num_rpt);
71 
72 static const char* bta_hh_le_rpt_name[4] = {"UNKNOWN", "INPUT", "OUTPUT",
73                                             "FEATURE"};
74 
75 /*******************************************************************************
76  *
77  * Function         bta_hh_le_hid_report_dbg
78  *
79  * Description      debug function to print out all HID report available on
80  *                  remote device.
81  *
82  * Returns          void
83  *
84  ******************************************************************************/
bta_hh_le_hid_report_dbg(tBTA_HH_DEV_CB * p_cb)85 static void bta_hh_le_hid_report_dbg(tBTA_HH_DEV_CB* p_cb) {
86   APPL_TRACE_DEBUG("%s: HID Report DB", __func__);
87 
88   if (!p_cb->hid_srvc.in_use) return;
89 
90   tBTA_HH_LE_RPT* p_rpt = &p_cb->hid_srvc.report[0];
91 
92   for (int j = 0; j < BTA_HH_LE_RPT_MAX; j++, p_rpt++) {
93     const char* rpt_name = "Unknown";
94 
95     if (!p_rpt->in_use) break;
96 
97     if (p_rpt->uuid == GATT_UUID_HID_REPORT) rpt_name = "Report";
98     if (p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT) rpt_name = "Boot KB Input";
99     if (p_rpt->uuid == GATT_UUID_HID_BT_KB_OUTPUT) rpt_name = "Boot KB Output";
100     if (p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) rpt_name = "Boot MI Input";
101 
102     APPL_TRACE_DEBUG(
103         "\t\t [%s- 0x%04x] [Type: %s], [ReportID: %d] [srvc_inst_id: %d] "
104         "[char_inst_id: %d] [Clt_cfg: %d]",
105         rpt_name, p_rpt->uuid,
106         ((p_rpt->rpt_type < 4) ? bta_hh_le_rpt_name[p_rpt->rpt_type]
107                                : "UNKNOWN"),
108         p_rpt->rpt_id, p_rpt->srvc_inst_id, p_rpt->char_inst_id,
109         p_rpt->client_cfg_value);
110   }
111 }
112 
113 /*******************************************************************************
114  *
115  * Function         bta_hh_uuid_to_str
116  *
117  * Description
118  *
119  * Returns          void
120  *
121  ******************************************************************************/
bta_hh_uuid_to_str(uint16_t uuid)122 static const char* bta_hh_uuid_to_str(uint16_t uuid) {
123   switch (uuid) {
124     case GATT_UUID_HID_INFORMATION:
125       return "GATT_UUID_HID_INFORMATION";
126     case GATT_UUID_HID_REPORT_MAP:
127       return "GATT_UUID_HID_REPORT_MAP";
128     case GATT_UUID_HID_CONTROL_POINT:
129       return "GATT_UUID_HID_CONTROL_POINT";
130     case GATT_UUID_HID_REPORT:
131       return "GATT_UUID_HID_REPORT";
132     case GATT_UUID_HID_PROTO_MODE:
133       return "GATT_UUID_HID_PROTO_MODE";
134     case GATT_UUID_HID_BT_KB_INPUT:
135       return "GATT_UUID_HID_BT_KB_INPUT";
136     case GATT_UUID_HID_BT_KB_OUTPUT:
137       return "GATT_UUID_HID_BT_KB_OUTPUT";
138     case GATT_UUID_HID_BT_MOUSE_INPUT:
139       return "GATT_UUID_HID_BT_MOUSE_INPUT";
140     case GATT_UUID_CHAR_CLIENT_CONFIG:
141       return "GATT_UUID_CHAR_CLIENT_CONFIG";
142     case GATT_UUID_EXT_RPT_REF_DESCR:
143       return "GATT_UUID_EXT_RPT_REF_DESCR";
144     case GATT_UUID_RPT_REF_DESCR:
145       return "GATT_UUID_RPT_REF_DESCR";
146     default:
147       return "Unknown UUID";
148   }
149 }
150 
151 /*******************************************************************************
152  *
153  * Function         bta_hh_le_enable
154  *
155  * Description      initialize LE HID related functionality
156  *
157  *
158  * Returns          void
159  *
160  ******************************************************************************/
bta_hh_le_enable(void)161 void bta_hh_le_enable(void) {
162   uint8_t xx;
163 
164   bta_hh_cb.gatt_if = BTA_GATTS_INVALID_IF;
165 
166   for (xx = 0; xx < ARRAY_SIZE(bta_hh_cb.le_cb_index); xx++)
167     bta_hh_cb.le_cb_index[xx] = BTA_HH_IDX_INVALID;
168 
169   BTA_GATTC_AppRegister(bta_hh_gattc_callback,
170                         base::Bind([](uint8_t client_id, uint8_t r_status) {
171                           tBTA_HH bta_hh;
172                           bta_hh.status = BTA_HH_ERR;
173 
174                           if (r_status == GATT_SUCCESS) {
175                             bta_hh_cb.gatt_if = client_id;
176                             bta_hh.status = BTA_HH_OK;
177                           } else {
178                             bta_hh_cb.gatt_if = BTA_GATTS_INVALID_IF;
179                           }
180 
181                           /* null check is needed in case HID profile is shut
182                            * down before BTA_GATTC_AppRegister is done */
183                           if (bta_hh_cb.p_cback) {
184                             /* signal BTA call back event */
185                             (*bta_hh_cb.p_cback)(BTA_HH_ENABLE_EVT, &bta_hh);
186                           }
187                         }), false);
188 }
189 
190 /*******************************************************************************
191  *
192  * Function         bta_hh_le_is_hh_gatt_if
193  *
194  * Description      Check to see if client_if is BTA HH LE GATT interface
195  *
196  *
197  * Returns          whether it is HH GATT IF
198  *
199  ******************************************************************************/
bta_hh_le_is_hh_gatt_if(tGATT_IF client_if)200 bool bta_hh_le_is_hh_gatt_if(tGATT_IF client_if) {
201   return (bta_hh_cb.gatt_if == client_if);
202 }
203 
204 /*******************************************************************************
205  *
206  * Function         bta_hh_le_deregister
207  *
208  * Description      De-register BTA HH from BTA GATTC
209  *
210  *
211  * Returns          void
212  *
213  ******************************************************************************/
bta_hh_le_deregister(void)214 void bta_hh_le_deregister(void) { BTA_GATTC_AppDeregister(bta_hh_cb.gatt_if); }
215 
216 /******************************************************************************
217  *
218  * Function         bta_hh_le_get_le_cb
219  *
220  * Description      Allocate bta_hh_cb.le_cb_index
221  *
222  * Parameters:
223  *
224  ******************************************************************************/
bta_hh_le_get_le_dev_hdl(uint8_t cb_index)225 static uint8_t bta_hh_le_get_le_dev_hdl(uint8_t cb_index) {
226   uint8_t i;
227   for (i = 0; i < ARRAY_SIZE(bta_hh_cb.le_cb_index); i++) {
228     if (bta_hh_cb.le_cb_index[i] == cb_index) return BTA_HH_GET_LE_DEV_HDL(i);
229   }
230 
231   for (i = 0; i < ARRAY_SIZE(bta_hh_cb.le_cb_index); i++) {
232     if (bta_hh_cb.le_cb_index[i] == BTA_HH_IDX_INVALID)
233       return BTA_HH_GET_LE_DEV_HDL(i);
234   }
235   return BTA_HH_IDX_INVALID;
236 }
237 
238 /*******************************************************************************
239  *
240  * Function         bta_hh_le_open_conn
241  *
242  * Description      open a GATT connection first.
243  *
244  * Parameters:
245  *
246  ******************************************************************************/
bta_hh_le_open_conn(tBTA_HH_DEV_CB * p_cb,const RawAddress & remote_bda)247 void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb, const RawAddress& remote_bda) {
248   tBTA_HH_STATUS status = BTA_HH_ERR_NO_RES;
249 
250   /* update cb_index[] map */
251   p_cb->hid_handle = bta_hh_le_get_le_dev_hdl(p_cb->index);
252   if (p_cb->hid_handle == BTA_HH_IDX_INVALID) {
253     bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA*)&status);
254     return;
255   }
256 
257   p_cb->addr = remote_bda;
258   bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index;
259   p_cb->in_use = true;
260 
261   BTA_GATTC_Open(bta_hh_cb.gatt_if, remote_bda, true, false);
262 }
263 
264 /*******************************************************************************
265  *
266  * Function         bta_hh_le_find_dev_cb_by_conn_id
267  *
268  * Description      Utility function find a device control block by connection
269  *                  ID.
270  *
271  ******************************************************************************/
bta_hh_le_find_dev_cb_by_conn_id(uint16_t conn_id)272 static tBTA_HH_DEV_CB* bta_hh_le_find_dev_cb_by_conn_id(uint16_t conn_id) {
273   uint8_t i;
274   tBTA_HH_DEV_CB* p_dev_cb = &bta_hh_cb.kdev[0];
275 
276   for (i = 0; i < BTA_HH_MAX_DEVICE; i++, p_dev_cb++) {
277     if (p_dev_cb->in_use && p_dev_cb->conn_id == conn_id) return p_dev_cb;
278   }
279   return NULL;
280 }
281 
282 /*******************************************************************************
283  *
284  * Function         bta_hh_le_find_dev_cb_by_bda
285  *
286  * Description      Utility function find a device control block by BD address.
287  *
288  ******************************************************************************/
bta_hh_le_find_dev_cb_by_bda(const RawAddress & bda)289 static tBTA_HH_DEV_CB* bta_hh_le_find_dev_cb_by_bda(const RawAddress& bda) {
290   uint8_t i;
291   tBTA_HH_DEV_CB* p_dev_cb = &bta_hh_cb.kdev[0];
292 
293   for (i = 0; i < BTA_HH_MAX_DEVICE; i++, p_dev_cb++) {
294     if (p_dev_cb->in_use && p_dev_cb->addr == bda) return p_dev_cb;
295   }
296   return NULL;
297 }
298 
299 /*******************************************************************************
300  *
301  * Function         bta_hh_le_find_service_inst_by_battery_inst_id
302  *
303  * Description      find HID service instance ID by battery service instance ID
304  *
305  ******************************************************************************/
bta_hh_le_find_service_inst_by_battery_inst_id(tBTA_HH_DEV_CB * p_cb,uint8_t ba_inst_id)306 static uint8_t bta_hh_le_find_service_inst_by_battery_inst_id(
307     tBTA_HH_DEV_CB* p_cb, uint8_t ba_inst_id) {
308   if (p_cb->hid_srvc.in_use && 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,void * data)662 static void write_rpt_ctl_cfg_cb(uint16_t conn_id, tGATT_STATUS status,
663                                  uint16_t handle, void* data) {
664   uint8_t srvc_inst_id, hid_inst_id;
665 
666   tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
667   const gatt::Characteristic* characteristic =
668       BTA_GATTC_GetOwningCharacteristic(conn_id, handle);
669   uint16_t char_uuid = characteristic->uuid.As16Bit();
670 
671   srvc_inst_id = BTA_GATTC_GetOwningService(conn_id, handle)->handle;
672   hid_inst_id = srvc_inst_id;
673   switch (char_uuid) {
674     case GATT_UUID_BATTERY_LEVEL: /* battery level clt cfg registered */
675       hid_inst_id = bta_hh_le_find_service_inst_by_battery_inst_id(
676           p_dev_cb, srvc_inst_id);
677       FALLTHROUGH_INTENDED; /* FALLTHROUGH */
678     case GATT_UUID_HID_BT_KB_INPUT:
679     case GATT_UUID_HID_BT_MOUSE_INPUT:
680     case GATT_UUID_HID_REPORT:
681       if (status == GATT_SUCCESS)
682         p_dev_cb->hid_srvc.report[p_dev_cb->clt_cfg_idx].client_cfg_value =
683             GATT_CLT_CONFIG_NOTIFICATION;
684       p_dev_cb->clt_cfg_idx++;
685       bta_hh_le_write_rpt_clt_cfg(p_dev_cb);
686       break;
687 
688     default:
689       APPL_TRACE_ERROR("Unknown char ID clt cfg: 0x%04x", char_uuid);
690   }
691 }
692 /*******************************************************************************
693  *
694  * Function         bta_hh_le_write_rpt_clt_cfg
695  *
696  * Description      write client configuration. This is only for input report
697  *                  enable all input notification upon connection open.
698  *
699  ******************************************************************************/
bta_hh_le_write_rpt_clt_cfg(tBTA_HH_DEV_CB * p_cb)700 static bool bta_hh_le_write_rpt_clt_cfg(tBTA_HH_DEV_CB* p_cb) {
701   uint8_t i;
702   tBTA_HH_LE_RPT* p_rpt = &p_cb->hid_srvc.report[p_cb->clt_cfg_idx];
703 
704   for (i = p_cb->clt_cfg_idx; i < BTA_HH_LE_RPT_MAX && p_rpt->in_use;
705        i++, p_rpt++) {
706     /* enable notification for all input report, regardless mode */
707     if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT) {
708       if (bta_hh_le_write_ccc(p_cb, p_rpt->char_inst_id,
709                               GATT_CLT_CONFIG_NOTIFICATION,
710                               write_rpt_ctl_cfg_cb, p_cb)) {
711         p_cb->clt_cfg_idx = i;
712         return true;
713       }
714     }
715   }
716   p_cb->clt_cfg_idx = 0;
717 
718   /* client configuration is completed, send open callback */
719   if (p_cb->state == BTA_HH_W4_CONN_ST) {
720     p_cb->disc_active &= ~BTA_HH_LE_DISC_HIDS;
721 
722     bta_hh_le_open_cmpl(p_cb);
723   }
724   return false;
725 }
726 
write_proto_mode_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,void * data)727 static void write_proto_mode_cb(uint16_t conn_id, tGATT_STATUS status,
728                                 uint16_t handle, 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.in_use && p_cb->hid_srvc.proto_mode_handle != 0) {
854     BtaGattQueue::ReadCharacteristic(p_cb->conn_id,
855                                      p_cb->hid_srvc.proto_mode_handle,
856                                      get_protocol_mode_cb, p_cb);
857     return;
858   }
859 
860   /* no service support protocol_mode, by default report mode */
861   hs_data.status = BTA_HH_OK;
862   hs_data.handle = p_cb->hid_handle;
863   hs_data.rsp_data.proto_mode = BTA_HH_PROTO_RPT_MODE;
864   p_cb->w4_evt = 0;
865   (*bta_hh_cb.p_cback)(BTA_HH_GET_PROTO_EVT, (tBTA_HH*)&hs_data);
866 }
867 
868 /*******************************************************************************
869  *
870  * Function         bta_hh_le_dis_cback
871  *
872  * Description      DIS read complete callback
873  *
874  * Parameters:
875  *
876  ******************************************************************************/
bta_hh_le_dis_cback(const RawAddress & addr,tDIS_VALUE * p_dis_value)877 static void bta_hh_le_dis_cback(const RawAddress& addr,
878                                 tDIS_VALUE* p_dis_value) {
879   tBTA_HH_DEV_CB* p_cb = bta_hh_le_find_dev_cb_by_bda(addr);
880 
881   if (p_cb == NULL || p_dis_value == NULL) {
882     APPL_TRACE_ERROR("received unexpected/error DIS callback");
883     return;
884   }
885 
886   p_cb->disc_active &= ~BTA_HH_LE_DISC_DIS;
887   /* plug in the PnP info for this device */
888   if (p_dis_value->attr_mask & DIS_ATTR_PNP_ID_BIT) {
889     APPL_TRACE_DEBUG(
890         "Plug in PnP info: product_id = %02x, vendor_id = %04x, version = %04x",
891         p_dis_value->pnp_id.product_id, p_dis_value->pnp_id.vendor_id,
892         p_dis_value->pnp_id.product_version);
893     p_cb->dscp_info.product_id = p_dis_value->pnp_id.product_id;
894     p_cb->dscp_info.vendor_id = p_dis_value->pnp_id.vendor_id;
895     p_cb->dscp_info.version = p_dis_value->pnp_id.product_version;
896   }
897   bta_hh_le_open_cmpl(p_cb);
898 }
899 
900 /*******************************************************************************
901  *
902  * Function         bta_hh_le_pri_service_discovery
903  *
904  * Description      Initialize GATT discovery on the remote LE HID device by
905  *                  opening a GATT connection first.
906  *
907  * Parameters:
908  *
909  ******************************************************************************/
bta_hh_le_pri_service_discovery(tBTA_HH_DEV_CB * p_cb)910 static void bta_hh_le_pri_service_discovery(tBTA_HH_DEV_CB* p_cb) {
911   bta_hh_le_co_reset_rpt_cache(p_cb->addr, p_cb->app_id);
912 
913   p_cb->disc_active |= (BTA_HH_LE_DISC_HIDS | BTA_HH_LE_DISC_DIS);
914 
915   /* read DIS info */
916   if (!DIS_ReadDISInfo(p_cb->addr, bta_hh_le_dis_cback, DIS_ATTR_PNP_ID_BIT)) {
917     APPL_TRACE_ERROR("read DIS failed");
918     p_cb->disc_active &= ~BTA_HH_LE_DISC_DIS;
919   }
920 
921   /* in parallel */
922   /* start primary service discovery for HID service */
923   Uuid pri_srvc = Uuid::From16Bit(UUID_SERVCLASS_LE_HID);
924   BTA_GATTC_ServiceSearchRequest(p_cb->conn_id, &pri_srvc);
925   return;
926 }
927 
928 /*******************************************************************************
929  *
930  * Function         bta_hh_le_encrypt_cback
931  *
932  * Description      link encryption complete callback for bond verification.
933  *
934  * Returns          None
935  *
936  ******************************************************************************/
bta_hh_le_encrypt_cback(const RawAddress * bd_addr,UNUSED_ATTR tBT_TRANSPORT transport,UNUSED_ATTR void * p_ref_data,tBTM_STATUS result)937 static void bta_hh_le_encrypt_cback(const RawAddress* bd_addr,
938                                     UNUSED_ATTR tBT_TRANSPORT transport,
939                                     UNUSED_ATTR void* p_ref_data,
940                                     tBTM_STATUS result) {
941   tBTA_HH_DEV_CB* p_dev_cb = bta_hh_get_cb(*bd_addr);
942   if (p_dev_cb == nullptr) {
943     LOG_ERROR("unexpected encryption callback, ignore");
944     return;
945   }
946 
947   // TODO Collapse the duplicated status values
948   p_dev_cb->status = (result == BTM_SUCCESS) ? BTA_HH_OK : BTA_HH_ERR_SEC;
949   p_dev_cb->btm_status = result;
950 
951   bta_hh_sm_execute(p_dev_cb, BTA_HH_ENC_CMPL_EVT, NULL);
952 }
953 
954 /*******************************************************************************
955  *
956  * Function         bta_hh_security_cmpl
957  *
958  * Description      Security check completed, start the service discovery
959  *                  if no cache available, otherwise report connection open
960  *                  completed
961  *
962  * Parameters:
963  *
964  ******************************************************************************/
bta_hh_security_cmpl(tBTA_HH_DEV_CB * p_cb,UNUSED_ATTR const tBTA_HH_DATA * p_buf)965 void bta_hh_security_cmpl(tBTA_HH_DEV_CB* p_cb,
966                           UNUSED_ATTR const tBTA_HH_DATA* p_buf) {
967   APPL_TRACE_DEBUG("%s", __func__);
968   if (p_cb->status == BTA_HH_OK) {
969     if (!p_cb->hid_srvc.in_use) {
970       APPL_TRACE_DEBUG("bta_hh_security_cmpl no reports loaded, try to load");
971 
972       /* start loading the cache if not in stack */
973       tBTA_HH_RPT_CACHE_ENTRY* p_rpt_cache;
974       uint8_t num_rpt = 0;
975       if ((p_rpt_cache = bta_hh_le_co_cache_load(p_cb->addr, &num_rpt,
976                                                  p_cb->app_id)) != NULL) {
977         bta_hh_process_cache_rpt(p_cb, p_rpt_cache, num_rpt);
978       }
979     }
980     /*  discovery has been done for HID service */
981     if (p_cb->app_id != 0 && p_cb->hid_srvc.in_use) {
982       APPL_TRACE_DEBUG("%s: discovery has been done for HID service", __func__);
983       /* configure protocol mode */
984       if (!bta_hh_le_set_protocol_mode(p_cb, p_cb->mode)) {
985         bta_hh_le_open_cmpl(p_cb);
986       }
987     }
988     /* start primary service discovery for HID service */
989     else {
990       APPL_TRACE_DEBUG("%s: Starting service discovery", __func__);
991       bta_hh_le_pri_service_discovery(p_cb);
992     }
993   } else {
994     LOG_ERROR("Encryption failed status:%s btm_status:%s",
995               bta_hh_status_text(p_cb->status).c_str(),
996               btm_status_text(p_cb->btm_status).c_str());
997     if (!(p_cb->status == BTA_HH_ERR_SEC &&
998           p_cb->btm_status == BTM_ERR_PROCESSING))
999       bta_hh_le_api_disc_act(p_cb);
1000   }
1001 }
1002 
1003 /*******************************************************************************
1004  *
1005  * Function         bta_hh_le_notify_enc_cmpl
1006  *
1007  * Description      process GATT encryption complete event
1008  *
1009  * Returns
1010  *
1011  ******************************************************************************/
bta_hh_le_notify_enc_cmpl(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_buf)1012 void bta_hh_le_notify_enc_cmpl(tBTA_HH_DEV_CB* p_cb,
1013                                const tBTA_HH_DATA* p_buf) {
1014   if (p_cb == NULL || !p_cb->security_pending || p_buf == NULL ||
1015       p_buf->le_enc_cmpl.client_if != bta_hh_cb.gatt_if) {
1016     return;
1017   }
1018 
1019   p_cb->security_pending = false;
1020   bta_hh_start_security(p_cb, NULL);
1021 }
1022 
1023 /*******************************************************************************
1024  *
1025  * Function         bta_hh_clear_service_cache
1026  *
1027  * Description      clear the service cache
1028  *
1029  * Parameters:
1030  *
1031  ******************************************************************************/
bta_hh_clear_service_cache(tBTA_HH_DEV_CB * p_cb)1032 static void bta_hh_clear_service_cache(tBTA_HH_DEV_CB* p_cb) {
1033   tBTA_HH_LE_HID_SRVC* p_hid_srvc = &p_cb->hid_srvc;
1034 
1035   p_cb->app_id = 0;
1036   p_cb->dscp_info.descriptor.dsc_list = NULL;
1037 
1038   osi_free_and_reset((void**)&p_hid_srvc->rpt_map);
1039   memset(p_hid_srvc, 0, sizeof(tBTA_HH_LE_HID_SRVC));
1040 }
1041 
1042 /*******************************************************************************
1043  *
1044  * Function         bta_hh_start_security
1045  *
1046  * Description      start the security check of the established connection
1047  *
1048  * Parameters:
1049  *
1050  ******************************************************************************/
bta_hh_start_security(tBTA_HH_DEV_CB * p_cb,UNUSED_ATTR const tBTA_HH_DATA * p_buf)1051 void bta_hh_start_security(tBTA_HH_DEV_CB* p_cb,
1052                            UNUSED_ATTR const tBTA_HH_DATA* p_buf) {
1053   if (BTM_SecIsSecurityPending(p_cb->addr)) {
1054     /* if security collision happened, wait for encryption done */
1055     p_cb->security_pending = true;
1056     return;
1057   }
1058 
1059   /* if link has been encrypted */
1060   if (BTM_IsEncrypted(p_cb->addr, BT_TRANSPORT_LE)) {
1061     p_cb->status = BTA_HH_OK;
1062     bta_hh_sm_execute(p_cb, BTA_HH_ENC_CMPL_EVT, NULL);
1063   }
1064   /* if bonded and link not encrypted */
1065   else if (BTM_IsLinkKeyKnown(p_cb->addr, BT_TRANSPORT_LE)) {
1066     p_cb->status = BTA_HH_ERR_AUTH_FAILED;
1067     BTM_SetEncryption(p_cb->addr, BT_TRANSPORT_LE, bta_hh_le_encrypt_cback,
1068                       NULL, BTM_BLE_SEC_ENCRYPT);
1069   }
1070   /* unbonded device, report security error here */
1071   else {
1072     p_cb->status = BTA_HH_ERR_AUTH_FAILED;
1073     bta_hh_clear_service_cache(p_cb);
1074     BTM_SetEncryption(p_cb->addr, BT_TRANSPORT_LE, bta_hh_le_encrypt_cback,
1075                       NULL, BTM_BLE_SEC_ENCRYPT_NO_MITM);
1076   }
1077 }
1078 
1079 /*******************************************************************************
1080  *
1081  * Function         bta_hh_gatt_open
1082  *
1083  * Description      process GATT open event.
1084  *
1085  * Parameters:
1086  *
1087  ******************************************************************************/
bta_hh_gatt_open(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_buf)1088 void bta_hh_gatt_open(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_buf) {
1089   const tBTA_GATTC_OPEN* p_data = &p_buf->le_open;
1090   const uint8_t* p2;
1091 
1092   /* if received invalid callback data , ignore it */
1093   if (p_cb == NULL || p_data == NULL) return;
1094 
1095   p2 = p_data->remote_bda.address;
1096 
1097   APPL_TRACE_DEBUG(
1098       "bta_hh_gatt_open BTA_GATTC_OPEN_EVT bda= [%08x%04x] status =%d",
1099       ((p2[0]) << 24) + ((p2[1]) << 16) + ((p2[2]) << 8) + (p2[3]),
1100       ((p2[4]) << 8) + p2[5], p_data->status);
1101 
1102   if (p_data->status == GATT_SUCCESS) {
1103     p_cb->hid_handle = bta_hh_le_get_le_dev_hdl(p_cb->index);
1104     if (p_cb->hid_handle == BTA_HH_IDX_INVALID) {
1105       p_cb->conn_id = p_data->conn_id;
1106       bta_hh_le_api_disc_act(p_cb);
1107       return;
1108     }
1109     p_cb->is_le_device = true;
1110     p_cb->in_use = true;
1111     p_cb->conn_id = p_data->conn_id;
1112 
1113     bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index;
1114 
1115     BtaGattQueue::Clean(p_cb->conn_id);
1116 
1117     APPL_TRACE_DEBUG("hid_handle = %2x conn_id = %04x cb_index = %d",
1118                      p_cb->hid_handle, p_cb->conn_id, p_cb->index);
1119 
1120     bta_hh_sm_execute(p_cb, BTA_HH_START_ENC_EVT, NULL);
1121 
1122   } else {
1123     /* open failure */
1124     tBTA_HH_DATA bta_hh_data;
1125     bta_hh_data.status = BTA_HH_ERR;
1126     bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data);
1127   }
1128 }
1129 
1130 /*******************************************************************************
1131  *
1132  * Function         bta_hh_le_close
1133  *
1134  * Description      This function converts the GATT close event and post it as a
1135  *                  BTA HH internal event.
1136  *
1137  ******************************************************************************/
bta_hh_le_close(const tBTA_GATTC_CLOSE & gattc_data)1138 static void bta_hh_le_close(const tBTA_GATTC_CLOSE& gattc_data) {
1139   tBTA_HH_DEV_CB* p_cb = bta_hh_le_find_dev_cb_by_bda(gattc_data.remote_bda);
1140   if (p_cb == nullptr) {
1141     LOG_WARN("Received close event with unknown device:%s",
1142              PRIVATE_ADDRESS(gattc_data.remote_bda));
1143     return;
1144   }
1145   p_cb->conn_id = GATT_INVALID_CONN_ID;
1146   p_cb->security_pending = false;
1147 
1148   post_on_bt_main([=]() {
1149     const tBTA_HH_DATA data = {
1150         .le_close =
1151             {
1152                 .conn_id = gattc_data.conn_id,
1153                 .reason = gattc_data.reason,
1154                 .hdr =
1155                     {
1156                         .event = BTA_HH_GATT_CLOSE_EVT,
1157                         .layer_specific =
1158                             static_cast<uint16_t>(p_cb->hid_handle),
1159                     },
1160             },
1161     };
1162     bta_hh_sm_execute(p_cb, BTA_HH_GATT_CLOSE_EVT, &data);
1163   });
1164 }
1165 
1166 /*******************************************************************************
1167  *
1168  * Function         bta_hh_le_gatt_disc_cmpl
1169  *
1170  * Description      Check to see if the remote device is a LE only device
1171  *
1172  * Parameters:
1173  *
1174  ******************************************************************************/
bta_hh_le_gatt_disc_cmpl(tBTA_HH_DEV_CB * p_cb,tBTA_HH_STATUS status)1175 static void bta_hh_le_gatt_disc_cmpl(tBTA_HH_DEV_CB* p_cb,
1176                                      tBTA_HH_STATUS status) {
1177   APPL_TRACE_DEBUG("bta_hh_le_gatt_disc_cmpl ");
1178 
1179   /* if open sucessful or protocol mode not desired, keep the connection open
1180    * but inform app */
1181   if (status == BTA_HH_OK || status == BTA_HH_ERR_PROTO) {
1182     /* assign a special APP ID temp, since device type unknown */
1183     p_cb->app_id = BTA_HH_APP_ID_LE;
1184 
1185     /* set report notification configuration */
1186     p_cb->clt_cfg_idx = 0;
1187     bta_hh_le_write_rpt_clt_cfg(p_cb);
1188   } else /* error, close the GATT connection */
1189   {
1190     /* close GATT connection if it's on */
1191     bta_hh_le_api_disc_act(p_cb);
1192   }
1193 }
1194 
read_hid_info_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)1195 static void read_hid_info_cb(uint16_t conn_id, tGATT_STATUS status,
1196                              uint16_t handle, uint16_t len, uint8_t* value,
1197                              void* data) {
1198   if (status != GATT_SUCCESS) {
1199     APPL_TRACE_ERROR("%s: error: %d", __func__, status);
1200     return;
1201   }
1202 
1203   if (len != 4) {
1204     APPL_TRACE_ERROR("%s: wrong length: %d", __func__, len);
1205     return;
1206   }
1207 
1208   tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
1209   uint8_t* pp = value;
1210   /* save device information */
1211   STREAM_TO_UINT16(p_dev_cb->dscp_info.version, pp);
1212   STREAM_TO_UINT8(p_dev_cb->dscp_info.ctry_code, pp);
1213   STREAM_TO_UINT8(p_dev_cb->dscp_info.flag, pp);
1214 }
1215 
read_hid_report_map_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)1216 static void read_hid_report_map_cb(uint16_t conn_id, tGATT_STATUS status,
1217                                    uint16_t handle, uint16_t len,
1218                                    uint8_t* value, void* data) {
1219   if (status != GATT_SUCCESS) {
1220     APPL_TRACE_ERROR("%s: error reading characteristic: %d", __func__, status);
1221     return;
1222   }
1223 
1224   tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
1225   tBTA_HH_LE_HID_SRVC* p_srvc = &p_dev_cb->hid_srvc;
1226 
1227   osi_free_and_reset((void**)&p_srvc->rpt_map);
1228 
1229   if (len > 0) {
1230     p_srvc->rpt_map = (uint8_t*)osi_malloc(len);
1231 
1232     uint8_t* pp = value;
1233     STREAM_TO_ARRAY(p_srvc->rpt_map, pp, len);
1234     p_srvc->descriptor.dl_len = len;
1235     p_srvc->descriptor.dsc_list = p_dev_cb->hid_srvc.rpt_map;
1236   }
1237 }
1238 
read_ext_rpt_ref_desc_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)1239 static void read_ext_rpt_ref_desc_cb(uint16_t conn_id, tGATT_STATUS status,
1240                                      uint16_t handle, uint16_t len,
1241                                      uint8_t* value, void* data) {
1242   if (status != GATT_SUCCESS) {
1243     APPL_TRACE_ERROR("%s: error: %d", __func__, status);
1244     return;
1245   }
1246 
1247   /* if the length of the descriptor value is right, parse it assume it's a 16
1248    * bits UUID */
1249   if (len != Uuid::kNumBytes16) {
1250     APPL_TRACE_ERROR("%s: we support only 16bit UUID: %d", __func__, len);
1251     return;
1252   }
1253 
1254   tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
1255   uint8_t* pp = value;
1256 
1257   STREAM_TO_UINT16(p_dev_cb->hid_srvc.ext_rpt_ref, pp);
1258 
1259   APPL_TRACE_DEBUG("%s: External Report Reference UUID 0x%04x", __func__,
1260                    p_dev_cb->hid_srvc.ext_rpt_ref);
1261 }
1262 
read_report_ref_desc_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)1263 static void read_report_ref_desc_cb(uint16_t conn_id, tGATT_STATUS status,
1264                                     uint16_t handle, uint16_t len,
1265                                     uint8_t* value, void* data) {
1266   if (status != GATT_SUCCESS) {
1267     APPL_TRACE_ERROR("%s: error: %d", __func__, status);
1268     return;
1269   }
1270 
1271   tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
1272   const gatt::Descriptor* p_desc = BTA_GATTC_GetDescriptor(conn_id, handle);
1273 
1274   if (!p_desc) {
1275     APPL_TRACE_ERROR("%s: error: descriptor is null!", __func__);
1276     return;
1277   }
1278 
1279   const gatt::Characteristic* characteristic =
1280       BTA_GATTC_GetOwningCharacteristic(conn_id, handle);
1281   const gatt::Service* service =
1282       BTA_GATTC_GetOwningService(conn_id, characteristic->value_handle);
1283 
1284   tBTA_HH_LE_RPT* p_rpt;
1285   p_rpt = bta_hh_le_find_report_entry(p_dev_cb, service->handle,
1286                                       GATT_UUID_HID_REPORT,
1287                                       characteristic->value_handle);
1288   if (p_rpt) bta_hh_le_save_report_ref(p_dev_cb, p_rpt, status, value, len);
1289 }
1290 
read_pref_conn_params_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)1291 static void read_pref_conn_params_cb(uint16_t conn_id, tGATT_STATUS status,
1292                                      uint16_t handle, uint16_t len,
1293                                      uint8_t* value, void* data) {
1294   if (status != GATT_SUCCESS) {
1295     APPL_TRACE_ERROR("%s: error: %d", __func__, status);
1296     return;
1297   }
1298 
1299   if (len != 8) {
1300     APPL_TRACE_ERROR("%s: we support only 16bit UUID: %d", __func__, len);
1301     return;
1302   }
1303 
1304   // TODO(jpawlowski): this should be done by GAP profile, remove when GAP is
1305   // fixed.
1306   uint8_t* pp = value;
1307   uint16_t min_interval, max_interval, latency, timeout;
1308   STREAM_TO_UINT16(min_interval, pp);
1309   STREAM_TO_UINT16(max_interval, pp);
1310   STREAM_TO_UINT16(latency, pp);
1311   STREAM_TO_UINT16(timeout, pp);
1312 
1313   // Make sure both min, and max are bigger than 11.25ms, lower values can
1314   // introduce audio issues if A2DP is also active.
1315   L2CA_AdjustConnectionIntervals(&min_interval, &max_interval,
1316                                  BTM_BLE_CONN_INT_MIN_LIMIT);
1317 
1318   // If the device has no preferred connection timeout, use the default.
1319   if (timeout == BTM_BLE_CONN_PARAM_UNDEF) timeout = BTM_BLE_CONN_TIMEOUT_DEF;
1320 
1321   if (min_interval < BTM_BLE_CONN_INT_MIN ||
1322       min_interval > BTM_BLE_CONN_INT_MAX ||
1323       max_interval < BTM_BLE_CONN_INT_MIN ||
1324       max_interval > BTM_BLE_CONN_INT_MAX ||
1325       latency > BTM_BLE_CONN_LATENCY_MAX ||
1326       timeout < BTM_BLE_CONN_SUP_TOUT_MIN ||
1327       timeout > BTM_BLE_CONN_SUP_TOUT_MAX || max_interval < min_interval) {
1328     APPL_TRACE_ERROR(
1329         "%s: Invalid connection parameters. min=%d, max=%d, latency=%d, "
1330         "timeout=%d",
1331         __func__, min_interval, max_interval, latency, timeout);
1332     return;
1333   }
1334 
1335   tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
1336 
1337   if (interop_match_addr(INTEROP_HID_PREF_CONN_SUP_TIMEOUT_3S,
1338                          (RawAddress*)&p_dev_cb->addr)) {
1339     if (timeout < 300) timeout = 300;
1340   }
1341 
1342   BTM_BleSetPrefConnParams(p_dev_cb->addr, min_interval, max_interval, latency,
1343                            timeout);
1344   L2CA_UpdateBleConnParams(p_dev_cb->addr, min_interval, max_interval, latency,
1345                            timeout, 0, 0);
1346 }
1347 
1348 /*******************************************************************************
1349  *
1350  * Function         bta_hh_le_search_hid_chars
1351  *
1352  * Description      This function discover all characteristics a service and
1353  *                  all descriptors available.
1354  *
1355  * Parameters:
1356  *
1357  ******************************************************************************/
bta_hh_le_search_hid_chars(tBTA_HH_DEV_CB * p_dev_cb,const gatt::Service * service)1358 static void bta_hh_le_search_hid_chars(tBTA_HH_DEV_CB* p_dev_cb,
1359                                        const gatt::Service* service) {
1360   tBTA_HH_LE_RPT* p_rpt;
1361 
1362   for (const gatt::Characteristic& charac : service->characteristics) {
1363     if (!charac.uuid.Is16Bit()) continue;
1364 
1365     uint16_t uuid16 = charac.uuid.As16Bit();
1366     LOG_INFO("%s: %s %s", __func__, bta_hh_uuid_to_str(uuid16),
1367              charac.uuid.ToString().c_str());
1368 
1369     switch (uuid16) {
1370       case GATT_UUID_HID_CONTROL_POINT:
1371         p_dev_cb->hid_srvc.control_point_handle = charac.value_handle;
1372         break;
1373       case GATT_UUID_HID_INFORMATION:
1374         /* only one instance per HID service */
1375         BtaGattQueue::ReadCharacteristic(p_dev_cb->conn_id, charac.value_handle,
1376                                          read_hid_info_cb, p_dev_cb);
1377         break;
1378       case GATT_UUID_HID_REPORT_MAP:
1379         /* only one instance per HID service */
1380         BtaGattQueue::ReadCharacteristic(p_dev_cb->conn_id, charac.value_handle,
1381                                          read_hid_report_map_cb, p_dev_cb);
1382         /* descriptor is optional */
1383         bta_hh_le_read_char_descriptor(p_dev_cb, charac.value_handle,
1384                                        GATT_UUID_EXT_RPT_REF_DESCR,
1385                                        read_ext_rpt_ref_desc_cb, p_dev_cb);
1386         break;
1387 
1388       case GATT_UUID_HID_REPORT:
1389         p_rpt = bta_hh_le_find_alloc_report_entry(
1390             p_dev_cb, p_dev_cb->hid_srvc.srvc_inst_id, GATT_UUID_HID_REPORT,
1391             charac.value_handle);
1392         if (p_rpt == NULL) {
1393           APPL_TRACE_ERROR("%s: Add report entry failed !!!", __func__);
1394           break;
1395         }
1396 
1397         if (p_rpt->rpt_type != BTA_HH_RPTT_INPUT) break;
1398 
1399         bta_hh_le_read_char_descriptor(p_dev_cb, charac.value_handle,
1400                                        GATT_UUID_RPT_REF_DESCR,
1401                                        read_report_ref_desc_cb, p_dev_cb);
1402         break;
1403 
1404       /* found boot mode report types */
1405       case GATT_UUID_HID_BT_KB_OUTPUT:
1406       case GATT_UUID_HID_BT_MOUSE_INPUT:
1407       case GATT_UUID_HID_BT_KB_INPUT:
1408         if (bta_hh_le_find_alloc_report_entry(p_dev_cb, service->handle, uuid16,
1409                                               charac.value_handle) == NULL)
1410           APPL_TRACE_ERROR("%s: Add report entry failed !!!", __func__);
1411 
1412         break;
1413 
1414       default:
1415         APPL_TRACE_DEBUG("%s: not processing %s 0x%04d", __func__,
1416                          bta_hh_uuid_to_str(uuid16), uuid16);
1417     }
1418   }
1419 
1420   /* Make sure PROTO_MODE is processed as last */
1421   for (const gatt::Characteristic& charac : service->characteristics) {
1422     if (charac.uuid == Uuid::From16Bit(GATT_UUID_HID_PROTO_MODE)) {
1423       p_dev_cb->hid_srvc.proto_mode_handle = charac.value_handle;
1424       bta_hh_le_set_protocol_mode(p_dev_cb, p_dev_cb->mode);
1425       break;
1426     }
1427   }
1428 }
1429 
1430 /*******************************************************************************
1431  *
1432  * Function         bta_hh_le_srvc_search_cmpl
1433  *
1434  * Description      This function process the GATT service search complete.
1435  *
1436  * Parameters:
1437  *
1438  ******************************************************************************/
bta_hh_le_srvc_search_cmpl(tBTA_GATTC_SEARCH_CMPL * p_data)1439 static void bta_hh_le_srvc_search_cmpl(tBTA_GATTC_SEARCH_CMPL* p_data) {
1440   tBTA_HH_DEV_CB* p_dev_cb = bta_hh_le_find_dev_cb_by_conn_id(p_data->conn_id);
1441 
1442   /* service search exception or no HID service is supported on remote */
1443   if (p_dev_cb == NULL) return;
1444 
1445   if (p_data->status != GATT_SUCCESS) {
1446     p_dev_cb->status = BTA_HH_ERR_SDP;
1447     /* close the connection and report service discovery complete with error */
1448     bta_hh_le_api_disc_act(p_dev_cb);
1449     return;
1450   }
1451 
1452   const std::list<gatt::Service>* services =
1453       BTA_GATTC_GetServices(p_data->conn_id);
1454 
1455   bool have_hid = false;
1456   for (const gatt::Service& service : *services) {
1457     if (service.uuid == Uuid::From16Bit(UUID_SERVCLASS_LE_HID) &&
1458         service.is_primary && !have_hid) {
1459       have_hid = true;
1460 
1461       /* found HID primamry service */
1462       p_dev_cb->hid_srvc.in_use = true;
1463       p_dev_cb->hid_srvc.srvc_inst_id = service.handle;
1464       p_dev_cb->hid_srvc.proto_mode_handle = 0;
1465       p_dev_cb->hid_srvc.control_point_handle = 0;
1466 
1467       bta_hh_le_search_hid_chars(p_dev_cb, &service);
1468 
1469       APPL_TRACE_DEBUG("%s: have HID service inst_id= %d", __func__,
1470                        p_dev_cb->hid_srvc.srvc_inst_id);
1471     } else if (service.uuid == Uuid::From16Bit(UUID_SERVCLASS_SCAN_PARAM)) {
1472 
1473       for (const gatt::Characteristic& charac : service.characteristics) {
1474         if (charac.uuid == Uuid::From16Bit(GATT_UUID_SCAN_REFRESH)) {
1475 
1476           if (charac.properties & GATT_CHAR_PROP_BIT_NOTIFY)
1477             p_dev_cb->scps_notify |= BTA_HH_LE_SCPS_NOTIFY_SPT;
1478           else
1479             p_dev_cb->scps_notify = BTA_HH_LE_SCPS_NOTIFY_NONE;
1480 
1481           break;
1482         }
1483       }
1484     } else if (service.uuid == Uuid::From16Bit(UUID_SERVCLASS_GAP_SERVER)) {
1485       // TODO(jpawlowski): this should be done by GAP profile, remove when GAP
1486       // is fixed.
1487       for (const gatt::Characteristic& charac : service.characteristics) {
1488         if (charac.uuid == Uuid::From16Bit(GATT_UUID_GAP_PREF_CONN_PARAM)) {
1489           /* read the char value */
1490           BtaGattQueue::ReadCharacteristic(p_dev_cb->conn_id,
1491                                            charac.value_handle,
1492                                            read_pref_conn_params_cb, p_dev_cb);
1493           break;
1494         }
1495       }
1496     }
1497   }
1498 
1499   bta_hh_le_gatt_disc_cmpl(p_dev_cb, p_dev_cb->status);
1500 }
1501 
1502 /*******************************************************************************
1503  *
1504  * Function         bta_hh_le_input_rpt_notify
1505  *
1506  * Description      process the notificaton event, most likely for input report.
1507  *
1508  * Parameters:
1509  *
1510  ******************************************************************************/
bta_hh_le_input_rpt_notify(tBTA_GATTC_NOTIFY * p_data)1511 static void bta_hh_le_input_rpt_notify(tBTA_GATTC_NOTIFY* p_data) {
1512   tBTA_HH_DEV_CB* p_dev_cb = bta_hh_le_find_dev_cb_by_conn_id(p_data->conn_id);
1513   uint8_t app_id;
1514   uint8_t* p_buf;
1515   tBTA_HH_LE_RPT* p_rpt;
1516 
1517   if (p_dev_cb == NULL) {
1518     APPL_TRACE_ERROR(
1519         "%s: notification received from Unknown device, conn_id: 0x%04x",
1520         __func__, p_data->conn_id);
1521     return;
1522   }
1523 
1524   const gatt::Characteristic* p_char =
1525       BTA_GATTC_GetCharacteristic(p_dev_cb->conn_id, p_data->handle);
1526   if (p_char == NULL) {
1527     APPL_TRACE_ERROR(
1528         "%s: notification received for Unknown Characteristic, conn_id: "
1529         "0x%04x, handle: 0x%04x",
1530         __func__, p_dev_cb->conn_id, p_data->handle);
1531     return;
1532   }
1533 
1534   app_id = p_dev_cb->app_id;
1535 
1536   const gatt::Service* p_svc =
1537       BTA_GATTC_GetOwningService(p_dev_cb->conn_id, p_char->value_handle);
1538 
1539   p_rpt = bta_hh_le_find_report_entry(
1540       p_dev_cb, p_svc->handle, p_char->uuid.As16Bit(), p_char->value_handle);
1541   if (p_rpt == NULL) {
1542     APPL_TRACE_ERROR(
1543         "%s: notification received for Unknown Report, uuid: %s, handle: "
1544         "0x%04x",
1545         __func__, p_char->uuid.ToString().c_str(), p_char->value_handle);
1546     return;
1547   }
1548 
1549   if (p_char->uuid == Uuid::From16Bit(GATT_UUID_HID_BT_MOUSE_INPUT))
1550     app_id = BTA_HH_APP_ID_MI;
1551   else if (p_char->uuid == Uuid::From16Bit(GATT_UUID_HID_BT_KB_INPUT))
1552     app_id = BTA_HH_APP_ID_KB;
1553 
1554   APPL_TRACE_DEBUG("Notification received on report ID: %d", p_rpt->rpt_id);
1555 
1556   /* need to append report ID to the head of data */
1557   if (p_rpt->rpt_id != 0) {
1558     p_buf = (uint8_t*)osi_malloc(p_data->len + 1);
1559 
1560     p_buf[0] = p_rpt->rpt_id;
1561     memcpy(&p_buf[1], p_data->value, p_data->len);
1562     ++p_data->len;
1563   } else {
1564     p_buf = p_data->value;
1565   }
1566 
1567   bta_hh_co_data((uint8_t)p_dev_cb->hid_handle, p_buf, p_data->len,
1568                  p_dev_cb->mode, 0, /* no sub class*/
1569                  p_dev_cb->dscp_info.ctry_code, p_dev_cb->addr, app_id);
1570 
1571   if (p_buf != p_data->value) osi_free(p_buf);
1572 }
1573 
1574 /*******************************************************************************
1575  *
1576  * Function         bta_hh_gatt_open_fail
1577  *
1578  * Description      action function to process the open fail
1579  *
1580  * Returns          void
1581  *
1582  ******************************************************************************/
bta_hh_le_open_fail(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)1583 void bta_hh_le_open_fail(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
1584   tBTA_HH_CONN conn_dat;
1585 
1586   /* open failure in the middle of service discovery, clear all services */
1587   if (p_cb->disc_active & BTA_HH_LE_DISC_HIDS) {
1588     bta_hh_clear_service_cache(p_cb);
1589   }
1590 
1591   p_cb->disc_active = BTA_HH_LE_DISC_NONE;
1592   /* Failure in opening connection or GATT discovery failure */
1593   conn_dat.handle = p_cb->hid_handle;
1594   conn_dat.bda = p_cb->addr;
1595   conn_dat.le_hid = true;
1596   conn_dat.scps_supported = p_cb->scps_supported;
1597   conn_dat.status = p_cb->status;
1598   if (p_data->le_close.reason != GATT_CONN_OK) {
1599     conn_dat.status = BTA_HH_ERR;
1600   }
1601 
1602   /* Report OPEN fail event */
1603   (*bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH*)&conn_dat);
1604 }
1605 
1606 /*******************************************************************************
1607  *
1608  * Function         bta_hh_gatt_close
1609  *
1610  * Description      action function to process the GATT close in the state
1611  *                  machine.
1612  *
1613  * Returns          void
1614  *
1615  ******************************************************************************/
bta_hh_gatt_close(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)1616 void bta_hh_gatt_close(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
1617 
1618   /* deregister all notification */
1619   bta_hh_le_deregister_input_notif(p_cb);
1620   /* finaliza device driver */
1621   bta_hh_co_close(p_cb->hid_handle, p_cb->app_id);
1622   /* update total conn number */
1623   bta_hh_cb.cnt_num--;
1624 
1625   tBTA_HH_CBDATA disc_dat = {
1626       .status = p_cb->status,
1627       .handle = p_cb->hid_handle,
1628   };
1629   (*bta_hh_cb.p_cback)(BTA_HH_CLOSE_EVT, (tBTA_HH*)&disc_dat);
1630 
1631   /* if no connection is active and HH disable is signaled, disable service */
1632   if (bta_hh_cb.cnt_num == 0 && bta_hh_cb.w4_disable) {
1633     bta_hh_disc_cmpl();
1634   } else if (kBTA_HH_LE_RECONN &&
1635              p_data->le_close.reason == GATT_CONN_TIMEOUT) {
1636     bta_hh_le_add_dev_bg_conn(p_cb, false);
1637   }
1638 }
1639 
1640 /*******************************************************************************
1641  *
1642  * Function         bta_hh_le_api_disc_act
1643  *
1644  * Description      initaite a Close API to a remote HID device
1645  *
1646  * Returns          void
1647  *
1648  ******************************************************************************/
bta_hh_le_api_disc_act(tBTA_HH_DEV_CB * p_cb)1649 void bta_hh_le_api_disc_act(tBTA_HH_DEV_CB* p_cb) {
1650   if (p_cb->conn_id == GATT_INVALID_CONN_ID) {
1651     LOG_ERROR("Tried to disconnect HID device with invalid id");
1652     return;
1653   }
1654 
1655   BtaGattQueue::Clean(p_cb->conn_id);
1656   BTA_GATTC_Close(p_cb->conn_id);
1657   /* remove device from background connection if intended to disconnect,
1658      do not allow reconnection */
1659   bta_hh_le_remove_dev_bg_conn(p_cb);
1660 }
1661 
1662 /*******************************************************************************
1663  *
1664  * Function         read_report_cb
1665  *
1666  * Description      Process the Read report complete, send GET_REPORT_EVT to
1667  *                  application with the report data.
1668  *
1669  * Parameters:
1670  *
1671  ******************************************************************************/
read_report_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)1672 static void read_report_cb(uint16_t conn_id, tGATT_STATUS status,
1673                            uint16_t handle, uint16_t len, uint8_t* value,
1674                            void* data) {
1675   const gatt::Characteristic* p_char =
1676       BTA_GATTC_GetCharacteristic(conn_id, handle);
1677 
1678   if (p_char == NULL) return;
1679 
1680   uint16_t char_uuid = p_char->uuid.As16Bit();
1681 
1682   if (char_uuid != GATT_UUID_HID_REPORT &&
1683       char_uuid != GATT_UUID_HID_BT_KB_INPUT &&
1684       char_uuid != GATT_UUID_HID_BT_KB_OUTPUT &&
1685       char_uuid != GATT_UUID_HID_BT_MOUSE_INPUT &&
1686       char_uuid != GATT_UUID_BATTERY_LEVEL) {
1687     APPL_TRACE_ERROR("%s: Unexpected Read UUID: 0x%04x", __func__, char_uuid);
1688     return;
1689   }
1690 
1691   tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
1692   if (p_dev_cb->w4_evt != BTA_HH_GET_RPT_EVT) {
1693     APPL_TRACE_ERROR("Unexpected READ cmpl, w4_evt = %d", p_dev_cb->w4_evt);
1694     return;
1695   }
1696 
1697   /* GET_REPORT */
1698   BT_HDR* p_buf = NULL;
1699   tBTA_HH_LE_RPT* p_rpt;
1700   tBTA_HH_HSDATA hs_data;
1701   uint8_t* pp;
1702 
1703   memset(&hs_data, 0, sizeof(hs_data));
1704   hs_data.status = BTA_HH_ERR;
1705   hs_data.handle = p_dev_cb->hid_handle;
1706 
1707   if (status == GATT_SUCCESS) {
1708     const gatt::Service* p_svc =
1709         BTA_GATTC_GetOwningService(conn_id, p_char->value_handle);
1710 
1711     p_rpt = bta_hh_le_find_report_entry(p_dev_cb, p_svc->handle, char_uuid,
1712                                         p_char->value_handle);
1713 
1714     if (p_rpt != NULL && len) {
1715       p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + len + 1);
1716       /* pack data send to app */
1717       hs_data.status = BTA_HH_OK;
1718       p_buf->len = len + 1;
1719       p_buf->layer_specific = 0;
1720       p_buf->offset = 0;
1721 
1722       /* attach report ID as the first byte of the report before sending it to
1723        * USB HID driver */
1724       pp = (uint8_t*)(p_buf + 1);
1725       UINT8_TO_STREAM(pp, p_rpt->rpt_id);
1726       memcpy(pp, value, len);
1727 
1728       hs_data.rsp_data.p_rpt_data = p_buf;
1729     }
1730   }
1731 
1732   p_dev_cb->w4_evt = 0;
1733   (*bta_hh_cb.p_cback)(BTA_HH_GET_RPT_EVT, (tBTA_HH*)&hs_data);
1734 
1735   osi_free_and_reset((void**)&p_buf);
1736 }
1737 
1738 /*******************************************************************************
1739  *
1740  * Function         bta_hh_le_get_rpt
1741  *
1742  * Description      GET_REPORT on a LE HID Report
1743  *
1744  * Returns          void
1745  *
1746  ******************************************************************************/
bta_hh_le_get_rpt(tBTA_HH_DEV_CB * p_cb,tBTA_HH_RPT_TYPE r_type,uint8_t rpt_id)1747 static void bta_hh_le_get_rpt(tBTA_HH_DEV_CB* p_cb, tBTA_HH_RPT_TYPE r_type,
1748                               uint8_t rpt_id) {
1749   tBTA_HH_LE_RPT* p_rpt = bta_hh_le_find_rpt_by_idtype(
1750       p_cb->hid_srvc.report, p_cb->mode, r_type, rpt_id);
1751 
1752   if (p_rpt == NULL) {
1753     APPL_TRACE_ERROR("%s: no matching report", __func__);
1754     return;
1755   }
1756 
1757   p_cb->w4_evt = BTA_HH_GET_RPT_EVT;
1758   BtaGattQueue::ReadCharacteristic(p_cb->conn_id, p_rpt->char_inst_id,
1759                                    read_report_cb, p_cb);
1760 }
1761 
write_report_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,void * data)1762 static void write_report_cb(uint16_t conn_id, tGATT_STATUS status,
1763                             uint16_t handle, void* data) {
1764   tBTA_HH_CBDATA cback_data;
1765   tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
1766   uint16_t cb_evt = p_dev_cb->w4_evt;
1767 
1768   if (cb_evt == 0) return;
1769 
1770   APPL_TRACE_DEBUG("bta_hh_le_write_cmpl w4_evt: %d", p_dev_cb->w4_evt);
1771 
1772   const gatt::Characteristic* p_char =
1773       BTA_GATTC_GetCharacteristic(conn_id, handle);
1774 
1775   if (p_char == nullptr) return;
1776 
1777   uint16_t uuid = p_char->uuid.As16Bit();
1778   if (uuid != GATT_UUID_HID_REPORT && uuid != GATT_UUID_HID_BT_KB_INPUT &&
1779       uuid != GATT_UUID_HID_BT_MOUSE_INPUT &&
1780       uuid != GATT_UUID_HID_BT_KB_OUTPUT) {
1781     return;
1782   }
1783 
1784   /* Set Report finished */
1785   cback_data.handle = p_dev_cb->hid_handle;
1786   cback_data.status = (status == GATT_SUCCESS) ? BTA_HH_OK : BTA_HH_ERR;
1787   p_dev_cb->w4_evt = 0;
1788   (*bta_hh_cb.p_cback)(cb_evt, (tBTA_HH*)&cback_data);
1789 }
1790 /*******************************************************************************
1791  *
1792  * Function         bta_hh_le_write_rpt
1793  *
1794  * Description      SET_REPORT/or DATA output on a LE HID Report
1795  *
1796  * Returns          void
1797  *
1798  ******************************************************************************/
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)1799 static void bta_hh_le_write_rpt(tBTA_HH_DEV_CB* p_cb, tBTA_HH_RPT_TYPE r_type,
1800                                 BT_HDR* p_buf, uint16_t w4_evt) {
1801   tBTA_HH_LE_RPT* p_rpt;
1802   uint8_t rpt_id;
1803 
1804   if (p_buf == NULL || p_buf->len == 0) {
1805     APPL_TRACE_ERROR("%s: Illegal data", __func__);
1806     return;
1807   }
1808 
1809   /* strip report ID from the data */
1810   uint8_t* vec_start = (uint8_t*)(p_buf + 1) + p_buf->offset;
1811   STREAM_TO_UINT8(rpt_id, vec_start);
1812   vector<uint8_t> value(vec_start, vec_start + p_buf->len - 1);
1813 
1814   p_rpt = bta_hh_le_find_rpt_by_idtype(p_cb->hid_srvc.report, p_cb->mode,
1815                                        r_type, rpt_id);
1816   if (p_rpt == NULL) {
1817     APPL_TRACE_ERROR("%s: no matching report", __func__);
1818     osi_free(p_buf);
1819     return;
1820   }
1821 
1822   p_cb->w4_evt = w4_evt;
1823 
1824   const gatt::Characteristic* p_char =
1825       BTA_GATTC_GetCharacteristic(p_cb->conn_id, p_rpt->char_inst_id);
1826 
1827   tGATT_WRITE_TYPE write_type = GATT_WRITE;
1828   if (p_char && (p_char->properties & GATT_CHAR_PROP_BIT_WRITE_NR))
1829     write_type = GATT_WRITE_NO_RSP;
1830 
1831   BtaGattQueue::WriteCharacteristic(p_cb->conn_id, p_rpt->char_inst_id,
1832                                     std::move(value), write_type,
1833                                     write_report_cb, p_cb);
1834 }
1835 
1836 /*******************************************************************************
1837  *
1838  * Function         bta_hh_le_suspend
1839  *
1840  * Description      send LE suspend or exit suspend mode to remote device.
1841  *
1842  * Returns          void
1843  *
1844  ******************************************************************************/
bta_hh_le_suspend(tBTA_HH_DEV_CB * p_cb,tBTA_HH_TRANS_CTRL_TYPE ctrl_type)1845 static void bta_hh_le_suspend(tBTA_HH_DEV_CB* p_cb,
1846                               tBTA_HH_TRANS_CTRL_TYPE ctrl_type) {
1847   ctrl_type -= BTA_HH_CTRL_SUSPEND;
1848 
1849   // We don't care about response
1850   BtaGattQueue::WriteCharacteristic(
1851       p_cb->conn_id, p_cb->hid_srvc.control_point_handle, {(uint8_t)ctrl_type},
1852       GATT_WRITE_NO_RSP, NULL, NULL);
1853 }
1854 
1855 /*******************************************************************************
1856  *
1857  * Function         bta_hh_le_write_dev_act
1858  *
1859  * Description      Write LE device action. can be SET/GET/DATA transaction.
1860  *
1861  * Returns          void
1862  *
1863  ******************************************************************************/
bta_hh_le_write_dev_act(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)1864 void bta_hh_le_write_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
1865   switch (p_data->api_sndcmd.t_type) {
1866     case HID_TRANS_SET_PROTOCOL:
1867       p_cb->w4_evt = BTA_HH_SET_PROTO_EVT;
1868       bta_hh_le_set_protocol_mode(p_cb, p_data->api_sndcmd.param);
1869       break;
1870 
1871     case HID_TRANS_GET_PROTOCOL:
1872       bta_hh_le_get_protocol_mode(p_cb);
1873       break;
1874 
1875     case HID_TRANS_GET_REPORT:
1876       bta_hh_le_get_rpt(p_cb, p_data->api_sndcmd.param,
1877                         p_data->api_sndcmd.rpt_id);
1878       break;
1879 
1880     case HID_TRANS_SET_REPORT:
1881       bta_hh_le_write_rpt(p_cb, p_data->api_sndcmd.param,
1882                           p_data->api_sndcmd.p_data, BTA_HH_SET_RPT_EVT);
1883       break;
1884 
1885     case HID_TRANS_DATA: /* output report */
1886 
1887       bta_hh_le_write_rpt(p_cb, p_data->api_sndcmd.param,
1888                           p_data->api_sndcmd.p_data, BTA_HH_DATA_EVT);
1889       break;
1890 
1891     case HID_TRANS_CONTROL:
1892       /* no handshake event will be generated */
1893       /* if VC_UNPLUG is issued, set flag */
1894       if (p_data->api_sndcmd.param == BTA_HH_CTRL_SUSPEND ||
1895           p_data->api_sndcmd.param == BTA_HH_CTRL_EXIT_SUSPEND) {
1896         bta_hh_le_suspend(p_cb, p_data->api_sndcmd.param);
1897       }
1898       break;
1899 
1900     default:
1901       APPL_TRACE_ERROR("%s unsupported transaction for BLE HID device: %d",
1902                        __func__, p_data->api_sndcmd.t_type);
1903       break;
1904   }
1905 }
1906 
1907 /*******************************************************************************
1908  *
1909  * Function         bta_hh_le_get_dscp_act
1910  *
1911  * Description      Send ReportDescriptor to application for all HID services.
1912  *
1913  * Returns          void
1914  *
1915  ******************************************************************************/
bta_hh_le_get_dscp_act(tBTA_HH_DEV_CB * p_cb)1916 void bta_hh_le_get_dscp_act(tBTA_HH_DEV_CB* p_cb) {
1917   if (p_cb->hid_srvc.in_use) {
1918     p_cb->dscp_info.descriptor.dl_len = p_cb->hid_srvc.descriptor.dl_len;
1919     p_cb->dscp_info.descriptor.dsc_list = p_cb->hid_srvc.descriptor.dsc_list;
1920 
1921     (*bta_hh_cb.p_cback)(BTA_HH_GET_DSCP_EVT, (tBTA_HH*)&p_cb->dscp_info);
1922   }
1923 }
1924 
1925 /*******************************************************************************
1926  *
1927  * Function         bta_hh_le_add_dev_bg_conn
1928  *
1929  * Description      Remove a LE HID device from back ground connection
1930  *                  procedure.
1931  *
1932  * Returns          void
1933  *
1934  ******************************************************************************/
bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB * p_cb,bool check_bond)1935 static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB* p_cb, bool check_bond) {
1936   bool to_add = true;
1937 
1938   if (check_bond) {
1939     /* start reconnection if remote is a bonded device */
1940     if (!BTM_IsLinkKeyKnown(p_cb->addr, BT_TRANSPORT_LE)) to_add = false;
1941   }
1942 
1943   if (!p_cb->in_bg_conn && to_add) {
1944     /* add device into BG connection to accept remote initiated connection */
1945     BTA_GATTC_Open(bta_hh_cb.gatt_if, p_cb->addr, false, false);
1946     p_cb->in_bg_conn = true;
1947   }
1948   return;
1949 }
1950 
1951 /*******************************************************************************
1952  *
1953  * Function         bta_hh_le_add_device
1954  *
1955  * Description      Add a LE HID device as a known device, and also add the
1956  *                  address
1957  *                  into back ground connection WL for incoming connection.
1958  *
1959  * Returns          void
1960  *
1961  ******************************************************************************/
bta_hh_le_add_device(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_MAINT_DEV * p_dev_info)1962 uint8_t bta_hh_le_add_device(tBTA_HH_DEV_CB* p_cb,
1963                              const tBTA_HH_MAINT_DEV* p_dev_info) {
1964   p_cb->hid_handle = bta_hh_le_get_le_dev_hdl(p_cb->index);
1965   if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) return BTA_HH_INVALID_HANDLE;
1966   bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index;
1967 
1968   /* update DI information */
1969   bta_hh_update_di_info(
1970       p_cb, p_dev_info->dscp_info.vendor_id, p_dev_info->dscp_info.product_id,
1971       p_dev_info->dscp_info.version, p_dev_info->dscp_info.flag);
1972 
1973   /* add to BTA device list */
1974   bta_hh_add_device_to_list(
1975       p_cb, p_cb->hid_handle, p_dev_info->attr_mask,
1976       &p_dev_info->dscp_info.descriptor, p_dev_info->sub_class,
1977       p_dev_info->dscp_info.ssr_max_latency, p_dev_info->dscp_info.ssr_min_tout,
1978       p_dev_info->app_id);
1979 
1980   bta_hh_le_add_dev_bg_conn(p_cb, false);
1981 
1982   return p_cb->hid_handle;
1983 }
1984 
1985 /*******************************************************************************
1986  *
1987  * Function         bta_hh_le_remove_dev_bg_conn
1988  *
1989  * Description      Remove a LE HID device from back ground connection
1990  *                  procedure.
1991  *
1992  * Returns          void
1993  *
1994  ******************************************************************************/
bta_hh_le_remove_dev_bg_conn(tBTA_HH_DEV_CB * p_dev_cb)1995 void bta_hh_le_remove_dev_bg_conn(tBTA_HH_DEV_CB* p_dev_cb) {
1996   if (p_dev_cb->in_bg_conn) {
1997     LOG_DEBUG("Removing from background connection device:%s",
1998               PRIVATE_ADDRESS(p_dev_cb->addr));
1999     p_dev_cb->in_bg_conn = false;
2000 
2001     BTA_GATTC_CancelOpen(bta_hh_cb.gatt_if, p_dev_cb->addr, false);
2002   }
2003 
2004   /* deregister all notifications */
2005   bta_hh_le_deregister_input_notif(p_dev_cb);
2006 }
2007 
2008 /*******************************************************************************
2009  *
2010  * Function         bta_hh_gattc_callback
2011  *
2012  * Description      This is GATT client callback function used in BTA HH.
2013  *
2014  * Parameters:
2015  *
2016  ******************************************************************************/
bta_hh_gattc_callback(tBTA_GATTC_EVT event,tBTA_GATTC * p_data)2017 static void bta_hh_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
2018   tBTA_HH_DEV_CB* p_dev_cb;
2019   APPL_TRACE_DEBUG("bta_hh_gattc_callback event = %d", event);
2020   if (p_data == NULL) return;
2021 
2022   switch (event) {
2023     case BTA_GATTC_DEREG_EVT: /* 1 */
2024       bta_hh_cleanup_disable(
2025           static_cast<tBTA_HH_STATUS>(p_data->reg_oper.status));
2026       break;
2027 
2028     case BTA_GATTC_OPEN_EVT: /* 2 */
2029       p_dev_cb = bta_hh_le_find_dev_cb_by_bda(p_data->open.remote_bda);
2030       if (p_dev_cb) {
2031         bta_hh_sm_execute(p_dev_cb, BTA_HH_GATT_OPEN_EVT,
2032                           (tBTA_HH_DATA*)&p_data->open);
2033       }
2034       break;
2035 
2036     case BTA_GATTC_CLOSE_EVT: /* 5 */
2037       bta_hh_le_close(p_data->close);
2038       break;
2039 
2040     case BTA_GATTC_SEARCH_CMPL_EVT: /* 6 */
2041       bta_hh_le_srvc_search_cmpl(&p_data->search_cmpl);
2042       break;
2043 
2044     case BTA_GATTC_NOTIF_EVT: /* 10 */
2045       bta_hh_le_input_rpt_notify(&p_data->notify);
2046       break;
2047 
2048     case BTA_GATTC_ENC_CMPL_CB_EVT: /* 17 */
2049       p_dev_cb = bta_hh_le_find_dev_cb_by_bda(p_data->enc_cmpl.remote_bda);
2050       if (p_dev_cb) {
2051         bta_hh_sm_execute(p_dev_cb, BTA_HH_GATT_ENC_CMPL_EVT,
2052                           (tBTA_HH_DATA*)&p_data->enc_cmpl);
2053       }
2054       break;
2055 
2056     default:
2057       break;
2058   }
2059 }
2060 
2061 /*******************************************************************************
2062  *
2063  * Function         bta_hh_process_cache_rpt
2064  *
2065  * Description      Process the cached reports
2066  *
2067  * Parameters:
2068  *
2069  ******************************************************************************/
bta_hh_process_cache_rpt(tBTA_HH_DEV_CB * p_cb,tBTA_HH_RPT_CACHE_ENTRY * p_rpt_cache,uint8_t num_rpt)2070 static void bta_hh_process_cache_rpt(tBTA_HH_DEV_CB* p_cb,
2071                                      tBTA_HH_RPT_CACHE_ENTRY* p_rpt_cache,
2072                                      uint8_t num_rpt) {
2073   uint8_t i = 0;
2074   tBTA_HH_LE_RPT* p_rpt;
2075 
2076   if (num_rpt != 0) /* no cache is found */
2077   {
2078     p_cb->hid_srvc.in_use = true;
2079 
2080     /* set the descriptor info */
2081     p_cb->hid_srvc.descriptor.dl_len = p_cb->dscp_info.descriptor.dl_len;
2082     p_cb->hid_srvc.descriptor.dsc_list = p_cb->dscp_info.descriptor.dsc_list;
2083 
2084     for (; i < num_rpt; i++, p_rpt_cache++) {
2085       if ((p_rpt = bta_hh_le_find_alloc_report_entry(
2086                p_cb, p_rpt_cache->srvc_inst_id, p_rpt_cache->rpt_uuid,
2087                p_rpt_cache->char_inst_id)) == NULL) {
2088         APPL_TRACE_ERROR(
2089             "bta_hh_process_cache_rpt: allocation report entry failure");
2090         break;
2091       } else {
2092         p_rpt->rpt_type = p_rpt_cache->rpt_type;
2093         p_rpt->rpt_id = p_rpt_cache->rpt_id;
2094 
2095         if (p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT ||
2096             p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT ||
2097             (p_rpt->uuid == GATT_UUID_HID_REPORT &&
2098              p_rpt->rpt_type == BTA_HH_RPTT_INPUT)) {
2099           p_rpt->client_cfg_value = GATT_CLT_CONFIG_NOTIFICATION;
2100         }
2101       }
2102     }
2103   }
2104 }
2105