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