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