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