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