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