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