1 /******************************************************************************
2  *
3  *  Copyright 2009-2012 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 /*******************************************************************************
20  *
21  *  Filename:      btif_hh.c
22  *
23  *  Description:   HID Host Profile Bluetooth Interface
24  *
25  *
26  ******************************************************************************/
27 
28 #define LOG_TAG "bt_btif_hh"
29 
30 #include "btif_hh.h"
31 
32 #include <base/logging.h>
33 #include <errno.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <unistd.h>
38 
39 #include "bt_common.h"
40 #include "bta_api.h"
41 #include "btif_common.h"
42 #include "btif_storage.h"
43 #include "btif_util.h"
44 #include "l2c_api.h"
45 #include "osi/include/log.h"
46 #include "osi/include/osi.h"
47 
48 #define BTIF_HH_APP_ID_MI 0x01
49 #define BTIF_HH_APP_ID_KB 0x02
50 
51 #define COD_HID_KEYBOARD 0x0540
52 #define COD_HID_POINTING 0x0580
53 #define COD_HID_COMBO 0x05C0
54 
55 #define KEYSTATE_FILEPATH \
56   "/data/misc/bluedroid/bt_hh_ks"  // keep this in sync with HID host jni
57 
58 #define HID_REPORT_CAPSLOCK 0x39
59 #define HID_REPORT_NUMLOCK 0x53
60 #define HID_REPORT_SCROLLLOCK 0x47
61 
62 // For Apple Magic Mouse
63 #define MAGICMOUSE_VENDOR_ID 0x05ac
64 #define MAGICMOUSE_PRODUCT_ID 0x030d
65 
66 #define LOGITECH_KB_MX5500_VENDOR_ID 0x046D
67 #define LOGITECH_KB_MX5500_PRODUCT_ID 0xB30B
68 
69 extern const int BT_UID;
70 extern const int BT_GID;
71 static int btif_hh_keylockstates = 0;  // The current key state of each key
72 
73 #define BTIF_HH_ID_1 0
74 #define BTIF_HH_DEV_DISCONNECTED 3
75 
76 #define BTIF_TIMEOUT_VUP_MS (3 * 1000)
77 
78 #ifndef BTUI_HH_SECURITY
79 #define BTUI_HH_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
80 #endif
81 
82 /* HH request events */
83 typedef enum {
84   BTIF_HH_CONNECT_REQ_EVT = 0,
85   BTIF_HH_DISCONNECT_REQ_EVT,
86   BTIF_HH_VUP_REQ_EVT
87 } btif_hh_req_evt_t;
88 
89 /*******************************************************************************
90  *  Constants & Macros
91  ******************************************************************************/
92 #define BTIF_HH_SERVICES (BTA_HID_SERVICE_MASK)
93 
94 /*******************************************************************************
95  *  Local type definitions
96  ******************************************************************************/
97 
98 typedef struct hid_kb_list {
99   uint16_t product_id;
100   uint16_t version_id;
101   const char* kb_name;
102 } tHID_KB_LIST;
103 
104 /*******************************************************************************
105  *  Static variables
106  ******************************************************************************/
107 btif_hh_cb_t btif_hh_cb;
108 
109 static bthh_callbacks_t* bt_hh_callbacks = NULL;
110 
111 /* List of HID keyboards for which the NUMLOCK state needs to be
112  * turned ON by default. Add devices to this list to apply the
113  * NUMLOCK state toggle on fpr first connect.*/
114 static tHID_KB_LIST hid_kb_numlock_on_list[] = {{LOGITECH_KB_MX5500_PRODUCT_ID,
115                                                  LOGITECH_KB_MX5500_VENDOR_ID,
116                                                  "Logitech MX5500 Keyboard"}};
117 
118 #define CHECK_BTHH_INIT()                                             \
119   do {                                                                \
120     if (bt_hh_callbacks == NULL) {                                    \
121       BTIF_TRACE_WARNING("BTHH: %s: BTHH not initialized", __func__); \
122       return BT_STATUS_NOT_READY;                                     \
123     }                                                                 \
124   } while (0)
125 
126 /*******************************************************************************
127  *  Static functions
128  ******************************************************************************/
129 
130 /*******************************************************************************
131  *  Externs
132  ******************************************************************************/
133 extern void bta_hh_co_destroy(int fd);
134 extern void bta_hh_co_write(int fd, uint8_t* rpt, uint16_t len);
135 extern bt_status_t btif_dm_remove_bond(const RawAddress* bd_addr);
136 extern void bta_hh_co_send_hid_info(btif_hh_device_t* p_dev,
137                                     const char* dev_name, uint16_t vendor_id,
138                                     uint16_t product_id, uint16_t version,
139                                     uint8_t ctry_code, int dscp_len,
140                                     uint8_t* p_dscp);
141 extern bool check_cod(const RawAddress* remote_bdaddr, uint32_t cod);
142 extern void btif_dm_cb_remove_bond(const RawAddress* bd_addr);
143 extern bool check_cod_hid(const RawAddress* remote_bdaddr);
144 extern int scru_ascii_2_hex(char* p_ascii, int len, uint8_t* p_hex);
145 extern void btif_dm_hh_open_failed(RawAddress* bdaddr);
146 extern void btif_hd_service_registration();
147 
148 /*****************************************************************************
149  *  Local Function prototypes
150  ****************************************************************************/
151 static void set_keylockstate(int keymask, bool isSet);
152 static void toggle_os_keylockstates(int fd, int changedkeystates);
153 static void sync_lockstate_on_connect(btif_hh_device_t* p_dev);
154 // static void hh_update_keyboard_lockstates(btif_hh_device_t *p_dev);
155 void btif_hh_timer_timeout(void* data);
156 void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data);
157 
158 /*******************************************************************************
159  *  Functions
160  ******************************************************************************/
161 
get_keylockstates()162 static int get_keylockstates() { return btif_hh_keylockstates; }
163 
set_keylockstate(int keymask,bool isSet)164 static void set_keylockstate(int keymask, bool isSet) {
165   if (isSet) btif_hh_keylockstates |= keymask;
166 }
167 
168 /*******************************************************************************
169  *
170  * Function         toggle_os_keylockstates
171  *
172  * Description      Function to toggle the keyboard lock states managed by the
173  linux.
174  *                  This function is used in by two call paths
175  *                  (1) if the lock state change occurred from an onscreen
176  keyboard,
177  *                  this function is called to update the lock state maintained
178                     for the HID keyboard(s)
179  *                  (2) if a HID keyboard is disconnected and reconnected,
180  *                  this function is called to update the lock state maintained
181                     for the HID keyboard(s)
182  * Returns          void
183  ******************************************************************************/
184 
toggle_os_keylockstates(int fd,int changedlockstates)185 static void toggle_os_keylockstates(int fd, int changedlockstates) {
186   BTIF_TRACE_EVENT("%s: fd = %d, changedlockstates = 0x%x", __func__, fd,
187                    changedlockstates);
188   uint8_t hidreport[9];
189   int reportIndex;
190   memset(hidreport, 0, 9);
191   hidreport[0] = 1;
192   reportIndex = 4;
193 
194   if (changedlockstates & BTIF_HH_KEYSTATE_MASK_CAPSLOCK) {
195     BTIF_TRACE_DEBUG("%s Setting CAPSLOCK", __func__);
196     hidreport[reportIndex++] = (uint8_t)HID_REPORT_CAPSLOCK;
197   }
198 
199   if (changedlockstates & BTIF_HH_KEYSTATE_MASK_NUMLOCK) {
200     BTIF_TRACE_DEBUG("%s Setting NUMLOCK", __func__);
201     hidreport[reportIndex++] = (uint8_t)HID_REPORT_NUMLOCK;
202   }
203 
204   if (changedlockstates & BTIF_HH_KEYSTATE_MASK_SCROLLLOCK) {
205     BTIF_TRACE_DEBUG("%s Setting SCROLLLOCK", __func__);
206     hidreport[reportIndex++] = (uint8_t)HID_REPORT_SCROLLLOCK;
207   }
208 
209   BTIF_TRACE_DEBUG(
210       "Writing hidreport #1 to os: "
211       "%s:  %x %x %x",
212       __func__, hidreport[0], hidreport[1], hidreport[2]);
213   BTIF_TRACE_DEBUG("%s:  %x %x %x", __func__, hidreport[3], hidreport[4],
214                    hidreport[5]);
215   BTIF_TRACE_DEBUG("%s:  %x %x %x", __func__, hidreport[6], hidreport[7],
216                    hidreport[8]);
217   bta_hh_co_write(fd, hidreport, sizeof(hidreport));
218   usleep(200000);
219   memset(hidreport, 0, 9);
220   hidreport[0] = 1;
221   BTIF_TRACE_DEBUG(
222       "Writing hidreport #2 to os: "
223       "%s:  %x %x %x",
224       __func__, hidreport[0], hidreport[1], hidreport[2]);
225   BTIF_TRACE_DEBUG("%s:  %x %x %x", __func__, hidreport[3], hidreport[4],
226                    hidreport[5]);
227   BTIF_TRACE_DEBUG("%s:  %x %x %x ", __func__, hidreport[6], hidreport[7],
228                    hidreport[8]);
229   bta_hh_co_write(fd, hidreport, sizeof(hidreport));
230 }
231 
232 /*******************************************************************************
233  *
234  * Function         create_pbuf
235  *
236  * Description      Helper function to create p_buf for send_data or set_report
237  *
238  ******************************************************************************/
create_pbuf(uint16_t len,uint8_t * data)239 static BT_HDR* create_pbuf(uint16_t len, uint8_t* data) {
240   BT_HDR* p_buf = (BT_HDR*)osi_malloc(len + BTA_HH_MIN_OFFSET + sizeof(BT_HDR));
241   uint8_t* pbuf_data;
242 
243   p_buf->len = len;
244   p_buf->offset = BTA_HH_MIN_OFFSET;
245 
246   pbuf_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
247   memcpy(pbuf_data, data, len);
248 
249   return p_buf;
250 }
251 
252 /*******************************************************************************
253  *
254  * Function         update_keyboard_lockstates
255  *
256  * Description      Sends a report to the keyboard to set the lock states of
257  *                  keys.
258  *
259  ******************************************************************************/
update_keyboard_lockstates(btif_hh_device_t * p_dev)260 static void update_keyboard_lockstates(btif_hh_device_t* p_dev) {
261   uint8_t len = 2; /* reportid + 1 byte report*/
262   BT_HDR* p_buf;
263   uint8_t data[] = {0x01, /* report id */
264                     static_cast<uint8_t>(btif_hh_keylockstates)}; /* keystate */
265 
266   /* Set report for other keyboards */
267   BTIF_TRACE_EVENT("%s: setting report on dev_handle %d to 0x%x", __func__,
268                    p_dev->dev_handle, btif_hh_keylockstates);
269 
270   /* Get SetReport buffer */
271   p_buf = create_pbuf(len, data);
272   if (p_buf != NULL) {
273     p_buf->layer_specific = BTA_HH_RPTT_OUTPUT;
274     BTA_HhSendData(p_dev->dev_handle, p_dev->bd_addr, p_buf);
275   }
276 }
277 
278 /*******************************************************************************
279  *
280  * Function         sync_lockstate_on_connect
281  *
282  * Description      Function to update the keyboard lock states managed by the
283  *                  OS when a HID keyboard is connected or disconnected and
284  *                  reconnected
285  *
286  * Returns          void
287  ******************************************************************************/
sync_lockstate_on_connect(btif_hh_device_t * p_dev)288 static void sync_lockstate_on_connect(btif_hh_device_t* p_dev) {
289   int keylockstates;
290 
291   BTIF_TRACE_EVENT(
292       "%s: Syncing keyboard lock states after "
293       "reconnect...",
294       __func__);
295   /*If the device is connected, update keyboard state */
296   update_keyboard_lockstates(p_dev);
297 
298   /*Check if the lockstate of caps,scroll,num is set.
299    If so, send a report to the kernel
300   so the lockstate is in sync */
301   keylockstates = get_keylockstates();
302   if (keylockstates) {
303     BTIF_TRACE_DEBUG(
304         "%s: Sending hid report to kernel "
305         "indicating lock key state 0x%x",
306         __func__, keylockstates);
307     usleep(200000);
308     toggle_os_keylockstates(p_dev->fd, keylockstates);
309   } else {
310     BTIF_TRACE_DEBUG(
311         "%s: NOT sending hid report to kernel "
312         "indicating lock key state 0x%x",
313         __func__, keylockstates);
314   }
315 }
316 
317 /*******************************************************************************
318  *
319  * Function         btif_hh_find_connected_dev_by_handle
320  *
321  * Description      Return the connected device pointer of the specified device
322  *                  handle
323  *
324  * Returns          Device entry pointer in the device table
325  ******************************************************************************/
btif_hh_find_connected_dev_by_handle(uint8_t handle)326 btif_hh_device_t* btif_hh_find_connected_dev_by_handle(uint8_t handle) {
327   uint32_t i;
328   for (i = 0; i < BTIF_HH_MAX_HID; i++) {
329     if (btif_hh_cb.devices[i].dev_status == BTHH_CONN_STATE_CONNECTED &&
330         btif_hh_cb.devices[i].dev_handle == handle) {
331       return &btif_hh_cb.devices[i];
332     }
333   }
334   return NULL;
335 }
336 
337 /*******************************************************************************
338  *
339  * Function         btif_hh_find_dev_by_bda
340  *
341  * Description      Return the device pointer of the specified RawAddress.
342  *
343  * Returns          Device entry pointer in the device table
344  ******************************************************************************/
btif_hh_find_dev_by_bda(const RawAddress & bd_addr)345 static btif_hh_device_t* btif_hh_find_dev_by_bda(const RawAddress& bd_addr) {
346   uint32_t i;
347   for (i = 0; i < BTIF_HH_MAX_HID; i++) {
348     if (btif_hh_cb.devices[i].dev_status != BTHH_CONN_STATE_UNKNOWN &&
349         btif_hh_cb.devices[i].bd_addr == bd_addr) {
350       return &btif_hh_cb.devices[i];
351     }
352   }
353   return NULL;
354 }
355 
356 /*******************************************************************************
357  *
358  * Function         btif_hh_find_connected_dev_by_bda
359  *
360  * Description      Return the connected device pointer of the specified
361  *                  RawAddress.
362  *
363  * Returns          Device entry pointer in the device table
364  ******************************************************************************/
btif_hh_find_connected_dev_by_bda(const RawAddress & bd_addr)365 static btif_hh_device_t* btif_hh_find_connected_dev_by_bda(
366     const RawAddress& bd_addr) {
367   uint32_t i;
368   for (i = 0; i < BTIF_HH_MAX_HID; i++) {
369     if (btif_hh_cb.devices[i].dev_status == BTHH_CONN_STATE_CONNECTED &&
370         btif_hh_cb.devices[i].bd_addr == bd_addr) {
371       return &btif_hh_cb.devices[i];
372     }
373   }
374   return NULL;
375 }
376 
377 /*******************************************************************************
378  *
379  * Function      btif_hh_stop_vup_timer
380  *
381  * Description  stop vitual unplug timer
382  *
383  * Returns      void
384  ******************************************************************************/
btif_hh_stop_vup_timer(RawAddress * bd_addr)385 void btif_hh_stop_vup_timer(RawAddress* bd_addr) {
386   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
387 
388   if (p_dev != NULL) {
389     BTIF_TRACE_DEBUG("stop VUP timer");
390     alarm_free(p_dev->vup_timer);
391     p_dev->vup_timer = NULL;
392   }
393 }
394 /*******************************************************************************
395  *
396  * Function      btif_hh_start_vup_timer
397  *
398  * Description  start virtual unplug timer
399  *
400  * Returns      void
401  ******************************************************************************/
btif_hh_start_vup_timer(const RawAddress * bd_addr)402 void btif_hh_start_vup_timer(const RawAddress* bd_addr) {
403   BTIF_TRACE_DEBUG("%s", __func__);
404 
405   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
406   CHECK(p_dev != NULL);
407 
408   alarm_free(p_dev->vup_timer);
409   p_dev->vup_timer = alarm_new("btif_hh.vup_timer");
410   alarm_set_on_mloop(p_dev->vup_timer, BTIF_TIMEOUT_VUP_MS,
411                      btif_hh_timer_timeout, p_dev);
412 }
413 
414 /*******************************************************************************
415  *
416  * Function         btif_hh_add_added_dev
417  *
418  * Description      Add a new device to the added device list.
419  *
420  * Returns          true if add successfully, otherwise false.
421  ******************************************************************************/
btif_hh_add_added_dev(const RawAddress & bda,tBTA_HH_ATTR_MASK attr_mask)422 bool btif_hh_add_added_dev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask) {
423   int i;
424   for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
425     if (btif_hh_cb.added_devices[i].bd_addr == bda) {
426       LOG(WARNING) << " Device " << bda << " already added";
427       return false;
428     }
429   }
430   for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
431     if (btif_hh_cb.added_devices[i].bd_addr.IsEmpty()) {
432       LOG(WARNING) << " Added device " << bda;
433       btif_hh_cb.added_devices[i].bd_addr = bda;
434       btif_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE;
435       btif_hh_cb.added_devices[i].attr_mask = attr_mask;
436       return true;
437     }
438   }
439 
440   BTIF_TRACE_WARNING("%s: Error, out of space to add device", __func__);
441   return false;
442 }
443 
444 /*******************************************************************************
445  **
446  ** Function         btif_hh_remove_device
447  **
448  ** Description      Remove an added device from the stack.
449  **
450  ** Returns          void
451  ******************************************************************************/
btif_hh_remove_device(RawAddress bd_addr)452 void btif_hh_remove_device(RawAddress bd_addr) {
453   int i;
454   btif_hh_device_t* p_dev;
455   btif_hh_added_device_t* p_added_dev;
456 
457   LOG(INFO) << __func__ << ": bda = " << bd_addr;
458 
459   for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
460     p_added_dev = &btif_hh_cb.added_devices[i];
461     if (p_added_dev->bd_addr == bd_addr) {
462       BTA_HhRemoveDev(p_added_dev->dev_handle);
463       btif_storage_remove_hid_info(p_added_dev->bd_addr);
464       memset(&(p_added_dev->bd_addr), 0, 6);
465       p_added_dev->dev_handle = BTA_HH_INVALID_HANDLE;
466       break;
467     }
468   }
469 
470   p_dev = btif_hh_find_dev_by_bda(bd_addr);
471   if (p_dev == NULL) {
472     LOG(WARNING) << " Oops, can't find device " << bd_addr;
473     return;
474   }
475 
476   /* need to notify up-layer device is disconnected to avoid state out of sync
477    * with up-layer */
478   HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr),
479             BTHH_CONN_STATE_DISCONNECTED);
480 
481   p_dev->dev_status = BTHH_CONN_STATE_UNKNOWN;
482   p_dev->dev_handle = BTA_HH_INVALID_HANDLE;
483   p_dev->ready_for_data = false;
484 
485   if (btif_hh_cb.device_num > 0) {
486     btif_hh_cb.device_num--;
487   } else {
488     BTIF_TRACE_WARNING("%s: device_num = 0", __func__);
489   }
490 
491   p_dev->hh_keep_polling = 0;
492   p_dev->hh_poll_thread_id = -1;
493   BTIF_TRACE_DEBUG("%s: uhid fd = %d", __func__, p_dev->fd);
494   if (p_dev->fd >= 0) {
495     bta_hh_co_destroy(p_dev->fd);
496     p_dev->fd = -1;
497   }
498 }
499 
btif_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO * dest,tBTA_HH_DEV_DSCP_INFO * src)500 bool btif_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO* dest,
501                            tBTA_HH_DEV_DSCP_INFO* src) {
502   memset(dest, 0, sizeof(tBTA_HH_DEV_DSCP_INFO));
503   dest->descriptor.dl_len = 0;
504   if (src->descriptor.dl_len > 0) {
505     dest->descriptor.dsc_list = (uint8_t*)osi_malloc(src->descriptor.dl_len);
506   }
507   memcpy(dest->descriptor.dsc_list, src->descriptor.dsc_list,
508          src->descriptor.dl_len);
509   dest->descriptor.dl_len = src->descriptor.dl_len;
510   dest->vendor_id = src->vendor_id;
511   dest->product_id = src->product_id;
512   dest->version = src->version;
513   dest->ctry_code = src->ctry_code;
514   dest->ssr_max_latency = src->ssr_max_latency;
515   dest->ssr_min_tout = src->ssr_min_tout;
516   return true;
517 }
518 
519 /*******************************************************************************
520  *
521  * Function         btif_hh_virtual_unplug
522  *
523  * Description      Virtual unplug initiated from the BTIF thread context
524  *                  Special handling for HID mouse-
525  *
526  * Returns          void
527  *
528  ******************************************************************************/
529 
btif_hh_virtual_unplug(const RawAddress * bd_addr)530 bt_status_t btif_hh_virtual_unplug(const RawAddress* bd_addr) {
531   BTIF_TRACE_DEBUG("%s", __func__);
532   btif_hh_device_t* p_dev;
533   p_dev = btif_hh_find_dev_by_bda(*bd_addr);
534   if ((p_dev != NULL) && (p_dev->dev_status == BTHH_CONN_STATE_CONNECTED) &&
535       (p_dev->attr_mask & HID_VIRTUAL_CABLE)) {
536     BTIF_TRACE_DEBUG("%s: Sending BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG for: %s", __func__,
537                      bd_addr->ToString().c_str());
538     /* start the timer */
539     btif_hh_start_vup_timer(bd_addr);
540     p_dev->local_vup = true;
541     BTA_HhSendCtrl(p_dev->dev_handle, BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG);
542     return BT_STATUS_SUCCESS;
543   } else if ((p_dev != NULL) &&
544              (p_dev->dev_status == BTHH_CONN_STATE_CONNECTED)) {
545     BTIF_TRACE_ERROR("%s: Virtual unplug not suported, disconnecting device: %s",
546                      __func__, bd_addr->ToString().c_str());
547     /* start the timer */
548     btif_hh_start_vup_timer(bd_addr);
549     p_dev->local_vup = true;
550     BTA_HhClose(p_dev->dev_handle);
551     return BT_STATUS_SUCCESS;
552   } else {
553     BTIF_TRACE_ERROR("%s: Error, device %s not opened, status = %d", __func__,
554                      bd_addr->ToString().c_str(), btif_hh_cb.status);
555     if ((btif_hh_cb.pending_conn_address == *bd_addr) &&
556        (btif_hh_cb.status == BTIF_HH_DEV_CONNECTING)) {
557           btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
558           btif_hh_cb.pending_conn_address = RawAddress::kEmpty;
559     }
560     return BT_STATUS_FAIL;
561   }
562 }
563 
564 /*******************************************************************************
565  *
566  * Function         btif_hh_connect
567  *
568  * Description      connection initiated from the BTIF thread context
569  *
570  * Returns          int status
571  *
572  ******************************************************************************/
573 
btif_hh_connect(const RawAddress * bd_addr)574 bt_status_t btif_hh_connect(const RawAddress* bd_addr) {
575   btif_hh_added_device_t* added_dev = NULL;
576   CHECK_BTHH_INIT();
577   BTIF_TRACE_EVENT("BTHH: %s", __func__);
578   btif_hh_device_t* dev = btif_hh_find_dev_by_bda(*bd_addr);
579   if (!dev && btif_hh_cb.device_num >= BTIF_HH_MAX_HID) {
580     // No space for more HID device now.
581     BTIF_TRACE_WARNING(
582         "%s: Error, exceeded the maximum supported HID device number %d",
583         __func__, BTIF_HH_MAX_HID);
584     return BT_STATUS_FAIL;
585   }
586 
587   for (int i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
588     if (btif_hh_cb.added_devices[i].bd_addr == *bd_addr) {
589       added_dev = &btif_hh_cb.added_devices[i];
590       LOG(WARNING) << __func__ << ": Device " << *bd_addr
591                    << " already added, attr_mask = 0x" << std::hex
592                    << added_dev->attr_mask;
593     }
594   }
595 
596   if (added_dev != NULL) {
597     if (added_dev->dev_handle == BTA_HH_INVALID_HANDLE) {
598       // No space for more HID device now.
599       LOG(ERROR) << __func__ << ": Error, device " << *bd_addr
600                  << " added but addition failed";
601       added_dev->bd_addr = RawAddress::kEmpty;
602       added_dev->dev_handle = BTA_HH_INVALID_HANDLE;
603       return BT_STATUS_FAIL;
604     }
605   }
606 
607   /* Not checking the NORMALLY_Connectible flags from sdp record, and anyways
608    sending this
609    request from host, for subsequent user initiated connection. If the remote is
610    not in
611    pagescan mode, we will do 2 retries to connect before giving up */
612   btif_hh_cb.status = BTIF_HH_DEV_CONNECTING;
613   btif_hh_cb.pending_conn_address = *bd_addr;
614   BTA_HhOpen(*bd_addr, BTA_HH_PROTO_RPT_MODE, BTUI_HH_SECURITY);
615 
616   // TODO(jpawlowski); make cback accept const and remove tmp!
617   auto tmp = *bd_addr;
618   HAL_CBACK(bt_hh_callbacks, connection_state_cb, &tmp,
619             BTHH_CONN_STATE_CONNECTING);
620   return BT_STATUS_SUCCESS;
621 }
622 
623 /*******************************************************************************
624  *
625  * Function         btif_hh_disconnect
626  *
627  * Description      disconnection initiated from the BTIF thread context
628  *
629  * Returns          void
630  *
631  ******************************************************************************/
632 
btif_hh_disconnect(RawAddress * bd_addr)633 void btif_hh_disconnect(RawAddress* bd_addr) {
634   btif_hh_device_t* p_dev;
635   p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
636   if (p_dev != NULL) {
637     BTA_HhClose(p_dev->dev_handle);
638   } else
639     BTIF_TRACE_DEBUG("%s-- Error: device not connected:", __func__);
640 }
641 
642 /*******************************************************************************
643  *
644  * Function         btif_btif_hh_setreport
645  *
646  * Description      setreport initiated from the BTIF thread context
647  *
648  * Returns          void
649  *
650  ******************************************************************************/
btif_hh_setreport(btif_hh_device_t * p_dev,bthh_report_type_t r_type,uint16_t size,uint8_t * report)651 void btif_hh_setreport(btif_hh_device_t* p_dev, bthh_report_type_t r_type,
652                        uint16_t size, uint8_t* report) {
653   BT_HDR* p_buf = create_pbuf(size, report);
654   if (p_buf == NULL) {
655     APPL_TRACE_ERROR("%s: Error, failed to allocate RPT buffer, size = %d",
656                      __func__, size);
657     return;
658   }
659   BTA_HhSetReport(p_dev->dev_handle, r_type, p_buf);
660 }
661 
662 /*******************************************************************************
663  *
664  * Function         btif_hh_service_registration
665  *
666  * Description      Registers or derigisters the hid host service
667  *
668  * Returns          none
669  *
670  ******************************************************************************/
btif_hh_service_registration(bool enable)671 void btif_hh_service_registration(bool enable) {
672   BTIF_TRACE_API("%s", __func__);
673 
674   BTIF_TRACE_API("enable = %d", enable);
675   if (bt_hh_callbacks == NULL) {
676     // The HID Host service was never initialized (it is either disabled or not
677     // available in this build). We should proceed directly to changing the HID
678     // Device service state (if needed).
679     if (!enable) {
680       btif_hd_service_registration();
681     }
682   } else if (enable) {
683     BTA_HhEnable(BTA_SEC_ENCRYPT, bte_hh_evt);
684   } else {
685     btif_hh_cb.service_dereg_active = TRUE;
686     BTA_HhDisable();
687   }
688 }
689 
690 /*******************************************************************************
691  *
692  *
693  * Function         btif_hh_getreport
694  *
695  * Description      getreport initiated from the BTIF thread context
696  *
697  * Returns          void
698  *
699  ******************************************************************************/
btif_hh_getreport(btif_hh_device_t * p_dev,bthh_report_type_t r_type,uint8_t reportId,uint16_t bufferSize)700 void btif_hh_getreport(btif_hh_device_t* p_dev, bthh_report_type_t r_type,
701                        uint8_t reportId, uint16_t bufferSize) {
702   BTA_HhGetReport(p_dev->dev_handle, r_type, reportId, bufferSize);
703 }
704 
705 /*****************************************************************************
706  *   Section name (Group of functions)
707  ****************************************************************************/
708 
709 /*****************************************************************************
710  *
711  *   btif hh api functions (no context switch)
712  *
713  ****************************************************************************/
714 
715 /*******************************************************************************
716  *
717  * Function         btif_hh_upstreams_evt
718  *
719  * Description      Executes HH UPSTREAMS events in btif context
720  *
721  * Returns          void
722  *
723  ******************************************************************************/
btif_hh_upstreams_evt(uint16_t event,char * p_param)724 static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
725   tBTA_HH* p_data = (tBTA_HH*)p_param;
726   btif_hh_device_t* p_dev = NULL;
727   int i;
728   int len, tmplen;
729 
730   BTIF_TRACE_DEBUG("%s: event=%s dereg = %d", __func__, dump_hh_event(event),
731                    btif_hh_cb.service_dereg_active);
732 
733   switch (event) {
734     case BTA_HH_ENABLE_EVT:
735       BTIF_TRACE_DEBUG("%s: BTA_HH_ENABLE_EVT: status =%d", __func__,
736                        p_data->status);
737       if (p_data->status == BTA_HH_OK) {
738         btif_hh_cb.status = BTIF_HH_ENABLED;
739         BTIF_TRACE_DEBUG("%s--Loading added devices", __func__);
740         /* Add hid descriptors for already bonded hid devices*/
741         btif_storage_load_bonded_hid_info();
742       } else {
743         btif_hh_cb.status = BTIF_HH_DISABLED;
744         BTIF_TRACE_WARNING(
745             "BTA_HH_ENABLE_EVT: Error, HH enabling failed, status = %d",
746             p_data->status);
747       }
748       break;
749 
750     case BTA_HH_DISABLE_EVT:
751       btif_hh_cb.status = BTIF_HH_DISABLED;
752       if (btif_hh_cb.service_dereg_active) {
753         BTIF_TRACE_DEBUG("BTA_HH_DISABLE_EVT: enabling HID Device service");
754         btif_hd_service_registration();
755         btif_hh_cb.service_dereg_active = FALSE;
756       }
757       if (p_data->status == BTA_HH_OK) {
758         int i;
759         // Clear the control block
760         for (i = 0; i < BTIF_HH_MAX_HID; i++) {
761           alarm_free(btif_hh_cb.devices[i].vup_timer);
762         }
763         memset(&btif_hh_cb, 0, sizeof(btif_hh_cb));
764         for (i = 0; i < BTIF_HH_MAX_HID; i++) {
765           btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN;
766         }
767       } else
768         BTIF_TRACE_WARNING(
769             "BTA_HH_DISABLE_EVT: Error, HH disabling failed, status = %d",
770             p_data->status);
771       break;
772 
773     case BTA_HH_OPEN_EVT:
774       BTIF_TRACE_WARNING("%s: BTA_HH_OPN_EVT: handle=%d, status =%d", __func__,
775                          p_data->conn.handle, p_data->conn.status);
776       btif_hh_cb.pending_conn_address = RawAddress::kEmpty;
777       if (p_data->conn.status == BTA_HH_OK) {
778         p_dev = btif_hh_find_connected_dev_by_handle(p_data->conn.handle);
779         if (p_dev == NULL) {
780           BTIF_TRACE_WARNING(
781               "BTA_HH_OPEN_EVT: Error, cannot find device with handle %d",
782               p_data->conn.handle);
783           btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
784           // The connect request must come from device side and exceeded the
785           // connected
786           // HID device number.
787           BTA_HhClose(p_data->conn.handle);
788           HAL_CBACK(bt_hh_callbacks, connection_state_cb,
789                     (RawAddress*)&p_data->conn.bda,
790                     BTHH_CONN_STATE_DISCONNECTED);
791         } else if (p_dev->fd < 0) {
792           BTIF_TRACE_WARNING(
793               "BTA_HH_OPEN_EVT: Error, failed to find the uhid driver...");
794           p_dev->bd_addr = p_data->conn.bda;
795           // remove the connection  and then try again to reconnect from the
796           // mouse side to recover
797           btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
798           BTA_HhClose(p_data->conn.handle);
799         } else {
800           BTIF_TRACE_WARNING(
801               "BTA_HH_OPEN_EVT: Found device...Getting dscp info for handle "
802               "... %d",
803               p_data->conn.handle);
804           p_dev->bd_addr = p_data->conn.bda;
805           btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_CONNECTED;
806           // Send set_idle if the peer_device is a keyboard
807           if (check_cod(&p_data->conn.bda, COD_HID_KEYBOARD) ||
808               check_cod(&p_data->conn.bda, COD_HID_COMBO))
809             BTA_HhSetIdle(p_data->conn.handle, 0);
810           btif_hh_cb.p_curr_dev =
811               btif_hh_find_connected_dev_by_handle(p_data->conn.handle);
812           BTA_HhGetDscpInfo(p_data->conn.handle);
813           p_dev->dev_status = BTHH_CONN_STATE_CONNECTED;
814           HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr),
815                     p_dev->dev_status);
816         }
817       } else {
818         RawAddress* bdaddr = &p_data->conn.bda;
819         btif_dm_hh_open_failed(bdaddr);
820         p_dev = btif_hh_find_dev_by_bda(*bdaddr);
821         if (p_dev != NULL) {
822           btif_hh_stop_vup_timer(&(p_dev->bd_addr));
823           if (p_dev->fd >= 0) {
824             bta_hh_co_destroy(p_dev->fd);
825             p_dev->fd = -1;
826           }
827           p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
828         }
829         HAL_CBACK(bt_hh_callbacks, connection_state_cb,
830                   (RawAddress*)&p_data->conn.bda, BTHH_CONN_STATE_DISCONNECTED);
831         btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
832       }
833       break;
834 
835     case BTA_HH_CLOSE_EVT:
836       BTIF_TRACE_DEBUG("BTA_HH_CLOSE_EVT: status = %d, handle = %d",
837                        p_data->dev_status.status, p_data->dev_status.handle);
838       p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
839       if (p_dev != NULL) {
840         BTIF_TRACE_DEBUG("%s: uhid fd=%d local_vup=%d", __func__, p_dev->fd,
841                          p_dev->local_vup);
842         btif_hh_stop_vup_timer(&(p_dev->bd_addr));
843         /* If this is a locally initiated VUP, remove the bond as ACL got
844          *  disconnected while VUP being processed.
845          */
846         if (p_dev->local_vup) {
847           p_dev->local_vup = false;
848           BTA_DmRemoveDevice(p_dev->bd_addr);
849         }
850 
851         btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
852         p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
853 
854         if (p_dev->fd >= 0) {
855           bta_hh_co_destroy(p_dev->fd);
856           p_dev->fd = -1;
857         }
858         HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr),
859                   p_dev->dev_status);
860       } else {
861         BTIF_TRACE_WARNING("Error: cannot find device with handle %d",
862                            p_data->dev_status.handle);
863       }
864       break;
865 
866     case BTA_HH_GET_RPT_EVT: {
867       BT_HDR* hdr = p_data->hs_data.rsp_data.p_rpt_data;
868       uint8_t* data = NULL;
869       uint16_t len = 0;
870 
871       BTIF_TRACE_DEBUG("BTA_HH_GET_RPT_EVT: status = %d, handle = %d",
872                        p_data->hs_data.status, p_data->hs_data.handle);
873       p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
874       if (p_dev) {
875         /* p_rpt_data is NULL in HANDSHAKE response case */
876         if (hdr) {
877           data = (uint8_t*)(hdr + 1) + hdr->offset;
878           len = hdr->len;
879           HAL_CBACK(bt_hh_callbacks, get_report_cb,
880                     (RawAddress*)&(p_dev->bd_addr),
881                     (bthh_status_t)p_data->hs_data.status, data, len);
882         } else {
883           HAL_CBACK(bt_hh_callbacks, handshake_cb,
884                     (RawAddress*)&(p_dev->bd_addr),
885                     (bthh_status_t)p_data->hs_data.status);
886         }
887       } else {
888         BTIF_TRACE_WARNING("Error: cannot find device with handle %d",
889                            p_data->hs_data.handle);
890       }
891       break;
892     }
893 
894     case BTA_HH_SET_RPT_EVT:
895       BTIF_TRACE_DEBUG("BTA_HH_SET_RPT_EVT: status = %d, handle = %d",
896                        p_data->dev_status.status, p_data->dev_status.handle);
897       p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
898       if (p_dev != NULL) {
899         HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr),
900                   (bthh_status_t)p_data->hs_data.status);
901       }
902       break;
903 
904     case BTA_HH_GET_PROTO_EVT:
905       p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
906       BTIF_TRACE_WARNING(
907           "BTA_HH_GET_PROTO_EVT: status = %d, handle = %d, proto = [%d], %s",
908           p_data->hs_data.status, p_data->hs_data.handle,
909           p_data->hs_data.rsp_data.proto_mode,
910           (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE)
911               ? "Report Mode"
912               : (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_BOOT_MODE)
913                     ? "Boot Mode"
914                     : "Unsupported");
915       if (p_data->hs_data.rsp_data.proto_mode != BTA_HH_PROTO_UNKNOWN) {
916         HAL_CBACK(bt_hh_callbacks, protocol_mode_cb,
917                   (RawAddress*)&(p_dev->bd_addr),
918                   (bthh_status_t)p_data->hs_data.status,
919                   (bthh_protocol_mode_t)p_data->hs_data.rsp_data.proto_mode);
920       } else {
921         HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr),
922                   (bthh_status_t)p_data->hs_data.status);
923       }
924       break;
925 
926     case BTA_HH_SET_PROTO_EVT:
927       BTIF_TRACE_DEBUG("BTA_HH_SET_PROTO_EVT: status = %d, handle = %d",
928                        p_data->dev_status.status, p_data->dev_status.handle);
929       p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
930       if (p_dev) {
931         HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr),
932                   (bthh_status_t)p_data->hs_data.status);
933       }
934       break;
935 
936     case BTA_HH_GET_IDLE_EVT:
937       BTIF_TRACE_DEBUG(
938           "BTA_HH_GET_IDLE_EVT: handle = %d, status = %d, rate = %d",
939           p_data->hs_data.handle, p_data->hs_data.status,
940           p_data->hs_data.rsp_data.idle_rate);
941       p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
942       HAL_CBACK(bt_hh_callbacks, idle_time_cb, (RawAddress*)&(p_dev->bd_addr),
943                 (bthh_status_t)p_data->hs_data.status,
944                 p_data->hs_data.rsp_data.idle_rate);
945       break;
946 
947     case BTA_HH_SET_IDLE_EVT:
948       BTIF_TRACE_DEBUG("BTA_HH_SET_IDLE_EVT: status = %d, handle = %d",
949                        p_data->dev_status.status, p_data->dev_status.handle);
950       break;
951 
952     case BTA_HH_GET_DSCP_EVT:
953       len = p_data->dscp_info.descriptor.dl_len;
954       BTIF_TRACE_DEBUG("BTA_HH_GET_DSCP_EVT: len = %d", len);
955       p_dev = btif_hh_cb.p_curr_dev;
956       if (p_dev == NULL) {
957         BTIF_TRACE_ERROR(
958             "BTA_HH_GET_DSCP_EVT: No HID device is currently connected");
959         return;
960       }
961       if (p_dev->fd < 0) {
962         LOG_ERROR(
963 
964             "BTA_HH_GET_DSCP_EVT: Error, failed to find the uhid driver...");
965         return;
966       }
967       {
968         const char* cached_name = NULL;
969         bt_bdname_t bdname;
970         bt_property_t prop_name;
971         BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_BDNAME,
972                                    sizeof(bt_bdname_t), &bdname);
973         if (btif_storage_get_remote_device_property(
974                 &p_dev->bd_addr, &prop_name) == BT_STATUS_SUCCESS) {
975           cached_name = (char*)bdname.name;
976         } else {
977           cached_name = "Bluetooth HID";
978         }
979 
980         BTIF_TRACE_WARNING("%s: name = %s", __func__, cached_name);
981         bta_hh_co_send_hid_info(p_dev, cached_name, p_data->dscp_info.vendor_id,
982                                 p_data->dscp_info.product_id,
983                                 p_data->dscp_info.version,
984                                 p_data->dscp_info.ctry_code, len,
985                                 p_data->dscp_info.descriptor.dsc_list);
986         if (btif_hh_add_added_dev(p_dev->bd_addr, p_dev->attr_mask)) {
987           tBTA_HH_DEV_DSCP_INFO dscp_info;
988           bt_status_t ret;
989           btif_hh_copy_hid_info(&dscp_info, &p_data->dscp_info);
990           VLOG(1) << "BTA_HH_GET_DSCP_EVT:bda = " << p_dev->bd_addr;
991           BTA_HhAddDev(p_dev->bd_addr, p_dev->attr_mask, p_dev->sub_class,
992                        p_dev->app_id, dscp_info);
993           // write hid info to nvram
994           ret = btif_storage_add_hid_device_info(
995               &(p_dev->bd_addr), p_dev->attr_mask, p_dev->sub_class,
996               p_dev->app_id, p_data->dscp_info.vendor_id,
997               p_data->dscp_info.product_id, p_data->dscp_info.version,
998               p_data->dscp_info.ctry_code, p_data->dscp_info.ssr_max_latency,
999               p_data->dscp_info.ssr_min_tout, len,
1000               p_data->dscp_info.descriptor.dsc_list);
1001 
1002           ASSERTC(ret == BT_STATUS_SUCCESS, "storing hid info failed", ret);
1003           BTIF_TRACE_WARNING("BTA_HH_GET_DSCP_EVT: Called add device");
1004 
1005           // Free buffer created for dscp_info;
1006           if (dscp_info.descriptor.dl_len > 0 &&
1007               dscp_info.descriptor.dsc_list != NULL) {
1008             osi_free_and_reset((void**)&dscp_info.descriptor.dsc_list);
1009             dscp_info.descriptor.dl_len = 0;
1010           }
1011         } else {
1012           // Device already added.
1013           BTIF_TRACE_WARNING("%s: Device already added ", __func__);
1014         }
1015         /*Sync HID Keyboard lockstates */
1016         tmplen = sizeof(hid_kb_numlock_on_list) / sizeof(tHID_KB_LIST);
1017         for (i = 0; i < tmplen; i++) {
1018           if (p_data->dscp_info.vendor_id ==
1019                   hid_kb_numlock_on_list[i].version_id &&
1020               p_data->dscp_info.product_id ==
1021                   hid_kb_numlock_on_list[i].product_id) {
1022             BTIF_TRACE_DEBUG(
1023                 "%s() idx[%d] Enabling "
1024                 "NUMLOCK for device :: %s",
1025                 __func__, i, hid_kb_numlock_on_list[i].kb_name);
1026             /* Enable NUMLOCK by default so that numeric
1027                 keys work from first keyboard connect */
1028             set_keylockstate(BTIF_HH_KEYSTATE_MASK_NUMLOCK, true);
1029             sync_lockstate_on_connect(p_dev);
1030             /* End Sync HID Keyboard lockstates */
1031             break;
1032           }
1033         }
1034       }
1035       break;
1036 
1037     case BTA_HH_ADD_DEV_EVT:
1038       BTIF_TRACE_WARNING("BTA_HH_ADD_DEV_EVT: status = %d, handle = %d",
1039                          p_data->dev_info.status, p_data->dev_info.handle);
1040       int i;
1041       for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
1042         if (btif_hh_cb.added_devices[i].bd_addr == p_data->dev_info.bda) {
1043           if (p_data->dev_info.status == BTA_HH_OK) {
1044             btif_hh_cb.added_devices[i].dev_handle = p_data->dev_info.handle;
1045           } else {
1046             btif_hh_cb.added_devices[i].bd_addr = RawAddress::kEmpty;
1047             btif_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE;
1048           }
1049           break;
1050         }
1051       }
1052       break;
1053     case BTA_HH_RMV_DEV_EVT:
1054       BTIF_TRACE_DEBUG("BTA_HH_RMV_DEV_EVT: status = %d, handle = %d",
1055                        p_data->dev_info.status, p_data->dev_info.handle);
1056       VLOG(1) << "BTA_HH_RMV_DEV_EVT:bda = " << p_data->dev_info.bda;
1057       break;
1058 
1059     case BTA_HH_VC_UNPLUG_EVT:
1060       BTIF_TRACE_DEBUG("BTA_HH_VC_UNPLUG_EVT: status = %d, handle = %d",
1061                        p_data->dev_status.status, p_data->dev_status.handle);
1062       p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
1063       btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
1064       if (p_dev != NULL) {
1065         VLOG(1) << "BTA_HH_VC_UNPLUG_EVT:bda = " << p_dev->bd_addr;
1066 
1067         /* Stop the VUP timer */
1068         btif_hh_stop_vup_timer(&(p_dev->bd_addr));
1069         p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
1070         BTIF_TRACE_DEBUG("%s---Sending connection state change", __func__);
1071         HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr),
1072                   p_dev->dev_status);
1073         BTIF_TRACE_DEBUG("%s---Removing HID bond", __func__);
1074         /* If it is locally initiated VUP or remote device has its major COD as
1075         Peripheral removed the bond.*/
1076         if (p_dev->local_vup || check_cod_hid(&(p_dev->bd_addr))) {
1077           p_dev->local_vup = false;
1078           BTA_DmRemoveDevice(p_dev->bd_addr);
1079         } else
1080           btif_hh_remove_device(p_dev->bd_addr);
1081         HAL_CBACK(bt_hh_callbacks, virtual_unplug_cb, &(p_dev->bd_addr),
1082                   (bthh_status_t)p_data->dev_status.status);
1083       }
1084       break;
1085 
1086     case BTA_HH_API_ERR_EVT:
1087       LOG_INFO("BTA_HH API_ERR");
1088       break;
1089 
1090     default:
1091       BTIF_TRACE_WARNING("%s: Unhandled event: %d", __func__, event);
1092       break;
1093   }
1094 }
1095 
1096 /*******************************************************************************
1097  *
1098  * Function         bte_hh_evt
1099  *
1100  * Description      Switches context from BTE to BTIF for all HH events
1101  *
1102  * Returns          void
1103  *
1104  ******************************************************************************/
1105 
bte_hh_evt(tBTA_HH_EVT event,tBTA_HH * p_data)1106 void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
1107   bt_status_t status;
1108   int param_len = 0;
1109 
1110   if (BTA_HH_ENABLE_EVT == event)
1111     param_len = sizeof(tBTA_HH_STATUS);
1112   else if (BTA_HH_OPEN_EVT == event)
1113     param_len = sizeof(tBTA_HH_CONN);
1114   else if (BTA_HH_DISABLE_EVT == event)
1115     param_len = sizeof(tBTA_HH_STATUS);
1116   else if (BTA_HH_CLOSE_EVT == event)
1117     param_len = sizeof(tBTA_HH_CBDATA);
1118   else if (BTA_HH_GET_DSCP_EVT == event)
1119     param_len = sizeof(tBTA_HH_DEV_DSCP_INFO);
1120   else if ((BTA_HH_GET_PROTO_EVT == event) || (BTA_HH_GET_RPT_EVT == event) ||
1121            (BTA_HH_GET_IDLE_EVT == event))
1122     param_len = sizeof(tBTA_HH_HSDATA);
1123   else if ((BTA_HH_SET_PROTO_EVT == event) || (BTA_HH_SET_RPT_EVT == event) ||
1124            (BTA_HH_VC_UNPLUG_EVT == event) || (BTA_HH_SET_IDLE_EVT == event))
1125     param_len = sizeof(tBTA_HH_CBDATA);
1126   else if ((BTA_HH_ADD_DEV_EVT == event) || (BTA_HH_RMV_DEV_EVT == event))
1127     param_len = sizeof(tBTA_HH_DEV_INFO);
1128   else if (BTA_HH_API_ERR_EVT == event)
1129     param_len = 0;
1130   /* switch context to btif task context (copy full union size for convenience)
1131    */
1132   status = btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event,
1133                                  (char*)p_data, param_len, NULL);
1134 
1135   /* catch any failed context transfers */
1136   ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
1137 }
1138 
1139 /*******************************************************************************
1140  *
1141  * Function         btif_hh_handle_evt
1142  *
1143  * Description      Switches context for immediate callback
1144  *
1145  * Returns          void
1146  *
1147  ******************************************************************************/
1148 
btif_hh_handle_evt(uint16_t event,char * p_param)1149 static void btif_hh_handle_evt(uint16_t event, char* p_param) {
1150   RawAddress* bd_addr = (RawAddress*)p_param;
1151   BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
1152   int ret;
1153   switch (event) {
1154     case BTIF_HH_CONNECT_REQ_EVT: {
1155       ret = btif_hh_connect(bd_addr);
1156       if (ret == BT_STATUS_SUCCESS) {
1157         HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr,
1158                   BTHH_CONN_STATE_CONNECTING);
1159       } else
1160         HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr,
1161                   BTHH_CONN_STATE_DISCONNECTED);
1162     } break;
1163 
1164     case BTIF_HH_DISCONNECT_REQ_EVT: {
1165       BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
1166       btif_hh_disconnect(bd_addr);
1167       HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr,
1168                 BTHH_CONN_STATE_DISCONNECTING);
1169     } break;
1170 
1171     case BTIF_HH_VUP_REQ_EVT: {
1172       BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
1173       ret = btif_hh_virtual_unplug(bd_addr);
1174     } break;
1175 
1176     default: {
1177       BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __func__, event);
1178     } break;
1179   }
1180 }
1181 
1182 /*******************************************************************************
1183  *
1184  * Function      btif_hh_timer_timeout
1185  *
1186  * Description   Process timer timeout
1187  *
1188  * Returns      void
1189  ******************************************************************************/
btif_hh_timer_timeout(void * data)1190 void btif_hh_timer_timeout(void* data) {
1191   btif_hh_device_t* p_dev = (btif_hh_device_t*)data;
1192   tBTA_HH_EVT event = BTA_HH_VC_UNPLUG_EVT;
1193   tBTA_HH p_data;
1194   int param_len = sizeof(tBTA_HH_CBDATA);
1195 
1196   BTIF_TRACE_DEBUG("%s", __func__);
1197   if (p_dev->dev_status != BTHH_CONN_STATE_CONNECTED) return;
1198 
1199   memset(&p_data, 0, sizeof(tBTA_HH));
1200   p_data.dev_status.status = BTHH_ERR;
1201   p_data.dev_status.handle = p_dev->dev_handle;
1202 
1203   /* switch context to btif task context */
1204   btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event, (char*)&p_data,
1205                         param_len, NULL);
1206 }
1207 
1208 /*******************************************************************************
1209  *
1210  * Function         btif_hh_init
1211  *
1212  * Description     initializes the hh interface
1213  *
1214  * Returns         bt_status_t
1215  *
1216  ******************************************************************************/
init(bthh_callbacks_t * callbacks)1217 static bt_status_t init(bthh_callbacks_t* callbacks) {
1218   uint32_t i;
1219   BTIF_TRACE_EVENT("%s", __func__);
1220 
1221   bt_hh_callbacks = callbacks;
1222   memset(&btif_hh_cb, 0, sizeof(btif_hh_cb));
1223   for (i = 0; i < BTIF_HH_MAX_HID; i++) {
1224     btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN;
1225   }
1226   /* Invoke the enable service API to the core to set the appropriate service_id
1227    */
1228   btif_enable_service(BTA_HID_SERVICE_ID);
1229   return BT_STATUS_SUCCESS;
1230 }
1231 
1232 /*******************************************************************************
1233  *
1234  * Function        connect
1235  *
1236  * Description     connect to hid device
1237  *
1238  * Returns         bt_status_t
1239  *
1240  ******************************************************************************/
connect(RawAddress * bd_addr)1241 static bt_status_t connect(RawAddress* bd_addr) {
1242   if (btif_hh_cb.status != BTIF_HH_DEV_CONNECTING) {
1243     btif_transfer_context(btif_hh_handle_evt, BTIF_HH_CONNECT_REQ_EVT,
1244                           (char*)bd_addr, sizeof(RawAddress), NULL);
1245     return BT_STATUS_SUCCESS;
1246   } else
1247     return BT_STATUS_BUSY;
1248 }
1249 
1250 /*******************************************************************************
1251  *
1252  * Function         disconnect
1253  *
1254  * Description      disconnect from hid device
1255  *
1256  * Returns         bt_status_t
1257  *
1258  ******************************************************************************/
disconnect(RawAddress * bd_addr)1259 static bt_status_t disconnect(RawAddress* bd_addr) {
1260   CHECK_BTHH_INIT();
1261   BTIF_TRACE_EVENT("BTHH: %s", __func__);
1262   btif_hh_device_t* p_dev;
1263 
1264   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1265     BTIF_TRACE_WARNING("%s: Error, HH status = %d", __func__,
1266                        btif_hh_cb.status);
1267     return BT_STATUS_FAIL;
1268   }
1269   p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1270   if (p_dev != NULL) {
1271     return btif_transfer_context(btif_hh_handle_evt, BTIF_HH_DISCONNECT_REQ_EVT,
1272                                  (char*)bd_addr, sizeof(RawAddress), NULL);
1273   } else {
1274     BTIF_TRACE_WARNING("%s: Error, device  not opened.", __func__);
1275     return BT_STATUS_FAIL;
1276   }
1277 }
1278 
1279 /*******************************************************************************
1280  *
1281  * Function         virtual_unplug
1282  *
1283  * Description      Virtual UnPlug (VUP) the specified HID device.
1284  *
1285  * Returns         bt_status_t
1286  *
1287  ******************************************************************************/
virtual_unplug(RawAddress * bd_addr)1288 static bt_status_t virtual_unplug(RawAddress* bd_addr) {
1289   CHECK_BTHH_INIT();
1290   BTIF_TRACE_EVENT("BTHH: %s", __func__);
1291   btif_hh_device_t* p_dev;
1292   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1293     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1294     return BT_STATUS_FAIL;
1295   }
1296   p_dev = btif_hh_find_dev_by_bda(*bd_addr);
1297   if (!p_dev) {
1298     BTIF_TRACE_ERROR("%s: Error, device %s not opened.", __func__,
1299                      bd_addr->ToString().c_str());
1300     return BT_STATUS_FAIL;
1301   }
1302   btif_transfer_context(btif_hh_handle_evt, BTIF_HH_VUP_REQ_EVT, (char*)bd_addr,
1303                         sizeof(RawAddress), NULL);
1304   return BT_STATUS_SUCCESS;
1305 }
1306 
1307 /*******************************************************************************
1308 **
1309 ** Function         get_idle_time
1310 **
1311 ** Description      Get the HID idle time
1312 **
1313 ** Returns         bt_status_t
1314 **
1315 *******************************************************************************/
get_idle_time(RawAddress * bd_addr)1316 static bt_status_t get_idle_time(RawAddress* bd_addr) {
1317   CHECK_BTHH_INIT();
1318 
1319   BTIF_TRACE_DEBUG("%s: addr = %s", __func__, bd_addr->ToString().c_str());
1320 
1321   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1322     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1323     return BT_STATUS_FAIL;
1324   }
1325 
1326   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1327   if (p_dev == NULL) return BT_STATUS_FAIL;
1328 
1329   BTA_HhGetIdle(p_dev->dev_handle);
1330   return BT_STATUS_SUCCESS;
1331 }
1332 
1333 /*******************************************************************************
1334 **
1335 ** Function         set_idle_time
1336 **
1337 ** Description      Set the HID idle time
1338 **
1339 ** Returns         bt_status_t
1340 **
1341 *******************************************************************************/
set_idle_time(RawAddress * bd_addr,uint8_t idle_time)1342 static bt_status_t set_idle_time(RawAddress* bd_addr, uint8_t idle_time) {
1343   CHECK_BTHH_INIT();
1344 
1345   BTIF_TRACE_DEBUG("%s: addr = %s, idle time = %d", __func__,
1346                    bd_addr->ToString().c_str(), idle_time);
1347 
1348   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1349     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1350     return BT_STATUS_FAIL;
1351   }
1352 
1353   btif_hh_device_t* p_dev = p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1354   if (p_dev == NULL) {
1355     BTIF_TRACE_WARNING("%s: addr = %s not opened", __func__,
1356                        bd_addr->ToString().c_str());
1357     return BT_STATUS_FAIL;
1358   }
1359 
1360   BTA_HhSetIdle(p_dev->dev_handle, idle_time);
1361   return BT_STATUS_SUCCESS;
1362 }
1363 
1364 /*******************************************************************************
1365  *
1366  * Function         set_info
1367  *
1368  * Description      Set the HID device descriptor for the specified HID device.
1369  *
1370  * Returns         bt_status_t
1371  *
1372  ******************************************************************************/
set_info(RawAddress * bd_addr,bthh_hid_info_t hid_info)1373 static bt_status_t set_info(RawAddress* bd_addr, bthh_hid_info_t hid_info) {
1374   CHECK_BTHH_INIT();
1375   tBTA_HH_DEV_DSCP_INFO dscp_info;
1376 
1377   VLOG(1) << __func__ << " BTHH: addr = " << *bd_addr;
1378   BTIF_TRACE_DEBUG(
1379       "BTHH: %s: sub_class = 0x%02x, app_id = %d, vendor_id = 0x%04x, "
1380       "product_id = 0x%04x, version= 0x%04x",
1381       __func__, hid_info.sub_class, hid_info.app_id, hid_info.vendor_id,
1382       hid_info.product_id, hid_info.version);
1383 
1384   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1385     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1386     return BT_STATUS_FAIL;
1387   }
1388 
1389   memset(&dscp_info, 0, sizeof(dscp_info));
1390   dscp_info.vendor_id = hid_info.vendor_id;
1391   dscp_info.product_id = hid_info.product_id;
1392   dscp_info.version = hid_info.version;
1393   dscp_info.ctry_code = hid_info.ctry_code;
1394 
1395   dscp_info.descriptor.dl_len = hid_info.dl_len;
1396   dscp_info.descriptor.dsc_list =
1397       (uint8_t*)osi_malloc(dscp_info.descriptor.dl_len);
1398   memcpy(dscp_info.descriptor.dsc_list, &(hid_info.dsc_list), hid_info.dl_len);
1399 
1400   if (btif_hh_add_added_dev(*bd_addr, hid_info.attr_mask)) {
1401     BTA_HhAddDev(*bd_addr, hid_info.attr_mask, hid_info.sub_class,
1402                  hid_info.app_id, dscp_info);
1403   }
1404 
1405   osi_free_and_reset((void**)&dscp_info.descriptor.dsc_list);
1406 
1407   return BT_STATUS_SUCCESS;
1408 }
1409 
1410 /*******************************************************************************
1411  *
1412  * Function         get_protocol
1413  *
1414  * Description      Get the HID proto mode.
1415  *
1416  * Returns         bt_status_t
1417  *
1418  ******************************************************************************/
get_protocol(RawAddress * bd_addr,UNUSED_ATTR bthh_protocol_mode_t protocolMode)1419 static bt_status_t get_protocol(RawAddress* bd_addr,
1420                                 UNUSED_ATTR bthh_protocol_mode_t protocolMode) {
1421   CHECK_BTHH_INIT();
1422 
1423   VLOG(1) << __func__ << " BTHH: addr = " << *bd_addr;
1424 
1425   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1426     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1427     return BT_STATUS_FAIL;
1428   }
1429 
1430   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1431   if (!p_dev) return BT_STATUS_FAIL;
1432 
1433   BTA_HhGetProtoMode(p_dev->dev_handle);
1434   return BT_STATUS_SUCCESS;
1435 }
1436 
1437 /*******************************************************************************
1438  *
1439  * Function         set_protocol
1440  *
1441  * Description      Set the HID proto mode.
1442  *
1443  * Returns         bt_status_t
1444  *
1445  ******************************************************************************/
set_protocol(RawAddress * bd_addr,bthh_protocol_mode_t protocolMode)1446 static bt_status_t set_protocol(RawAddress* bd_addr,
1447                                 bthh_protocol_mode_t protocolMode) {
1448   CHECK_BTHH_INIT();
1449   btif_hh_device_t* p_dev;
1450   uint8_t proto_mode = protocolMode;
1451 
1452   VLOG(1) << __func__ << " BTHH: proto_mod=" << protocolMode
1453           << " addr = " << *bd_addr;
1454 
1455   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1456     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1457     return BT_STATUS_FAIL;
1458   }
1459 
1460   p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1461   if (p_dev == NULL) {
1462     LOG(WARNING) << " Error, device" << *bd_addr << " not opened";
1463     return BT_STATUS_FAIL;
1464   } else if (protocolMode != BTA_HH_PROTO_RPT_MODE &&
1465              protocolMode != BTA_HH_PROTO_BOOT_MODE) {
1466     BTIF_TRACE_WARNING("%s: Error, device proto_mode = %d.", __func__,
1467                        proto_mode);
1468     return BT_STATUS_FAIL;
1469   } else {
1470     BTA_HhSetProtoMode(p_dev->dev_handle, protocolMode);
1471   }
1472 
1473   return BT_STATUS_SUCCESS;
1474 }
1475 
1476 /*******************************************************************************
1477  *
1478  * Function         get_report
1479  *
1480  * Description      Send a GET_REPORT to HID device.
1481  *
1482  * Returns         bt_status_t
1483  *
1484  ******************************************************************************/
get_report(RawAddress * bd_addr,bthh_report_type_t reportType,uint8_t reportId,int bufferSize)1485 static bt_status_t get_report(RawAddress* bd_addr,
1486                               bthh_report_type_t reportType, uint8_t reportId,
1487                               int bufferSize) {
1488   CHECK_BTHH_INIT();
1489   btif_hh_device_t* p_dev;
1490 
1491   VLOG(1) << __func__ << " BTHH: r_type = " << reportType
1492           << ", rpt_id = " << reportId << ", buf_size = " << bufferSize
1493           << " addr = " << *bd_addr;
1494 
1495   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1496     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1497     return BT_STATUS_FAIL;
1498   }
1499 
1500   p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1501   if (p_dev == NULL) {
1502     LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
1503     return BT_STATUS_FAIL;
1504   } else if (((int)reportType) <= BTA_HH_RPTT_RESRV ||
1505              ((int)reportType) > BTA_HH_RPTT_FEATURE) {
1506     LOG(ERROR) << " Error, report type=" << +reportType << " not supported";
1507     return BT_STATUS_FAIL;
1508   } else {
1509     BTA_HhGetReport(p_dev->dev_handle, reportType, reportId, bufferSize);
1510   }
1511 
1512   return BT_STATUS_SUCCESS;
1513 }
1514 
1515 /*******************************************************************************
1516  *
1517  * Function         set_report
1518  *
1519  * Description      Send a SET_REPORT to HID device.
1520  *
1521  * Returns         bt_status_t
1522  *
1523  ******************************************************************************/
set_report(RawAddress * bd_addr,bthh_report_type_t reportType,char * report)1524 static bt_status_t set_report(RawAddress* bd_addr,
1525                               bthh_report_type_t reportType, char* report) {
1526   CHECK_BTHH_INIT();
1527   btif_hh_device_t* p_dev;
1528 
1529   VLOG(1) << __func__ << " BTHH: reportType=" << reportType
1530           << " addr=" << *bd_addr;
1531 
1532   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1533     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1534     return BT_STATUS_FAIL;
1535   }
1536 
1537   p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1538   if (p_dev == NULL) {
1539     LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
1540     return BT_STATUS_FAIL;
1541   } else if (((int)reportType) <= BTA_HH_RPTT_RESRV ||
1542              ((int)reportType) > BTA_HH_RPTT_FEATURE) {
1543     LOG(ERROR) << " Error, report type=" << +reportType << " not supported";
1544     return BT_STATUS_FAIL;
1545   } else {
1546     int hex_bytes_filled;
1547     size_t len = (strlen(report) + 1) / 2;
1548     uint8_t* hexbuf = (uint8_t*)osi_calloc(len);
1549 
1550     /* Build a SetReport data buffer */
1551     // TODO
1552     hex_bytes_filled = ascii_2_hex(report, len, hexbuf);
1553     LOG_INFO("Hex bytes filled, hex value: %d", hex_bytes_filled);
1554     if (hex_bytes_filled) {
1555       BT_HDR* p_buf = create_pbuf(hex_bytes_filled, hexbuf);
1556       if (p_buf == NULL) {
1557         BTIF_TRACE_ERROR("%s: Error, failed to allocate RPT buffer, len = %d",
1558                          __func__, hex_bytes_filled);
1559         osi_free(hexbuf);
1560         return BT_STATUS_FAIL;
1561       }
1562       BTA_HhSetReport(p_dev->dev_handle, reportType, p_buf);
1563       osi_free(hexbuf);
1564       return BT_STATUS_SUCCESS;
1565     }
1566     osi_free(hexbuf);
1567     return BT_STATUS_FAIL;
1568   }
1569 }
1570 
1571 /*******************************************************************************
1572  *
1573  * Function         send_data
1574  *
1575  * Description      Send a SEND_DATA to HID device.
1576  *
1577  * Returns         bt_status_t
1578  *
1579  ******************************************************************************/
send_data(RawAddress * bd_addr,char * data)1580 static bt_status_t send_data(RawAddress* bd_addr, char* data) {
1581   CHECK_BTHH_INIT();
1582   btif_hh_device_t* p_dev;
1583 
1584   VLOG(1) << __func__ << " addr=" << *bd_addr;
1585 
1586   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1587     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1588     return BT_STATUS_FAIL;
1589   }
1590 
1591   p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1592   if (p_dev == NULL) {
1593     LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
1594     return BT_STATUS_FAIL;
1595   }
1596 
1597   else {
1598     int hex_bytes_filled;
1599     size_t len = (strlen(data) + 1) / 2;
1600     uint8_t* hexbuf = (uint8_t*)osi_calloc(len);
1601 
1602     /* Build a SendData data buffer */
1603     hex_bytes_filled = ascii_2_hex(data, len, hexbuf);
1604     BTIF_TRACE_ERROR("Hex bytes filled, hex value: %d, %d", hex_bytes_filled,
1605                      len);
1606 
1607     if (hex_bytes_filled) {
1608       BT_HDR* p_buf = create_pbuf(hex_bytes_filled, hexbuf);
1609       if (p_buf == NULL) {
1610         BTIF_TRACE_ERROR("%s: Error, failed to allocate RPT buffer, len = %d",
1611                          __func__, hex_bytes_filled);
1612         osi_free(hexbuf);
1613         return BT_STATUS_FAIL;
1614       }
1615       p_buf->layer_specific = BTA_HH_RPTT_OUTPUT;
1616       BTA_HhSendData(p_dev->dev_handle, *bd_addr, p_buf);
1617       osi_free(hexbuf);
1618       return BT_STATUS_SUCCESS;
1619     }
1620     osi_free(hexbuf);
1621     return BT_STATUS_FAIL;
1622   }
1623 }
1624 
1625 /*******************************************************************************
1626  *
1627  * Function         cleanup
1628  *
1629  * Description      Closes the HH interface
1630  *
1631  * Returns          bt_status_t
1632  *
1633  ******************************************************************************/
cleanup(void)1634 static void cleanup(void) {
1635   BTIF_TRACE_EVENT("%s", __func__);
1636   btif_hh_device_t* p_dev;
1637   int i;
1638   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1639     BTIF_TRACE_WARNING("%s: HH disabling or disabled already, status = %d",
1640                        __func__, btif_hh_cb.status);
1641     return;
1642   }
1643   if (bt_hh_callbacks) {
1644     btif_hh_cb.status = BTIF_HH_DISABLING;
1645     /* update flag, not to enable hid device service now as BT is switching off
1646      */
1647     btif_hh_cb.service_dereg_active = FALSE;
1648     btif_disable_service(BTA_HID_SERVICE_ID);
1649     bt_hh_callbacks = NULL;
1650   }
1651   for (i = 0; i < BTIF_HH_MAX_HID; i++) {
1652     p_dev = &btif_hh_cb.devices[i];
1653     if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->fd >= 0) {
1654       BTIF_TRACE_DEBUG("%s: Closing uhid fd = %d", __func__, p_dev->fd);
1655       if (p_dev->fd >= 0) {
1656         bta_hh_co_destroy(p_dev->fd);
1657         p_dev->fd = -1;
1658       }
1659       p_dev->hh_keep_polling = 0;
1660       p_dev->hh_poll_thread_id = -1;
1661     }
1662   }
1663 
1664 }
1665 
1666 static const bthh_interface_t bthhInterface = {
1667     sizeof(bthhInterface),
1668     init,
1669     connect,
1670     disconnect,
1671     virtual_unplug,
1672     set_info,
1673     get_protocol,
1674     set_protocol,
1675     get_idle_time,
1676     set_idle_time,
1677     get_report,
1678     set_report,
1679     send_data,
1680     cleanup,
1681 };
1682 
1683 /*******************************************************************************
1684  *
1685  * Function         btif_hh_execute_service
1686  *
1687  * Description      Initializes/Shuts down the service
1688  *
1689  * Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1690  *
1691  ******************************************************************************/
btif_hh_execute_service(bool b_enable)1692 bt_status_t btif_hh_execute_service(bool b_enable) {
1693   if (b_enable) {
1694     /* Enable and register with BTA-HH */
1695     BTA_HhEnable(BTUI_HH_SECURITY, bte_hh_evt);
1696   } else {
1697     /* Disable HH */
1698     BTA_HhDisable();
1699   }
1700   return BT_STATUS_SUCCESS;
1701 }
1702 
1703 /*******************************************************************************
1704  *
1705  * Function         btif_hh_get_interface
1706  *
1707  * Description      Get the hh callback interface
1708  *
1709  * Returns          bthh_interface_t
1710  *
1711  ******************************************************************************/
btif_hh_get_interface()1712 const bthh_interface_t* btif_hh_get_interface() {
1713   BTIF_TRACE_EVENT("%s", __func__);
1714   return &bthhInterface;
1715 }
1716