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