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