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