1 /******************************************************************************
2  *
3  *  Copyright 2005-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  *  This file contains the HID host action functions.
22  *
23  ******************************************************************************/
24 
25 #define LOG_TAG "bt_bta_hh"
26 
27 #include <bluetooth/log.h>
28 #include <com_android_bluetooth_flags.h>
29 
30 #include <cstdint>
31 #include <string>
32 
33 #include "bta/hh/bta_hh_int.h"
34 #include "bta/include/bta_hh_api.h"
35 #include "bta/include/bta_hh_co.h"
36 #include "bta/sys/bta_sys.h"
37 #include "btif/include/btif_storage.h"
38 #include "os/log.h"
39 #include "osi/include/allocator.h"
40 #include "stack/include/acl_api.h"
41 #include "stack/include/bt_hdr.h"
42 #include "stack/include/bt_uuid16.h"
43 #include "stack/include/btm_log_history.h"
44 #include "stack/include/hiddefs.h"
45 #include "stack/include/hidh_api.h"
46 #include "stack/include/sdp_api.h"
47 #include "types/bluetooth/uuid.h"
48 #include "types/raw_address.h"
49 
50 using namespace bluetooth::legacy::stack::sdp;
51 using namespace bluetooth;
52 
53 /*****************************************************************************
54  *  Constants
55  ****************************************************************************/
56 
57 namespace {
58 
59 constexpr char kBtmLogTag[] = "HIDH";
60 
61 }
62 
63 /*****************************************************************************
64  *  Local Function prototypes
65  ****************************************************************************/
66 static void bta_hh_cback(uint8_t dev_handle, const RawAddress& addr,
67                          uint8_t event, uint32_t data, BT_HDR* pdata);
68 static tBTA_HH_STATUS bta_hh_get_trans_status(uint32_t result);
69 
70 static const char* bta_hh_hid_event_name(uint16_t event);
71 
72 /*****************************************************************************
73  *  Action Functions
74  ****************************************************************************/
75 /*******************************************************************************
76  *
77  * Function         bta_hh_api_enable
78  *
79  * Description      Perform necessary operations to enable HID host.
80  *
81  *
82  * Returns          void
83  *
84  ******************************************************************************/
bta_hh_api_enable(tBTA_HH_CBACK * p_cback,bool enable_hid,bool enable_hogp)85 void bta_hh_api_enable(tBTA_HH_CBACK* p_cback, bool enable_hid, bool enable_hogp) {
86   tBTA_HH_STATUS status = BTA_HH_OK;
87   uint8_t xx;
88 
89   /* initialize BTE HID */
90   HID_HostInit();
91 
92   memset(&bta_hh_cb, 0, sizeof(tBTA_HH_CB));
93 
94   /* store parameters */
95   bta_hh_cb.p_cback = p_cback;
96   /* initialize device CB */
97   for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
98     bta_hh_cb.kdev[xx].state = BTA_HH_IDLE_ST;
99     bta_hh_cb.kdev[xx].hid_handle = BTA_HH_INVALID_HANDLE;
100     bta_hh_cb.kdev[xx].index = xx;
101   }
102 
103   /* initialize control block map */
104   for (xx = 0; xx < BTA_HH_MAX_KNOWN; xx++) {
105     bta_hh_cb.cb_index[xx] = BTA_HH_IDX_INVALID;
106   }
107 
108   if (enable_hid) {
109     /* Register with L2CAP */
110     if (HID_HostRegister(bta_hh_cback) != HID_SUCCESS) {
111       status = BTA_HH_ERR;
112     }
113   }
114 
115   if (status == BTA_HH_OK && enable_hogp) {
116     bta_hh_le_enable();
117   } else {
118     /* signal BTA call back event */
119     tBTA_HH bta_hh;
120     bta_hh.status = status;
121     if (status != BTA_HH_OK) {
122       log::error("Failed to register, status:{}", status);
123     }
124     if (bta_hh_cb.p_cback) {
125       (*bta_hh_cb.p_cback)(BTA_HH_ENABLE_EVT, &bta_hh);
126     }
127   }
128 }
129 /*******************************************************************************
130  *
131  * Function         bta_hh_api_disable
132  *
133  * Description      Perform necessary operations to disable HID host.
134  *
135  *
136  * Returns          void
137  *
138  ******************************************************************************/
bta_hh_api_disable(void)139 void bta_hh_api_disable(void) {
140   uint8_t xx;
141 
142   /* service is not enabled */
143   if (bta_hh_cb.p_cback == NULL) return;
144 
145   /* no live connection, signal DISC_CMPL_EVT directly */
146   if (!bta_hh_cb.cnt_num) {
147     bta_hh_disc_cmpl();
148   } else /* otherwise, disconnect all live connections */
149   {
150     bta_hh_cb.w4_disable = true;
151 
152     for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
153       /* send API_CLOSE event to every connected device */
154       if (bta_hh_cb.kdev[xx].state == BTA_HH_CONN_ST) {
155         /* disconnect all connected devices */
156         bta_hh_sm_execute(&bta_hh_cb.kdev[xx], BTA_HH_API_CLOSE_EVT, NULL);
157       }
158     }
159   }
160 
161   return;
162 }
163 
164 /*******************************************************************************
165  *
166  * Function         bta_hh_disc_cmpl
167  *
168  * Description      All connections have been closed, disable service.
169  *
170  *
171  * Returns          void
172  *
173  ******************************************************************************/
bta_hh_disc_cmpl(void)174 void bta_hh_disc_cmpl(void) {
175   log::debug("Disconnect complete");
176   tBTA_HH_STATUS status = BTA_HH_OK;
177 
178   /* Deregister with lower layer */
179   if (HID_HostDeregister() != HID_SUCCESS) status = BTA_HH_ERR;
180 
181   if (bta_hh_cb.gatt_if != BTA_GATTS_INVALID_IF) {
182     log::debug("Deregister HOGP host before cleanup");
183     bta_hh_le_deregister();
184   } else {
185     bta_hh_cleanup_disable(status);
186   }
187 }
188 
189 /*******************************************************************************
190  *
191  * Function         bta_hh_sdp_cback
192  *
193  * Description      SDP callback function.
194  *
195  * Returns          void
196  *
197  ******************************************************************************/
bta_hh_sdp_cback(uint16_t result,uint16_t attr_mask,tHID_DEV_SDP_INFO * sdp_rec)198 static void bta_hh_sdp_cback(uint16_t result, uint16_t attr_mask,
199                              tHID_DEV_SDP_INFO* sdp_rec) {
200   tBTA_HH_DEV_CB* p_cb = bta_hh_cb.p_cur;
201   uint8_t hdl = 0;
202   tBTA_HH_STATUS status = BTA_HH_ERR_SDP;
203 
204   /* make sure sdp succeeded and hh has not been disabled */
205   if ((result == SDP_SUCCESS) && (p_cb != NULL)) {
206     /* security is required for the connection, add attr_mask bit*/
207     attr_mask |= HID_SEC_REQUIRED;
208 
209     log::verbose("p_cb:{} result:0x{:02x}, attr_mask:0x{:02x}, handle:0x{:x}",
210                  fmt::ptr(p_cb), result, attr_mask, p_cb->hid_handle);
211 
212     /* check to see type of device is supported , and should not been added
213      * before */
214     if (bta_hh_tod_spt(p_cb, sdp_rec->sub_class)) {
215       /* if not added before */
216       if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) {
217         /*  add device/update attr_mask information */
218         if (HID_HostAddDev(p_cb->link_spec.addrt.bda, attr_mask, &hdl) ==
219             HID_SUCCESS) {
220           status = BTA_HH_OK;
221           /* update cb_index[] map */
222           bta_hh_cb.cb_index[hdl] = p_cb->index;
223         } else {
224           p_cb->app_id = 0;
225         }
226       } else {
227         hdl = p_cb->hid_handle;
228       }
229       /* else : incoming connection after SDP should update the SDP information
230        * as well */
231 
232       if (p_cb->app_id != 0) {
233         /* update cb information with attr_mask, dscp_info etc. */
234         bta_hh_add_device_to_list(p_cb, hdl, attr_mask, &sdp_rec->dscp_info,
235                                   sdp_rec->sub_class, sdp_rec->ssr_max_latency,
236                                   sdp_rec->ssr_min_tout, p_cb->app_id);
237 
238         p_cb->dscp_info.ctry_code = sdp_rec->ctry_code;
239 
240         status = BTA_HH_OK;
241       }
242 
243     } else /* type of device is not supported */
244       status = BTA_HH_ERR_TOD_UNSPT;
245   }
246 
247   /* free disc_db when SDP is completed */
248   osi_free_and_reset((void**)&bta_hh_cb.p_disc_db);
249 
250   /* send SDP_CMPL_EVT into state machine */
251   tBTA_HH_DATA bta_hh_data;
252   bta_hh_data.status = status;
253   bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data);
254 
255   return;
256 }
257 /*******************************************************************************
258  *
259  * Function         bta_hh_di_sdp_cback
260  *
261  * Description      SDP DI callback function.
262  *
263  * Returns          void
264  *
265  ******************************************************************************/
bta_hh_di_sdp_cback(const RawAddress &,tSDP_RESULT result)266 static void bta_hh_di_sdp_cback(const RawAddress& /* bd_addr */,
267                                 tSDP_RESULT result) {
268   tBTA_HH_DEV_CB* p_cb = bta_hh_cb.p_cur;
269   tBTA_HH_STATUS status = BTA_HH_ERR_SDP;
270   tSDP_DI_GET_RECORD di_rec;
271   tHID_STATUS ret;
272   log::verbose("p_cb:{} result:0x{:02x}", fmt::ptr(p_cb), result);
273 
274   /* if DI record does not exist on remote device, vendor_id in
275    * tBTA_HH_DEV_DSCP_INFO will be set to 0xffff and we will allow the
276    * connection to go through. Spec mandates that DI record be set, but many
277    * HID devices do not set this. So for IOP purposes, we allow the connection
278    * to go through and update the DI record to invalid DI entry.
279    */
280   if (((result == SDP_SUCCESS) || (result == SDP_NO_RECS_MATCH)) &&
281       (p_cb != NULL)) {
282     if (result == SDP_SUCCESS &&
283         get_legacy_stack_sdp_api()->device_id.SDP_GetNumDiRecords(
284             bta_hh_cb.p_disc_db) != 0) {
285       /* always update information with primary DI record */
286       if (get_legacy_stack_sdp_api()->device_id.SDP_GetDiRecord(
287               1, &di_rec, bta_hh_cb.p_disc_db) == SDP_SUCCESS) {
288         bta_hh_update_di_info(p_cb, di_rec.rec.vendor, di_rec.rec.product,
289                               di_rec.rec.version, 0, 0);
290       }
291 
292     } else /* no DI recrod available */
293     {
294       bta_hh_update_di_info(p_cb, BTA_HH_VENDOR_ID_INVALID, 0, 0, 0, 0);
295     }
296 
297     ret = HID_HostGetSDPRecord(p_cb->link_spec.addrt.bda, bta_hh_cb.p_disc_db,
298                                p_bta_hh_cfg->sdp_db_size, bta_hh_sdp_cback);
299     if (ret == HID_SUCCESS) {
300       status = BTA_HH_OK;
301     } else {
302       log::verbose("failure Status 0x{:2x}", ret);
303     }
304   }
305 
306   if (status != BTA_HH_OK) {
307     osi_free_and_reset((void**)&bta_hh_cb.p_disc_db);
308     /* send SDP_CMPL_EVT into state machine */
309     tBTA_HH_DATA bta_hh_data;
310     bta_hh_data.status = status;
311     bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data);
312   }
313   return;
314 }
315 
316 /*******************************************************************************
317  *
318  * Function         bta_hh_start_sdp
319  *
320  * Description      Start SDP service search, and obtain necessary SDP records.
321  *                  Only one SDP service search request is allowed at the same
322  *                  time. For every BTA_HhOpen API call, do SDP first unless SDP
323  *                  has been done previously.
324  *
325  * Returns          void
326  *
327  ******************************************************************************/
bta_hh_start_sdp(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)328 static void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
329   if (!bta_hh_cb.p_disc_db) {
330     bta_hh_cb.p_disc_db =
331         (tSDP_DISCOVERY_DB*)osi_malloc(p_bta_hh_cfg->sdp_db_size);
332 
333     /* Do DI discovery first */
334     if (get_legacy_stack_sdp_api()->device_id.SDP_DiDiscover(
335             p_data->api_conn.link_spec.addrt.bda, bta_hh_cb.p_disc_db,
336             p_bta_hh_cfg->sdp_db_size, bta_hh_di_sdp_cback) == SDP_SUCCESS) {
337       /* SDP search started successfully
338        * Connection will be triggered at the end of successful SDP search
339        */
340     } else {
341       log::error("SDP_DiDiscover failed");
342 
343       osi_free_and_reset((void**)&bta_hh_cb.p_disc_db);
344 
345       tBTA_HH_DATA bta_hh_data;
346       bta_hh_data.status = BTA_HH_ERR_SDP;
347       bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data);
348     }
349   } else if (bta_hh_cb.p_disc_db) {
350     /* Incoming/outgoing collision case. DUT initiated HID connection at the
351      * same time as the remote connected HID control channel.
352      * When flow reaches here due to remote initiated connection, DUT may be
353      * doing SDP. In such case, just do nothing and the ongoing SDP completion
354      * or failure will handle this case.
355      */
356     log::warn("Ignoring as SDP already in progress");
357   }
358 }
359 
360 /*******************************************************************************
361  *
362  * Function         bta_hh_sdp_cmpl
363  *
364  * Description      When SDP completes, initiate a connection or report an error
365  *                  depending on the SDP result.
366  *
367  *
368  * Returns          void
369  *
370  ******************************************************************************/
bta_hh_sdp_cmpl(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)371 void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
372   log::assert_that(p_data != nullptr, "assert failed: p_data != nullptr");
373 
374   tBTA_HH_CONN conn_dat;
375   tBTA_HH_STATUS status = p_data->status;
376 
377   log::verbose("status 0x{:2X}", p_data->status);
378 
379   /* initialize call back data */
380   memset((void*)&conn_dat, 0, sizeof(tBTA_HH_CONN));
381   conn_dat.handle = p_cb->hid_handle;
382   conn_dat.link_spec = p_cb->link_spec;
383 
384   /* if SDP compl success */
385   if (status == BTA_HH_OK) {
386     /* not incoming connection doing SDP, initiate a HID connection */
387     if (!p_cb->incoming_conn) {
388       tHID_STATUS ret;
389 
390       /* open HID connection */
391       ret = HID_HostOpenDev(p_cb->hid_handle);
392       log::verbose("HID_HostOpenDev returned={}", ret);
393       if (ret == HID_SUCCESS || ret == HID_ERR_ALREADY_CONN) {
394         status = BTA_HH_OK;
395       } else if (ret == HID_ERR_CONN_IN_PROCESS) {
396         /* Connection already in progress, return from here, SDP
397          * will be performed after connection is completed.
398          */
399         log::verbose("connection already in progress");
400         return;
401       } else {
402         log::verbose("HID_HostOpenDev failed: Status 0x{:2X}", ret);
403         /* open fail, remove device from management device list */
404         HID_HostRemoveDev(p_cb->hid_handle);
405         status = BTA_HH_ERR;
406       }
407     } else /* incoming connection SDP finish */
408     {
409       bta_hh_sm_execute(p_cb, BTA_HH_OPEN_CMPL_EVT, NULL);
410     }
411   }
412 
413   if (status != BTA_HH_OK) {
414     /* Check if this was incoming connection request  from an unknown device
415      * and connection failed due to missing HID Device SDP UUID
416      * In above condition, disconnect the link as well as remove the
417      * device from list of HID devices
418      */
419     if ((status == BTA_HH_ERR_SDP) && (p_cb->incoming_conn) &&
420         (p_cb->app_id == 0)) {
421       log::error("SDP failed for  incoming conn hndl:{}",
422                  p_cb->incoming_hid_handle);
423       HID_HostRemoveDev(p_cb->incoming_hid_handle);
424     }
425     conn_dat.status = status;
426     (*bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH*)&conn_dat);
427 
428     /* move state machine W4_CONN ->IDLE */
429     bta_hh_sm_execute(p_cb, BTA_HH_API_CLOSE_EVT, NULL);
430 
431     /* if this is an outgoing connection to an unknown device, clean up cb */
432     if (p_cb->app_id == 0 && !p_cb->incoming_conn) {
433       /* clean up device control block */
434       bta_hh_clean_up_kdev(p_cb);
435     }
436     bta_hh_trace_dev_db();
437   }
438   p_cb->incoming_conn = false;
439   p_cb->incoming_hid_handle = BTA_HH_INVALID_HANDLE;
440   return;
441 }
442 
443 /*******************************************************************************
444  *
445  * Function         bta_hh_bredr_conn
446  *
447  * Description      Initiate BR/EDR HID connection. This may be triggered by
448  *                  the local application or as a result of remote initiated
449  *                  HID connection.
450  *
451  * Returns          void
452  *
453  ******************************************************************************/
bta_hh_bredr_conn(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)454 static void bta_hh_bredr_conn(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
455   bta_hh_cb.p_cur = p_cb;
456 
457   /* If previously virtually cabled device */
458   if (p_cb->app_id) {
459     tBTA_HH_DATA bta_hh_data;
460     bta_hh_data.status = BTA_HH_OK;
461 
462     log::verbose("skip SDP for known devices");
463 
464     if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) {
465       uint8_t hdl;
466       if (HID_HostAddDev(p_cb->link_spec.addrt.bda, p_cb->attr_mask, &hdl) ==
467           HID_SUCCESS) {
468         /* update device CB with newly register device handle */
469         bta_hh_add_device_to_list(p_cb, hdl, p_cb->attr_mask, NULL,
470                                   p_cb->sub_class,
471                                   p_cb->dscp_info.ssr_max_latency,
472                                   p_cb->dscp_info.ssr_min_tout, p_cb->app_id);
473         /* update cb_index[] map */
474         bta_hh_cb.cb_index[hdl] = p_cb->index;
475       } else {
476         bta_hh_data.status = BTA_HH_ERR_NO_RES;
477       }
478     }
479 
480     bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data);
481   }
482   else { /* First time connection, start SDP */
483     bta_hh_start_sdp(p_cb, p_data);
484   }
485 }
486 
487 /*******************************************************************************
488  *
489  * Function         bta_hh_connect
490  *
491  * Description      Start HID host connection.
492  *
493  * Returns          void
494  *
495  ******************************************************************************/
bta_hh_connect(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)496 void bta_hh_connect(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
497   p_cb->link_spec = p_data->api_conn.link_spec;
498   p_cb->mode = p_data->api_conn.mode;
499   bta_hh_cb.p_cur = p_cb;
500 
501   // Initiate HID host connection
502   if (p_cb->link_spec.transport == BT_TRANSPORT_LE) {
503     bta_hh_le_open_conn(p_cb, p_data->api_conn.link_spec);
504   } else {
505     bta_hh_bredr_conn(p_cb, p_data);
506   }
507 }
508 
509 /*******************************************************************************
510  *
511  * Function         bta_hh_api_disc_act
512  *
513  * Description      HID Host initiate a disconnection.
514  *
515  *
516  * Returns          void
517  *
518  ******************************************************************************/
bta_hh_api_disc_act(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)519 void bta_hh_api_disc_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
520   log::assert_that(p_cb != nullptr, "assert failed: p_cb != nullptr");
521 
522   if (p_cb->link_spec.transport == BT_TRANSPORT_LE) {
523     log::debug("Host initiating close to le device:{}", p_cb->link_spec);
524 
525     bta_hh_le_api_disc_act(p_cb);
526 
527   } else {
528     const uint8_t hid_handle =
529         (p_data != nullptr) ? static_cast<uint8_t>(p_data->hdr.layer_specific)
530                             : p_cb->hid_handle;
531     tHID_STATUS status = HID_HostCloseDev(hid_handle);
532     if (status != HID_SUCCESS) {
533       log::warn("Failed closing classic device:{} status:{}", p_cb->link_spec,
534                 hid_status_text(status));
535     } else {
536       log::debug("Host initiated close to classic device:{}", p_cb->link_spec);
537     }
538     tBTA_HH bta_hh = {
539         .dev_status = {.status =
540                            (status == HID_SUCCESS) ? BTA_HH_OK : BTA_HH_ERR,
541                        .handle = hid_handle},
542     };
543     (*bta_hh_cb.p_cback)(BTA_HH_CLOSE_EVT, &bta_hh);
544   }
545 }
546 
547 /*******************************************************************************
548  *
549  * Function         bta_hh_open_cmpl_act
550  *
551  * Description      HID host connection completed
552  *
553  *
554  * Returns          void
555  *
556  ******************************************************************************/
bta_hh_open_cmpl_act(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)557 void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
558   tBTA_HH_CONN conn;
559   uint8_t dev_handle =
560       p_data ? (uint8_t)p_data->hid_cback.hdr.layer_specific : p_cb->hid_handle;
561 
562   memset((void*)&conn, 0, sizeof(tBTA_HH_CONN));
563   conn.handle = dev_handle;
564   conn.link_spec = p_cb->link_spec;
565 
566   /* increase connection number */
567   bta_hh_cb.cnt_num++;
568 
569   conn.status = p_cb->status;
570   conn.scps_supported = p_cb->scps_supported;
571   conn.sub_class = p_cb->sub_class;
572   conn.attr_mask = p_cb->attr_mask;
573   conn.app_id = p_cb->app_id;
574 
575   BTM_LogHistory(
576       kBtmLogTag, p_cb->link_spec.addrt.bda, "Opened",
577       base::StringPrintf("%s initiator:%s",
578                          bt_transport_text(p_cb->link_spec.transport).c_str(),
579                          (p_cb->incoming_conn) ? "remote" : "local"));
580 
581   if (p_cb->link_spec.transport != BT_TRANSPORT_LE) {
582     /* inform role manager */
583     bta_sys_conn_open(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda);
584 
585     /* set protocol mode when not default report mode */
586     if (p_cb->mode != BTA_HH_PROTO_RPT_MODE) {
587       tHID_STATUS status =
588           HID_HostWriteDev(dev_handle, HID_TRANS_SET_PROTOCOL,
589                            HID_PAR_PROTOCOL_BOOT_MODE, 0, 0, NULL);
590 
591       if (status == HID_SUCCESS) {
592         p_cb->w4_evt = BTA_HH_SET_PROTO_EVT;
593       } else {
594         /* HID connection is up, while SET_PROTO fail */
595         conn.status = BTA_HH_ERR_PROTO;
596       }
597     }
598   }
599   p_cb->incoming_conn = false;
600   p_cb->incoming_hid_handle = BTA_HH_INVALID_HANDLE;
601 
602   (*bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH*)&conn);
603 }
604 /*******************************************************************************
605  *
606  * Function         bta_hh_open_act
607  *
608  * Description      HID host receive HID_OPEN_EVT .
609  *
610  *
611  * Returns          void
612  *
613  ******************************************************************************/
bta_hh_open_act(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)614 void bta_hh_open_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
615   tBTA_HH_API_CONN conn_data;
616 
617   uint8_t dev_handle =
618       p_data ? (uint8_t)p_data->hid_cback.hdr.layer_specific : p_cb->hid_handle;
619 
620   log::verbose("Device[{}] connected", dev_handle);
621 
622   /* SDP has been done */
623   if (p_cb->app_id != 0) {
624     bta_hh_sm_execute(p_cb, BTA_HH_OPEN_CMPL_EVT, p_data);
625   } else
626   /*  app_id == 0 indicates an incoming conenction request arrives without SDP
627    *  performed, do it first
628    */
629   {
630     p_cb->incoming_conn = true;
631     /* store the handle here in case sdp fails - need to disconnect */
632     p_cb->incoming_hid_handle = dev_handle;
633 
634     memset(&conn_data, 0, sizeof(tBTA_HH_API_CONN));
635     conn_data.link_spec = p_cb->link_spec;
636     bta_hh_cb.p_cur = p_cb;
637     bta_hh_bredr_conn(p_cb, (tBTA_HH_DATA*)&conn_data);
638   }
639 
640   return;
641 }
642 
643 /*******************************************************************************
644  *
645  * Function         bta_hh_data_act
646  *
647  * Description      HID Host process a data report
648  *
649  *
650  * Returns          void
651  *
652  ******************************************************************************/
bta_hh_data_act(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)653 void bta_hh_data_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
654   BT_HDR* pdata = p_data->hid_cback.p_data;
655   uint8_t* p_rpt = (uint8_t*)(pdata + 1) + pdata->offset;
656 
657   bta_hh_co_data((uint8_t)p_data->hid_cback.hdr.layer_specific, p_rpt,
658                  pdata->len);
659 
660   osi_free_and_reset((void**)&pdata);
661 }
662 
663 /*******************************************************************************
664  *
665  * Function         bta_hh_handsk_act
666  *
667  * Description      HID Host process a handshake acknowledgement.
668  *
669  *
670  * Returns          void
671  *
672  ******************************************************************************/
bta_hh_handsk_act(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)673 void bta_hh_handsk_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
674   log::verbose("HANDSHAKE received for: event={} data={}",
675                bta_hh_event_text(p_cb->w4_evt), p_data->hid_cback.data);
676 
677   tBTA_HH bta_hh;
678   memset(&bta_hh, 0, sizeof(tBTA_HH));
679 
680   switch (p_cb->w4_evt) {
681     /* GET_ transsaction, handshake indicate unsupported request */
682     case BTA_HH_GET_PROTO_EVT:
683       bta_hh.hs_data.rsp_data.proto_mode = BTA_HH_PROTO_UNKNOWN;
684       FALLTHROUGH_INTENDED; /* FALLTHROUGH */
685     case BTA_HH_GET_RPT_EVT:
686     case BTA_HH_GET_IDLE_EVT:
687       bta_hh.hs_data.handle = p_cb->hid_handle;
688       /* if handshake gives an OK code for these transaction, fill in UNSUPT */
689       bta_hh.hs_data.status = bta_hh_get_trans_status(p_data->hid_cback.data);
690       if (bta_hh.hs_data.status == BTA_HH_OK)
691         bta_hh.hs_data.status = BTA_HH_HS_TRANS_NOT_SPT;
692       (*bta_hh_cb.p_cback)(p_cb->w4_evt, &bta_hh);
693       p_cb->w4_evt = BTA_HH_EMPTY_EVT;
694       break;
695 
696     /* acknoledgement from HID device for SET_ transaction */
697     case BTA_HH_SET_RPT_EVT:
698     case BTA_HH_SET_PROTO_EVT:
699     case BTA_HH_SET_IDLE_EVT:
700       bta_hh.dev_status.handle = p_cb->hid_handle;
701       bta_hh.dev_status.status =
702           bta_hh_get_trans_status(p_data->hid_cback.data);
703       (*bta_hh_cb.p_cback)(p_cb->w4_evt, &bta_hh);
704       p_cb->w4_evt = BTA_HH_EMPTY_EVT;
705       break;
706 
707     /* SET_PROTOCOL when open connection */
708     case BTA_HH_OPEN_EVT:
709       bta_hh.conn.status =
710           p_data->hid_cback.data ? BTA_HH_ERR_PROTO : BTA_HH_OK;
711       bta_hh.conn.handle = p_cb->hid_handle;
712       bta_hh.conn.link_spec = p_cb->link_spec;
713       (*bta_hh_cb.p_cback)(p_cb->w4_evt, &bta_hh);
714       bta_hh_trace_dev_db();
715       p_cb->w4_evt = BTA_HH_EMPTY_EVT;
716       break;
717 
718     default:
719       /* unknow transaction handshake response */
720       log::verbose("unknown transaction type {}",
721                    bta_hh_event_text(p_cb->w4_evt));
722       break;
723   }
724 
725   /* transaction achknoledgement received, inform PM for mode change */
726   bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda);
727   return;
728 }
729 /*******************************************************************************
730  *
731  * Function         bta_hh_ctrl_dat_act
732  *
733  * Description      HID Host process a data report from control channel.
734  *
735  *
736  * Returns          void
737  *
738  ******************************************************************************/
bta_hh_ctrl_dat_act(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)739 void bta_hh_ctrl_dat_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
740   BT_HDR* pdata = p_data->hid_cback.p_data;
741   uint8_t* data = (uint8_t*)(pdata + 1) + pdata->offset;
742   tBTA_HH_HSDATA hs_data;
743 
744   log::verbose("Ctrl DATA received w4: event[{}]",
745                bta_hh_event_text(p_cb->w4_evt));
746   if (pdata->len == 0) {
747     p_cb->w4_evt = BTA_HH_EMPTY_EVT;
748     osi_free_and_reset((void**)&pdata);
749     return;
750   }
751   hs_data.status = BTA_HH_OK;
752   hs_data.handle = p_cb->hid_handle;
753 
754   switch (p_cb->w4_evt) {
755     case BTA_HH_GET_IDLE_EVT:
756       hs_data.rsp_data.idle_rate = *data;
757       break;
758     case BTA_HH_GET_RPT_EVT:
759       hs_data.rsp_data.p_rpt_data = pdata;
760       break;
761     case BTA_HH_GET_PROTO_EVT:
762       /* match up BTE/BTA report/boot mode def*/
763       hs_data.rsp_data.proto_mode = ((*data) == HID_PAR_PROTOCOL_REPORT)
764                                         ? BTA_HH_PROTO_RPT_MODE
765                                         : BTA_HH_PROTO_BOOT_MODE;
766       log::verbose("GET_PROTOCOL Mode = [{}]",
767                    (hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE)
768                        ? "Report"
769                        : "Boot");
770       break;
771     /* should not expect control DATA for SET_ transaction */
772     case BTA_HH_SET_PROTO_EVT:
773       FALLTHROUGH_INTENDED; /* FALLTHROUGH */
774     case BTA_HH_SET_RPT_EVT:
775       FALLTHROUGH_INTENDED; /* FALLTHROUGH */
776     case BTA_HH_SET_IDLE_EVT:
777       FALLTHROUGH_INTENDED; /* FALLTHROUGH */
778     default:
779       log::verbose("invalid  transaction type for DATA payload:4_evt[{}]",
780                    bta_hh_event_text(p_cb->w4_evt));
781       break;
782   }
783 
784   /* inform PM for mode change */
785   bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda);
786   bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda);
787 
788   (*bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH*)&hs_data);
789 
790   p_cb->w4_evt = BTA_HH_EMPTY_EVT;
791   osi_free_and_reset((void**)&pdata);
792 }
793 
794 /*******************************************************************************
795  *
796  * Function         bta_hh_open_failure
797  *
798  * Description      report HID open failure when at wait for connection state
799  *                  and receive device close event.
800  *
801  *
802  * Returns          void
803  *
804  ******************************************************************************/
bta_hh_open_failure(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)805 void bta_hh_open_failure(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
806   tBTA_HH_CONN conn_dat;
807   uint32_t reason = p_data->hid_cback.data; /* Reason for closing (32-bit) */
808 
809   memset(&conn_dat, 0, sizeof(tBTA_HH_CONN));
810   conn_dat.handle = p_cb->hid_handle;
811   conn_dat.status =
812       (reason == HID_ERR_AUTH_FAILED) ? BTA_HH_ERR_AUTH_FAILED : BTA_HH_ERR;
813   conn_dat.link_spec = p_cb->link_spec;
814   HID_HostCloseDev(p_cb->hid_handle);
815 
816   /* Report OPEN fail event */
817   (*bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH*)&conn_dat);
818 
819   bta_hh_trace_dev_db();
820   /* clean up control block, but retain SDP info and device handle */
821   p_cb->vp = false;
822   p_cb->w4_evt = 0;
823 
824   /* if no connection is active and HH disable is signaled, disable service */
825   if (bta_hh_cb.cnt_num == 0 && bta_hh_cb.w4_disable) {
826     bta_hh_disc_cmpl();
827   }
828 
829   /* Error in opening hid connection, reset flags */
830   p_cb->incoming_conn = false;
831   p_cb->incoming_hid_handle = BTA_HH_INVALID_HANDLE;
832 }
833 
834 /*******************************************************************************
835  *
836  * Function         bta_hh_close_act
837  *
838  * Description      HID Host process a close event
839  *
840  *
841  * Returns          void
842  *
843  ******************************************************************************/
bta_hh_close_act(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)844 void bta_hh_close_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
845   tBTA_HH_CBDATA disc_dat = {BTA_HH_OK, 0};
846 
847   uint32_t reason = p_data->hid_cback.data; /* Reason for closing (32-bit) */
848   const bool l2cap_conn_fail = reason & HID_L2CAP_CONN_FAIL;
849   const bool l2cap_req_fail = reason & HID_L2CAP_REQ_FAIL;
850   const bool l2cap_cfg_fail = reason & HID_L2CAP_CFG_FAIL;
851   const tHID_STATUS hid_status = static_cast<tHID_STATUS>(reason & 0xff);
852 
853   /* if HID_HDEV_EVT_VC_UNPLUG was received, report BTA_HH_VC_UNPLUG_EVT */
854   uint16_t event = p_cb->vp ? BTA_HH_VC_UNPLUG_EVT : BTA_HH_CLOSE_EVT;
855 
856   disc_dat.handle = p_cb->hid_handle;
857   disc_dat.status = to_bta_hh_status(p_data->hid_cback.data);
858 
859   std::string overlay_fail =
860       base::StringPrintf("%s %s %s", (l2cap_conn_fail) ? "l2cap_conn_fail" : "",
861                          (l2cap_req_fail) ? "l2cap_req_fail" : "",
862                          (l2cap_cfg_fail) ? "l2cap_cfg_fail" : "");
863   BTM_LogHistory(
864       kBtmLogTag, p_cb->link_spec.addrt.bda, "Closed",
865       base::StringPrintf(
866           "%s reason %s %s",
867           (p_cb->link_spec.transport == BT_TRANSPORT_LE) ? "le" : "classic",
868           hid_status_text(hid_status).c_str(), overlay_fail.c_str()));
869 
870   /* inform role manager */
871   bta_sys_conn_close(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda);
872   /* update total conn number */
873   bta_hh_cb.cnt_num--;
874 
875   if (disc_dat.status) disc_dat.status = BTA_HH_ERR;
876 
877   (*bta_hh_cb.p_cback)(event, (tBTA_HH*)&disc_dat);
878 
879   /* if virtually unplug, remove device */
880   if (p_cb->vp) {
881     HID_HostRemoveDev(p_cb->hid_handle);
882     bta_hh_clean_up_kdev(p_cb);
883   }
884 
885   bta_hh_trace_dev_db();
886 
887   /* clean up control block, but retain SDP info and device handle */
888   p_cb->vp = false;
889   p_cb->w4_evt = BTA_HH_EMPTY_EVT;
890 
891   /* if no connection is active and HH disable is signaled, disable service */
892   if (bta_hh_cb.cnt_num == 0 && bta_hh_cb.w4_disable) {
893     bta_hh_disc_cmpl();
894   }
895 
896   return;
897 }
898 
899 /*******************************************************************************
900  *
901  * Function         bta_hh_get_dscp_act
902  *
903  * Description      Get device report descriptor
904  *
905  *
906  * Returns          void
907  *
908  ******************************************************************************/
bta_hh_get_dscp_act(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA *)909 void bta_hh_get_dscp_act(tBTA_HH_DEV_CB* p_cb,
910                          const tBTA_HH_DATA* /* p_data */) {
911   if (p_cb->link_spec.transport == BT_TRANSPORT_LE) {
912     if (p_cb->hid_srvc.state >= BTA_HH_SERVICE_DISCOVERED) {
913       p_cb->dscp_info.hid_handle = p_cb->hid_handle;
914     }
915     bta_hh_le_get_dscp_act(p_cb);
916   } else {
917     p_cb->dscp_info.hid_handle = p_cb->hid_handle;
918     (*bta_hh_cb.p_cback)(BTA_HH_GET_DSCP_EVT, (tBTA_HH*)&p_cb->dscp_info);
919   }
920 }
921 
922 /*******************************************************************************
923  *
924  * Function         bta_hh_maint_dev_act
925  *
926  * Description      HID Host maintain device list.
927  *
928  *
929  * Returns          void
930  *
931  ******************************************************************************/
bta_hh_maint_dev_act(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)932 void bta_hh_maint_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
933   const tBTA_HH_MAINT_DEV* p_dev_info = &p_data->api_maintdev;
934   tBTA_HH_DEV_INFO dev_info;
935   uint8_t dev_handle;
936 
937   dev_info.status = BTA_HH_ERR;
938   dev_info.handle = BTA_HH_INVALID_HANDLE;
939 
940   switch (p_dev_info->sub_event) {
941     case BTA_HH_ADD_DEV_EVT: /* add a device */
942       dev_info.link_spec = p_dev_info->link_spec;
943       /* initialize callback data */
944       if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) {
945         tBT_TRANSPORT transport = p_data->api_maintdev.link_spec.transport;
946         if (!com::android::bluetooth::flags::allow_switching_hid_and_hogp()) {
947           transport = BTM_UseLeLink(p_data->api_maintdev.link_spec.addrt.bda)
948                           ? BT_TRANSPORT_LE
949                           : BT_TRANSPORT_BR_EDR;
950         }
951         if (transport == BT_TRANSPORT_LE) {
952           p_cb->link_spec.transport = BT_TRANSPORT_LE;
953           dev_info.handle = bta_hh_le_add_device(p_cb, p_dev_info);
954           if (dev_info.handle != BTA_HH_INVALID_HANDLE)
955             dev_info.status = BTA_HH_OK;
956         } else if (transport == BT_TRANSPORT_BR_EDR) {
957           if (HID_HostAddDev(p_dev_info->link_spec.addrt.bda,
958                              p_dev_info->attr_mask,
959                              &dev_handle) == HID_SUCCESS) {
960             dev_info.handle = dev_handle;
961             dev_info.status = BTA_HH_OK;
962             p_cb->link_spec.transport = BT_TRANSPORT_BR_EDR;
963 
964             /* update DI information */
965             bta_hh_update_di_info(
966                 p_cb, p_dev_info->dscp_info.vendor_id,
967                 p_dev_info->dscp_info.product_id, p_dev_info->dscp_info.version,
968                 p_dev_info->dscp_info.flag, p_dev_info->dscp_info.ctry_code);
969 
970             /* add to BTA device list */
971             bta_hh_add_device_to_list(
972                 p_cb, dev_handle, p_dev_info->attr_mask,
973                 &p_dev_info->dscp_info.descriptor, p_dev_info->sub_class,
974                 p_dev_info->dscp_info.ssr_max_latency,
975                 p_dev_info->dscp_info.ssr_min_tout, p_dev_info->app_id);
976             /* update cb_index[] map */
977             bta_hh_cb.cb_index[dev_handle] = p_cb->index;
978           }
979         } else {
980           log::error("unexpected BT transport: {}",
981                      bt_transport_text(transport));
982           break;
983         }
984       } else /* device already been added */
985       {
986         dev_info.handle = p_cb->hid_handle;
987         dev_info.status = BTA_HH_OK;
988       }
989       bta_hh_trace_dev_db();
990 
991       break;
992     case BTA_HH_RMV_DEV_EVT: /* remove device */
993       dev_info.handle = (uint8_t)p_dev_info->hdr.layer_specific;
994       dev_info.link_spec = p_cb->link_spec;
995 
996       if (p_cb->link_spec.transport == BT_TRANSPORT_LE) {
997         bta_hh_le_remove_dev_bg_conn(p_cb);
998         bta_hh_sm_execute(p_cb, BTA_HH_API_CLOSE_EVT, NULL);
999         bta_hh_clean_up_kdev(p_cb);
1000       } else {
1001         if (HID_HostRemoveDev(dev_info.handle) == HID_SUCCESS) {
1002           dev_info.status = BTA_HH_OK;
1003 
1004           /* remove from known device list in BTA */
1005           bta_hh_clean_up_kdev(p_cb);
1006         }
1007       }
1008       break;
1009 
1010     default:
1011       log::verbose("invalid command");
1012       break;
1013   }
1014 
1015   (*bta_hh_cb.p_cback)(p_dev_info->sub_event, (tBTA_HH*)&dev_info);
1016 }
1017 /*******************************************************************************
1018  *
1019  * Function         bta_hh_write_dev_act
1020  *
1021  * Description      Write device action. can be SET/GET/DATA transaction.
1022  *
1023  * Returns          void
1024  *
1025  ******************************************************************************/
convert_api_sndcmd_param(const tBTA_HH_CMD_DATA & api_sndcmd)1026 static uint8_t convert_api_sndcmd_param(const tBTA_HH_CMD_DATA& api_sndcmd) {
1027   uint8_t api_sndcmd_param = api_sndcmd.param;
1028   if (api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL) {
1029     api_sndcmd_param = (api_sndcmd.param == BTA_HH_PROTO_RPT_MODE)
1030                            ? HID_PAR_PROTOCOL_REPORT
1031                            : HID_PAR_PROTOCOL_BOOT_MODE;
1032   }
1033   return api_sndcmd_param;
1034 }
1035 
bta_hh_write_dev_act(tBTA_HH_DEV_CB * p_cb,const tBTA_HH_DATA * p_data)1036 void bta_hh_write_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
1037   uint16_t event =
1038       (p_data->api_sndcmd.t_type - HID_TRANS_GET_REPORT) + BTA_HH_GET_RPT_EVT;
1039 
1040   if (p_cb->link_spec.transport == BT_TRANSPORT_LE)
1041     bta_hh_le_write_dev_act(p_cb, p_data);
1042   else {
1043     /* match up BTE/BTA report/boot mode def */
1044     const uint8_t api_sndcmd_param =
1045         convert_api_sndcmd_param(p_data->api_sndcmd);
1046 
1047     tHID_STATUS status = HID_HostWriteDev(p_cb->hid_handle,
1048                                           p_data->api_sndcmd.t_type,
1049                                           api_sndcmd_param,
1050                                           p_data->api_sndcmd.data,
1051                                           p_data->api_sndcmd.rpt_id,
1052                                           p_data->api_sndcmd.p_data);
1053     if (status != HID_SUCCESS) {
1054       log::error("HID_HostWriteDev Error, status:{}", status);
1055 
1056       if (p_data->api_sndcmd.t_type != HID_TRANS_CONTROL &&
1057           p_data->api_sndcmd.t_type != HID_TRANS_DATA) {
1058         BT_HDR cbhdr = {
1059           .event = BTA_HH_GET_RPT_EVT,
1060           .len = 0,
1061           .offset = 0,
1062           .layer_specific = 0,
1063         };
1064         tBTA_HH cbdata = {
1065           .hs_data = {
1066             .status = BTA_HH_ERR,
1067             .handle = p_cb->hid_handle,
1068             .rsp_data = {
1069               .p_rpt_data = &cbhdr,
1070             },
1071           },
1072         };
1073         (*bta_hh_cb.p_cback)(event, &cbdata);
1074       } else if (api_sndcmd_param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG) {
1075         tBTA_HH cbdata = {
1076           .dev_status = {
1077             .status = BTA_HH_ERR,
1078             .handle = p_cb->hid_handle,
1079           },
1080         };
1081         (*bta_hh_cb.p_cback)(BTA_HH_VC_UNPLUG_EVT, &cbdata);
1082       } else {
1083         log::error(
1084             "skipped executing callback in hid host error handling. command "
1085             "type:{}, param:{}",
1086             p_data->api_sndcmd.t_type, p_data->api_sndcmd.param);
1087       }
1088     } else {
1089       switch (p_data->api_sndcmd.t_type) {
1090         case HID_TRANS_SET_PROTOCOL:
1091           FALLTHROUGH_INTENDED; /* FALLTHROUGH */
1092         case HID_TRANS_GET_REPORT:
1093           FALLTHROUGH_INTENDED; /* FALLTHROUGH */
1094         case HID_TRANS_SET_REPORT:
1095           FALLTHROUGH_INTENDED; /* FALLTHROUGH */
1096         case HID_TRANS_GET_PROTOCOL:
1097           FALLTHROUGH_INTENDED; /* FALLTHROUGH */
1098         case HID_TRANS_GET_IDLE:
1099           FALLTHROUGH_INTENDED;  /* FALLTHROUGH */
1100         case HID_TRANS_SET_IDLE: /* set w4_handsk event name for callback
1101                                     function use */
1102           p_cb->w4_evt = event;
1103           break;
1104         case HID_TRANS_DATA: /* output report */
1105           FALLTHROUGH_INTENDED; /* FALLTHROUGH */
1106         case HID_TRANS_CONTROL:
1107           /* no handshake event will be generated */
1108           /* if VC_UNPLUG is issued, set flag */
1109           if (api_sndcmd_param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG)
1110             p_cb->vp = true;
1111 
1112           break;
1113         /* currently not expected */
1114         case HID_TRANS_DATAC:
1115         default:
1116           log::verbose("cmd type={}", p_data->api_sndcmd.t_type);
1117           break;
1118       }
1119 
1120       /* if not control type transaction, notify PM for energy control */
1121       if (p_data->api_sndcmd.t_type != HID_TRANS_CONTROL) {
1122         /* inform PM for mode change */
1123         bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda);
1124         bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda);
1125       } else if (api_sndcmd_param == BTA_HH_CTRL_SUSPEND) {
1126         bta_sys_sco_close(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda);
1127       } else if (api_sndcmd_param == BTA_HH_CTRL_EXIT_SUSPEND) {
1128         bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda);
1129       }
1130     }
1131   }
1132   return;
1133 }
1134 
1135 /*****************************************************************************
1136  *  Static Function
1137  ****************************************************************************/
1138 /*******************************************************************************
1139  *
1140  * Function         bta_hh_cback
1141  *
1142  * Description      BTA HH callback function.
1143  *
1144  *
1145  * Returns          void
1146  *
1147  ******************************************************************************/
bta_hh_cback(uint8_t dev_handle,const RawAddress & addr,uint8_t event,uint32_t data,BT_HDR * pdata)1148 static void bta_hh_cback(uint8_t dev_handle, const RawAddress& addr,
1149                          uint8_t event, uint32_t data, BT_HDR* pdata) {
1150   uint16_t sm_event = BTA_HH_INVALID_EVT;
1151   uint8_t xx = 0;
1152 
1153   log::verbose("HID_event [{}]", bta_hh_hid_event_name(event));
1154 
1155   switch (event) {
1156     case HID_HDEV_EVT_OPEN:
1157       sm_event = BTA_HH_INT_OPEN_EVT;
1158       break;
1159     case HID_HDEV_EVT_CLOSE:
1160       sm_event = BTA_HH_INT_CLOSE_EVT;
1161       break;
1162     case HID_HDEV_EVT_INTR_DATA:
1163       sm_event = BTA_HH_INT_DATA_EVT;
1164       break;
1165     case HID_HDEV_EVT_HANDSHAKE:
1166       sm_event = BTA_HH_INT_HANDSK_EVT;
1167       break;
1168     case HID_HDEV_EVT_CTRL_DATA:
1169       sm_event = BTA_HH_INT_CTRL_DATA;
1170       break;
1171     case HID_HDEV_EVT_RETRYING:
1172       break;
1173     case HID_HDEV_EVT_INTR_DATC:
1174     case HID_HDEV_EVT_CTRL_DATC:
1175       /* Unhandled events: Free buffer for DATAC */
1176       osi_free_and_reset((void**)&pdata);
1177       break;
1178     case HID_HDEV_EVT_VC_UNPLUG:
1179       for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
1180         if (bta_hh_cb.kdev[xx].hid_handle == dev_handle) {
1181           bta_hh_cb.kdev[xx].vp = true;
1182           break;
1183         }
1184       }
1185       break;
1186   }
1187 
1188   if (sm_event != BTA_HH_INVALID_EVT) {
1189     tBTA_HH_CBACK_DATA* p_buf = (tBTA_HH_CBACK_DATA*)osi_malloc(
1190         sizeof(tBTA_HH_CBACK_DATA) + sizeof(BT_HDR));
1191     p_buf->hdr.event = sm_event;
1192     p_buf->hdr.layer_specific = (uint16_t)dev_handle;
1193     p_buf->data = data;
1194     p_buf->link_spec.addrt.bda = addr;
1195     p_buf->link_spec.addrt.type = BLE_ADDR_PUBLIC;
1196     p_buf->link_spec.transport = BT_TRANSPORT_BR_EDR;
1197     p_buf->p_data = pdata;
1198 
1199     bta_sys_sendmsg(p_buf);
1200   }
1201 }
1202 
1203 /*******************************************************************************
1204  *
1205  * Function         bta_hh_get_trans_status
1206  *
1207  * Description      translate a handshake result code into BTA HH
1208  *                  status code
1209  *
1210  ******************************************************************************/
bta_hh_get_trans_status(uint32_t result)1211 static tBTA_HH_STATUS bta_hh_get_trans_status(uint32_t result) {
1212   switch (result) {
1213     case HID_PAR_HANDSHAKE_RSP_SUCCESS: /*   (0) */
1214       return BTA_HH_OK;
1215     case HID_PAR_HANDSHAKE_RSP_NOT_READY:           /*   (1) */
1216     case HID_PAR_HANDSHAKE_RSP_ERR_INVALID_REP_ID:  /*   (2) */
1217     case HID_PAR_HANDSHAKE_RSP_ERR_UNSUPPORTED_REQ: /*   (3) */
1218     case HID_PAR_HANDSHAKE_RSP_ERR_INVALID_PARAM:   /*   (4) */
1219       return (tBTA_HH_STATUS)result;
1220     case HID_PAR_HANDSHAKE_RSP_ERR_UNKNOWN: /*   (14) */
1221     case HID_PAR_HANDSHAKE_RSP_ERR_FATAL:   /*   (15) */
1222     default:
1223       return BTA_HH_HS_ERROR;
1224       break;
1225   }
1226 }
1227 /*****************************************************************************
1228  *  Debug Functions
1229  ****************************************************************************/
1230 
bta_hh_hid_event_name(uint16_t event)1231 static const char* bta_hh_hid_event_name(uint16_t event) {
1232   switch (event) {
1233     case HID_HDEV_EVT_OPEN:
1234       return "HID_HDEV_EVT_OPEN";
1235     case HID_HDEV_EVT_CLOSE:
1236       return "HID_HDEV_EVT_CLOSE";
1237     case HID_HDEV_EVT_RETRYING:
1238       return "HID_HDEV_EVT_RETRYING";
1239     case HID_HDEV_EVT_INTR_DATA:
1240       return "HID_HDEV_EVT_INTR_DATA";
1241     case HID_HDEV_EVT_INTR_DATC:
1242       return "HID_HDEV_EVT_INTR_DATC";
1243     case HID_HDEV_EVT_CTRL_DATA:
1244       return "HID_HDEV_EVT_CTRL_DATA";
1245     case HID_HDEV_EVT_CTRL_DATC:
1246       return "HID_HDEV_EVT_CTRL_DATC";
1247     case HID_HDEV_EVT_HANDSHAKE:
1248       return "HID_HDEV_EVT_HANDSHAKE";
1249     case HID_HDEV_EVT_VC_UNPLUG:
1250       return "HID_HDEV_EVT_VC_UNPLUG";
1251     default:
1252       return "Unknown HID event";
1253   }
1254 }
1255