1 /******************************************************************************
2  *
3  *  Copyright (C) 2016 The Android Open Source Project
4  *  Copyright (C) 2009-2012 Broadcom Corporation
5  *  Copyright (C) 2019 Blake Felt
6  *
7  *  Licensed under the Apache License, Version 2.0 (the "License");
8  *  you may not use this file except in compliance with the License.
9  *  You may obtain a copy of the License at:
10  *
11  *  http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *  Unless required by applicable law or agreed to in writing, software
14  *  distributed under the License is distributed on an "AS IS" BASIS,
15  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *  See the License for the specific language governing permissions and
17  *  limitations under the License.
18  *
19  ******************************************************************************/
20 /************************************************************************************
21  *
22  *  Filename:      btc_hd.c
23  *
24  *  Description:   HID Device Profile Bluetooth Interface
25  *
26  *
27  ***********************************************************************************/
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include "btc/btc_util.h"
33 #include "btc/btc_manage.h"
34 #include "device/bdaddr.h"
35 #include "btc/btc_storage.h"
36 #include "osi/allocator.h"
37 #include "bta/utl.h"
38 #include "bta/bta_hh_api.h"
39 #include "stack/l2c_api.h"
40 // #include "bta_dm_int.h"
41 
42 #if HID_HOST_INCLUDED == TRUE
43 #include "btc_hh.h"
44 
45 
46 /*******************************************************************************
47  *  Static variables
48  ******************************************************************************/
49 btc_hh_cb_t btc_hh_cb;
50 static bdstr_t bdstr;
51 
52 /******************************************************************************
53  *  Constants & Macros
54  *****************************************************************************/
55 #define COD_MASK 0x07FF
56 
57 #define COD_UNCLASSIFIED ((0x1F) << 8)
58 #define COD_HID_KEYBOARD 0x0540
59 #define COD_HID_POINTING 0x0580
60 #define COD_HID_COMBO 0x05C0
61 #define COD_HID_MAJOR 0x0500
62 #define COD_HID_MASK 0x0700
63 
64 #define is_hidh_init() (btc_hh_cb.status > BTC_HH_DISABLED)
65 #define BTC_TIMEOUT_VUP_MS (3 * 1000)
66 
btc_hh_cb_to_app(esp_hidh_cb_event_t event,esp_hidh_cb_param_t * param)67 static inline void btc_hh_cb_to_app(esp_hidh_cb_event_t event, esp_hidh_cb_param_t *param)
68 {
69     esp_hh_cb_t btc_hh_cb = (esp_hh_cb_t)btc_profile_cb_get(BTC_PID_HH);
70     if (btc_hh_cb) {
71         btc_hh_cb(event, param);
72     }
73 }
74 
75 /*******************************************************************************
76  *
77  * Function         proto_mode_change_to_lower_layer
78  *
79  * Description      Change the upper layer protocol mode definition to the lower layer protocol mode definition
80  *
81  * Returns          Lower layer protocol mode definition
82  ******************************************************************************/
proto_mode_change_to_lower_layer(esp_hidh_protocol_mode_t protocol_mode)83 static inline tBTA_HH_PROTO_MODE proto_mode_change_to_lower_layer(esp_hidh_protocol_mode_t protocol_mode)
84 {
85     tBTA_HH_PROTO_MODE proto_mode = BTA_HH_PROTO_UNKNOWN;
86 
87     switch (protocol_mode) {
88     case ESP_HIDH_REPORT_MODE:
89         proto_mode = BTA_HH_PROTO_RPT_MODE;
90         break;
91     case ESP_HIDH_BOOT_MODE:
92         proto_mode = BTA_HH_PROTO_BOOT_MODE;
93         break;
94     default:
95         break;
96     }
97 
98     return proto_mode;
99 }
100 
101 /*******************************************************************************
102  *
103  * Function         proto_mode_change_to_upper_layer
104  *
105  * Description      Change the lower layer protocol mode definition to the upper layer protocol mode definition
106  *
107  * Returns          Upper layer protocol mode definition
108  ******************************************************************************/
proto_mode_change_to_upper_layer(tBTA_HH_PROTO_MODE proto_mode)109 static inline esp_hidh_protocol_mode_t proto_mode_change_to_upper_layer(tBTA_HH_PROTO_MODE proto_mode)
110 {
111     esp_hidh_protocol_mode_t protocol_mode = ESP_HIDH_UNSUPPORTED_MODE;
112 
113     switch (proto_mode) {
114     case BTA_HH_PROTO_RPT_MODE:
115         protocol_mode = ESP_HIDH_REPORT_MODE;
116         break;
117     case BTA_HH_PROTO_BOOT_MODE:
118         protocol_mode = ESP_HIDH_BOOT_MODE;
119         break;
120     default:
121         break;
122     }
123 
124     return protocol_mode;
125 }
126 
127 /*******************************************************************************
128  *
129  * Function         btc_hh_find_connected_dev_by_handle
130  *
131  * Description      Return the connected device pointer of the specified device
132  *                  handle
133  *
134  * Returns          Device entry pointer in the device table
135  ******************************************************************************/
btc_hh_find_connected_dev_by_handle(uint8_t handle)136 btc_hh_device_t *btc_hh_find_connected_dev_by_handle(uint8_t handle)
137 {
138     uint32_t i;
139     for (i = 0; i < BTC_HH_MAX_HID; i++) {
140         if (btc_hh_cb.devices[i].dev_status == ESP_HIDH_CONN_STATE_CONNECTED && btc_hh_cb.devices[i].dev_handle == handle) {
141             return &btc_hh_cb.devices[i];
142         }
143     }
144     return NULL;
145 }
146 
147 /*******************************************************************************
148  *
149  * Function         btc_hh_find_dev_by_bda
150  *
151  * Description      Return the device pointer of the specified bd_addr.
152  *
153  * Returns          Device entry pointer in the device table
154  ******************************************************************************/
btc_hh_find_dev_by_bda(BD_ADDR bd_addr)155 static btc_hh_device_t *btc_hh_find_dev_by_bda(BD_ADDR bd_addr)
156 {
157     uint8_t i;
158     for (i = 0; i < BTC_HH_MAX_HID; i++) {
159         if (btc_hh_cb.devices[i].dev_status != ESP_HIDH_CONN_STATE_UNKNOWN &&
160             memcmp(btc_hh_cb.devices[i].bd_addr, bd_addr, BD_ADDR_LEN) == 0) {
161             return &btc_hh_cb.devices[i];
162         }
163     }
164     return NULL;
165 }
166 
167 /*******************************************************************************
168  *
169  * Function         btc_hh_find_connected_dev_by_bda
170  *
171  * Description      Return the connected device pointer of the specified
172  *                  RawAddress.
173  *
174  * Returns          Device entry pointer in the device table
175  ******************************************************************************/
btc_hh_find_connected_dev_by_bda(BD_ADDR bd_addr)176 static btc_hh_device_t *btc_hh_find_connected_dev_by_bda(BD_ADDR bd_addr)
177 {
178     uint32_t i;
179     for (i = 0; i < BTC_HH_MAX_HID; i++) {
180         if (btc_hh_cb.devices[i].dev_status == ESP_HIDH_CONN_STATE_CONNECTED &&
181             memcmp(btc_hh_cb.devices[i].bd_addr, bd_addr, BD_ADDR_LEN) == 0) {
182             return &btc_hh_cb.devices[i];
183         }
184     }
185     return NULL;
186 }
187 
188 /*******************************************************************************
189  *
190  * Function         btc_hh_stop_vup_timer
191  *
192  * Description      stop virtual unplug timer
193  *
194  * Returns          void
195  ******************************************************************************/
btc_hh_stop_vup_timer(BD_ADDR bd_addr)196 void btc_hh_stop_vup_timer(BD_ADDR bd_addr)
197 {
198     BTIF_TRACE_API("%s", __func__);
199     btc_hh_device_t *p_dev = btc_hh_find_connected_dev_by_bda(bd_addr);
200 
201     if (p_dev != NULL) {
202         BTC_TRACE_DEBUG("stop VUP timer");
203         if (p_dev->vup_timer) {
204             osi_alarm_free(p_dev->vup_timer);
205             p_dev->vup_timer = NULL;
206         }
207     }
208 }
209 
210 /*******************************************************************************
211  *
212  * Function         btc_hh_timer_timeout
213  *
214  * Description      Process timer timeout
215  *
216  * Returns          void
217  ******************************************************************************/
btc_hh_timer_timeout(void * data)218 void btc_hh_timer_timeout(void *data)
219 {
220     btc_hh_device_t *p_dev = (btc_hh_device_t *)data;
221     bt_status_t status;
222     tBTA_HH p_data;
223     btc_msg_t msg;
224     msg.sig = BTC_SIG_API_CB;
225     msg.pid = BTC_PID_HH;
226     msg.act = BTA_HH_VC_UNPLUG_EVT;
227 
228     BTC_TRACE_API("%s", __func__);
229     if (p_dev->dev_status != ESP_HIDH_CONN_STATE_CONNECTED){
230         BTC_TRACE_ERROR("%s Device[%s] is not connected!", __func__,
231                         bdaddr_to_string((const bt_bdaddr_t *)p_dev->bd_addr, bdstr, sizeof(bdstr)));
232         return;
233     }
234 
235     memset(&p_data, 0, sizeof(tBTA_HH));
236     p_data.dev_status.status = BTA_HH_ERR;
237     p_data.dev_status.handle = p_dev->dev_handle;
238 
239     /* switch context to btif task context */
240     status = btc_transfer_context(&msg, &p_data, sizeof(tBTA_HH), NULL, NULL);
241     if (status != BT_STATUS_SUCCESS) {
242         BTC_TRACE_ERROR("%s context transfer failed", __func__);
243     }
244 }
245 
246 /*******************************************************************************
247  *
248  * Function      btc_hh_start_vup_timer
249  *
250  * Description  start virtual unplug timer
251  *
252  * Returns      void
253  ******************************************************************************/
btc_hh_start_vup_timer(BD_ADDR bd_addr)254 void btc_hh_start_vup_timer(BD_ADDR bd_addr)
255 {
256     BTC_TRACE_API("%s", __func__);
257 
258     btc_hh_device_t *p_dev = btc_hh_find_connected_dev_by_bda(bd_addr);
259     if (p_dev == NULL) {
260         BTC_TRACE_ERROR("%s Error: device not connected!", __func__);
261         return;
262     }
263 
264     if (p_dev->vup_timer) {
265         osi_alarm_free(p_dev->vup_timer);
266         p_dev->vup_timer = NULL;
267     }
268     if ((p_dev->vup_timer = osi_alarm_new("btc_hh.vup_timer", btc_hh_timer_timeout, p_dev, BTC_TIMEOUT_VUP_MS)) ==
269         NULL) {
270         BTC_TRACE_ERROR("%s unable to malloc vup_timer!", __func__);
271     }
272 }
273 
274 /*******************************************************************************
275  *
276  * Function         btc_hh_add_added_dev
277  *
278  * Description      Add a new device to the added device list.
279  *
280  * Returns          true if add successfully, otherwise false.
281  ******************************************************************************/
btc_hh_add_added_dev(BD_ADDR bd_addr,tBTA_HH_ATTR_MASK attr_mask)282 bool btc_hh_add_added_dev(BD_ADDR bd_addr, tBTA_HH_ATTR_MASK attr_mask)
283 {
284     int i;
285     for (i = 0; i < BTC_HH_MAX_ADDED_DEV; i++) {
286         if (memcmp(btc_hh_cb.added_devices[i].bd_addr, bd_addr, BD_ADDR_LEN) == 0) {
287             return false;
288         }
289     }
290     for (i = 0; i < BTC_HH_MAX_ADDED_DEV; i++) {
291         if (memcmp(btc_hh_cb.added_devices[i].bd_addr, bd_addr_null, BD_ADDR_LEN) == 0) {
292             memcpy(btc_hh_cb.added_devices[i].bd_addr, bd_addr, BD_ADDR_LEN);
293             btc_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE;
294             btc_hh_cb.added_devices[i].attr_mask = attr_mask;
295             return true;
296         }
297     }
298 
299     BTC_TRACE_ERROR("%s: Error, out of space to add device", __func__);
300     return false;
301 }
302 
303 /*******************************************************************************
304  **
305  ** Function         btc_hh_remove_device
306  **
307  ** Description      Remove an added device from the stack.
308  **
309  ** Returns          void
310  ******************************************************************************/
btc_hh_remove_device(BD_ADDR bd_addr)311 void btc_hh_remove_device(BD_ADDR bd_addr)
312 {
313     int i;
314     btc_hh_device_t *p_dev;
315     btc_hh_added_device_t *p_added_dev;
316 
317     for (i = 0; i < BTC_HH_MAX_ADDED_DEV; i++) {
318         p_added_dev = &btc_hh_cb.added_devices[i];
319         if (memcmp(p_added_dev->bd_addr, bd_addr, BD_ADDR_LEN) == 0) {
320             BTA_HhRemoveDev(p_added_dev->dev_handle);
321             btc_storage_remove_hid_info((bt_bdaddr_t *)p_added_dev->bd_addr);
322             memset(p_added_dev->bd_addr, 0, 6);
323             p_added_dev->dev_handle = BTA_HH_INVALID_HANDLE;
324             break;
325         }
326     }
327 
328     p_dev = btc_hh_find_dev_by_bda(bd_addr);
329     if (p_dev == NULL) {
330         BTC_TRACE_ERROR("%s Oops, can't find device", __func__);
331         return;
332     }
333 
334     /* need to notify up-layer device is disconnected to avoid state out of sync
335      * with up-layer */ //[boblane]
336     // HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr), BTHH_CONN_STATE_DISCONNECTED);
337 
338     p_dev->dev_status = ESP_HIDH_CONN_STATE_UNKNOWN;
339     p_dev->dev_handle = BTA_HH_INVALID_HANDLE;
340     p_dev->ready_for_data = false;
341 
342     if (btc_hh_cb.device_num > 0) {
343         btc_hh_cb.device_num--;
344     } else {
345         BTC_TRACE_WARNING("%s: device_num = 0", __func__);
346     }
347 }
348 
bte_hh_arg_deep_copy(btc_msg_t * msg,void * p_dst,void * p_src)349 static void bte_hh_arg_deep_copy(btc_msg_t *msg, void *p_dst, void *p_src)
350 {
351     tBTA_HH *p_dst_data = (tBTA_HH *)p_dst;
352     tBTA_HH *p_src_data = (tBTA_HH *)p_src;
353     switch (msg->act)
354     {
355     case BTA_HH_GET_RPT_EVT: {
356         BT_HDR *src_hdr = p_src_data->hs_data.rsp_data.p_rpt_data;
357         if (src_hdr) {
358             p_dst_data->hs_data.rsp_data.p_rpt_data = osi_malloc(sizeof(BT_HDR) + src_hdr->offset + src_hdr->len);
359             if (p_dst_data->hs_data.rsp_data.p_rpt_data == NULL) {
360                 BTC_TRACE_ERROR("%s malloc p_rpt_data failed!", __func__);
361                 p_dst_data->hs_data.status = ESP_HIDH_ERR_NO_RES;
362                 break;
363             }
364             memcpy(p_dst_data->hs_data.rsp_data.p_rpt_data, src_hdr, sizeof(BT_HDR) + src_hdr->offset + src_hdr->len);
365         }
366         break;
367     }
368     default:
369         break;
370     }
371 }
372 
bte_hh_evt(tBTA_HH_EVT event,tBTA_HH * p_data)373 static void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH *p_data)
374 {
375     bt_status_t status;
376     int param_len = 0;
377 
378     BTC_TRACE_API("%s event=%d", __func__, event);
379 
380     switch (event) {
381     case BTA_HH_ENABLE_EVT:
382         param_len = sizeof(tBTA_HH_STATUS);
383         break;
384     case BTA_HH_DISABLE_EVT:
385         param_len = sizeof(tBTA_HH_STATUS);
386         break;
387     case BTA_HH_OPEN_EVT:
388         param_len = sizeof(tBTA_HH_CONN);
389         break;
390     case BTA_HH_CLOSE_EVT:
391         param_len = sizeof(tBTA_HH_CBDATA);
392         break;
393     case BTA_HH_GET_RPT_EVT:
394         param_len = sizeof(tBTA_HH_HSDATA);
395         break;
396     case BTA_HH_SET_RPT_EVT:
397         param_len = sizeof(tBTA_HH_CBDATA);
398         break;
399     case BTA_HH_GET_PROTO_EVT:
400         param_len = sizeof(tBTA_HH_HSDATA);
401         break;
402     case BTA_HH_SET_PROTO_EVT:
403         param_len = sizeof(tBTA_HH_CBDATA);
404         break;
405     case BTA_HH_GET_IDLE_EVT:
406         param_len = sizeof(tBTA_HH_HSDATA);
407         break;
408     case BTA_HH_SET_IDLE_EVT:
409         param_len = sizeof(tBTA_HH_CBDATA);
410         break;
411     case BTA_HH_GET_DSCP_EVT:
412         param_len = sizeof(tBTA_HH_DEV_DSCP_INFO);
413         break;
414     case BTA_HH_ADD_DEV_EVT:
415         param_len = sizeof(tBTA_HH_DEV_INFO);
416         break;
417     case BTA_HH_RMV_DEV_EVT:
418         param_len = sizeof(tBTA_HH_DEV_INFO);
419         break;
420     case BTA_HH_VC_UNPLUG_EVT:
421         param_len = sizeof(tBTA_HH_CBDATA);
422         break;
423     case BTA_HH_DATA_EVT:
424         param_len = sizeof(tBTA_HH_API_SENDDATA);
425         break;
426     case BTA_HH_API_ERR_EVT:
427         param_len = 0;
428         break;
429     }
430 
431     btc_msg_t msg;
432     msg.sig = BTC_SIG_API_CB;
433     msg.pid = BTC_PID_HH;
434     msg.act = event;
435 
436     status = btc_transfer_context(&msg, p_data, param_len, bte_hh_arg_deep_copy, btc_hh_cb_arg_deep_free);
437     assert(status == BT_STATUS_SUCCESS);
438 }
439 
440 /*******************************************************************************
441  *
442  * Function         btc_hh_init
443  *
444  * Description      initializes the hh interface
445  *
446  * Returns          void
447  *
448  ******************************************************************************/
btc_hh_init(void)449 static void btc_hh_init(void)
450 {
451     BTC_TRACE_API("%s", __func__);
452     esp_hidh_status_t ret = ESP_HIDH_OK;
453     do {
454         if (is_hidh_init()) {
455             BTC_TRACE_ERROR("%s HH has been initiated, shall uninit first!", __func__);
456             ret = ESP_HIDH_NEED_DEINIT;
457             break;
458         }
459 
460         memset(&btc_hh_cb, 0, sizeof(btc_hh_cb));
461         for (uint8_t i = 0; i < BTC_HH_MAX_HID; i++) {
462             btc_hh_cb.devices[i].dev_status = ESP_HIDH_CONN_STATE_UNKNOWN;
463         }
464         BTA_HhEnable(BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT, bte_hh_evt);
465     } while (0);
466 
467     if (ret != ESP_HIDH_OK) {
468         esp_hidh_cb_param_t param;
469         param.init.status = ret;
470         btc_hh_cb_to_app(ESP_HIDH_INIT_EVT, &param);
471     }
472 }
473 
474 /*******************************************************************************
475  *
476  * Function         btc_hh_deinit
477  *
478  * Description      de-initializes the hh interface
479  *
480  * Returns          void
481  *
482  ******************************************************************************/
btc_hh_deinit(void)483 static void btc_hh_deinit(void)
484 {
485     BTC_TRACE_API("%s", __func__);
486     esp_hidh_status_t ret = ESP_HIDH_OK;
487     do {
488         if (!is_hidh_init()) {
489             BTC_TRACE_ERROR("%s HH has not been initiated, shall init first!", __func__);
490             ret = ESP_HIDH_NEED_INIT;
491             break;
492         }
493 
494         // close all connections
495         for (uint8_t i = 0; i < BTC_HH_MAX_HID; i++) {
496             if(btc_hh_cb.devices[i].dev_status == ESP_HIDH_CONN_STATE_CONNECTED){
497                 BTA_HhClose(btc_hh_cb.devices[i].dev_handle);
498             }
499         }
500         btc_hh_cb.service_dereg_active = TRUE;
501         btc_hh_cb.status = BTC_HH_DISABLING;
502         BTA_HhDisable();
503     } while (0);
504 
505     if (ret != ESP_HIDH_OK) {
506         esp_hidh_cb_param_t param;
507         param.deinit.status = ret;
508         btc_hh_cb_to_app(ESP_HIDH_DEINIT_EVT, &param);
509     }
510 }
511 
512 /*******************************************************************************
513  *
514  * Function         btc_hh_connect
515  *
516  * Description      connection initiated from the BTC thread context
517  *
518  * Returns          void
519  *
520  ******************************************************************************/
btc_hh_connect(btc_hidh_args_t * arg)521 static void btc_hh_connect(btc_hidh_args_t *arg)
522 {
523     BTC_TRACE_API("%s", __func__);
524     esp_hidh_status_t ret = ESP_HIDH_OK;
525     btc_hh_added_device_t* added_dev = NULL;
526     btc_hh_device_t* dev = NULL;
527     esp_hidh_cb_param_t param;
528 
529     do {
530         if (!is_hidh_init()) {
531             BTC_TRACE_ERROR("%s HH has not been initiated, shall init first!", __func__);
532             ret = ESP_HIDH_NEED_INIT;
533             break;
534         }
535 
536         if (btc_hh_cb.status == BTC_HH_DEV_CONNECTING) {
537             BTC_TRACE_ERROR("%s HH is connecting, ignore!", __func__);
538             ret = ESP_HIDH_BUSY;
539             break;
540         }
541 
542         dev = btc_hh_find_dev_by_bda(arg->connect.bd_addr);
543         if (!dev && btc_hh_cb.device_num >= BTC_HH_MAX_HID) {
544             BTC_TRACE_ERROR("%s exceeded the maximum supported HID device number %d!", __func__, BTC_HH_MAX_HID);
545             ret = ESP_HIDH_ERR_NO_RES;
546             break;
547         } else if (dev && dev->dev_status == ESP_HIDH_CONN_STATE_CONNECTED) {
548             BTC_TRACE_WARNING("%s Device[%s] already connected", __func__,
549                               bdaddr_to_string((const bt_bdaddr_t *)arg->connect.bd_addr, bdstr, sizeof(bdstr)));
550             param.open.conn_status = ESP_HIDH_CONN_STATE_CONNECTED;
551             break;
552         }
553 
554         for (int i = 0; i < BTC_HH_MAX_ADDED_DEV; i++) {
555             if (memcmp(btc_hh_cb.added_devices[i].bd_addr, arg->connect.bd_addr, BD_ADDR_LEN) == 0) {
556                 added_dev = &btc_hh_cb.added_devices[i];
557                 BTC_TRACE_WARNING("%s Device[%s] already added, attr_mask = 0x%x", __func__,
558                                   bdaddr_to_string((const bt_bdaddr_t *)arg->connect.bd_addr, bdstr, sizeof(bdstr)),
559                                   added_dev->attr_mask);
560             }
561         }
562 
563         if (added_dev != NULL) {
564             if (added_dev->dev_handle == BTA_HH_INVALID_HANDLE) {
565                 // No space for more HID device now.
566                 BTC_TRACE_ERROR("device added but addition failed");
567                 memset(added_dev->bd_addr, 0, sizeof(added_dev->bd_addr));
568                 ret = ESP_HIDH_ERR;
569                 break;
570             }
571         }
572 
573         /* Not checking the NORMALLY_Connectible flags from sdp record, and anyways
574         sending this request from host, for subsequent user initiated connection. If the remote is
575         not in pagescan mode, we will do 2 retries to connect before giving up */
576         btc_hh_cb.status = BTC_HH_DEV_CONNECTING;
577         memcpy(btc_hh_cb.pending_conn_address, arg->connect.bd_addr, BD_ADDR_LEN);
578         BTA_HhOpen(arg->connect.bd_addr, BTA_HH_PROTO_RPT_MODE, (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT));
579         param.open.conn_status = ESP_HIDH_CONN_STATE_CONNECTING;
580         ret = ESP_HIDH_OK;
581     } while (0);
582 
583     if (ret != ESP_HIDH_OK) {
584         param.open.conn_status = ESP_HIDH_CONN_STATE_DISCONNECTED;
585     }
586     param.open.status = ret;
587     param.open.handle = BTA_HH_INVALID_HANDLE;
588     memcpy(param.open.bd_addr, arg->connect.bd_addr, BD_ADDR_LEN);
589     param.open.is_orig = true;
590     btc_hh_cb_to_app(ESP_HIDH_OPEN_EVT, &param);
591 }
592 
593 /*******************************************************************************
594  *
595  * Function         btc_hh_disconnect
596  *
597  * Description      disconnection initiated from the BTC thread context
598  *
599  * Returns          void
600  *
601  ******************************************************************************/
btc_hh_disconnect(btc_hidh_args_t * arg)602 static void btc_hh_disconnect(btc_hidh_args_t *arg)
603 {
604     BTC_TRACE_API("%s", __func__);
605     esp_hidh_status_t ret = ESP_HIDH_OK;
606     btc_hh_device_t *p_dev;
607     esp_hidh_cb_param_t param;
608 
609     do {
610         if (!is_hidh_init()) {
611             BTC_TRACE_ERROR("%s HH has not been initiated, shall init first!", __func__);
612             ret = ESP_HIDH_NEED_INIT;
613             break;
614         }
615         p_dev = btc_hh_find_connected_dev_by_bda(arg->disconnect.bd_addr);
616         if (p_dev != NULL) {
617             BTA_HhClose(p_dev->dev_handle);
618             param.close.conn_status = ESP_HIDH_CONN_STATE_DISCONNECTING;
619             param.close.handle = p_dev->dev_handle;
620         } else {
621             ret = ESP_HIDH_NO_CONNECTION;
622             BTC_TRACE_ERROR("%s Error: device not connected!", __func__);
623         }
624 
625     } while (0);
626 
627     if (ret != ESP_HIDH_OK) {
628         param.close.conn_status = ESP_HIDH_CONN_STATE_DISCONNECTED;
629         param.close.handle = BTA_HH_INVALID_HANDLE;
630     }
631     param.close.status = ret;
632     btc_hh_cb_to_app(ESP_HIDH_CLOSE_EVT, &param);
633 }
634 
635 /*******************************************************************************
636  *
637  * Function         btc_hh_virtual_unplug
638  *
639  * Description      Virtual unplug initiated from the BTC thread context
640  *                  Special handling for HID mouse-
641  *
642  * Returns          void
643  *
644  ******************************************************************************/
btc_hh_virtual_unplug(btc_hidh_args_t * arg)645 static void btc_hh_virtual_unplug(btc_hidh_args_t *arg)
646 {
647     BTC_TRACE_API("%s", __func__);
648     esp_hidh_status_t ret = ESP_HIDH_OK;
649     btc_hh_device_t *p_dev;
650     esp_hidh_cb_param_t param;
651 
652     do {
653         if (!is_hidh_init()) {
654             BTC_TRACE_ERROR("%s HH has not been initiated, shall init first!", __func__);
655             ret = ESP_HIDH_NEED_INIT;
656             break;
657         }
658         p_dev = btc_hh_find_dev_by_bda(arg->unplug.bd_addr);
659         if ((p_dev != NULL) && (p_dev->dev_status == ESP_HIDH_CONN_STATE_CONNECTED) &&
660             (p_dev->attr_mask & HID_VIRTUAL_CABLE)) {
661             BTC_TRACE_DEBUG("%s: Sending BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG", __func__);
662             /* start the timer */
663             btc_hh_start_vup_timer(arg->unplug.bd_addr);
664             p_dev->local_vup = true;
665             BTA_HhSendCtrl(p_dev->dev_handle, BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG);
666 
667             param.unplug.conn_status = ESP_HIDH_CONN_STATE_DISCONNECTING;
668             param.unplug.handle = p_dev->dev_handle;
669         } else if ((p_dev != NULL) && (p_dev->dev_status == ESP_HIDH_CONN_STATE_CONNECTED)) {
670             BTC_TRACE_WARNING("%s: Virtual unplug not supported, disconnecting device", __func__);
671             /* start the timer */
672             btc_hh_start_vup_timer(arg->unplug.bd_addr);
673             p_dev->local_vup = true;
674             BTA_HhClose(p_dev->dev_handle);
675 
676             param.unplug.conn_status = ESP_HIDH_CONN_STATE_DISCONNECTING;
677             param.unplug.handle = p_dev->dev_handle;
678         } else {
679             BTC_TRACE_ERROR("%s: Error, device not opened, status = %d", __func__, btc_hh_cb.status);
680             ret = ESP_HIDH_NO_CONNECTION;
681             if (memcmp(btc_hh_cb.pending_conn_address, arg->unplug.bd_addr, BD_ADDR_LEN) == 0 &&
682                 (btc_hh_cb.status == BTC_HH_DEV_CONNECTING)) {
683                 btc_hh_cb.status = (BTC_HH_STATUS)BTC_HH_DEV_DISCONNECTED;
684                 memset(btc_hh_cb.pending_conn_address, 0, BD_ADDR_LEN);
685             }
686         }
687     } while (0);
688 
689     if (ret != ESP_HIDH_OK) {
690         param.unplug.conn_status = ESP_HIDH_CONN_STATE_DISCONNECTED;
691         param.unplug.handle = BTA_HH_INVALID_HANDLE;
692     }
693     param.unplug.status = ret;
694     btc_hh_cb_to_app(ESP_HIDH_VC_UNPLUG_EVT, &param);
695 }
696 
697 /*******************************************************************************
698  *
699  * Function         btc_hh_set_info
700  *
701  * Description      Set the HID device descriptor for the specified HID device.
702  *
703  * Returns          void
704  *
705  ******************************************************************************/
btc_hh_set_info(btc_hidh_args_t * arg)706 static void btc_hh_set_info(btc_hidh_args_t *arg)
707 {
708     BTC_TRACE_API("%s", __func__);
709     esp_hidh_status_t ret = ESP_HIDH_OK;
710     esp_hidh_cb_param_t param;
711     tBTA_HH_DEV_DSCP_INFO dscp_info;
712 
713     BTC_TRACE_DEBUG("%s: sub_class = 0x%02x, app_id = %d, vendor_id = 0x%04x, "
714                     "product_id = 0x%04x, version= 0x%04x",
715                     __func__, arg->set_info.hid_info->sub_class, arg->set_info.hid_info->app_id,
716                     arg->set_info.hid_info->vendor_id, arg->set_info.hid_info->product_id,
717                     arg->set_info.hid_info->version);
718     do {
719         if (!is_hidh_init()) {
720             BTC_TRACE_ERROR("%s HH has not been initiated, shall init first!", __func__);
721             ret = ESP_HIDH_NEED_INIT;
722             break;
723         }
724 
725         memset(&dscp_info, 0, sizeof(dscp_info));
726         dscp_info.vendor_id = arg->set_info.hid_info->vendor_id;
727         dscp_info.product_id = arg->set_info.hid_info->product_id;
728         dscp_info.version = arg->set_info.hid_info->version;
729         dscp_info.ctry_code = arg->set_info.hid_info->ctry_code;
730 
731         dscp_info.descriptor.dl_len = arg->set_info.hid_info->dl_len;
732         dscp_info.descriptor.dsc_list = (uint8_t *)osi_malloc(dscp_info.descriptor.dl_len);
733         if (dscp_info.descriptor.dsc_list == NULL) {
734             BTC_TRACE_ERROR("%s malloc dsc_list failed!", __func__);
735             ret = ESP_HIDH_ERR_NO_RES;
736             break;
737         }
738         memcpy(dscp_info.descriptor.dsc_list, arg->set_info.hid_info->dsc_list, dscp_info.descriptor.dl_len);
739 
740         if (btc_hh_add_added_dev(arg->set_info.bd_addr, arg->set_info.hid_info->attr_mask)) {
741             btc_hh_cb.add_event = BTC_HH_SET_INFO_EVT;
742             BTA_HhAddDev(arg->set_info.bd_addr, arg->set_info.hid_info->attr_mask, arg->set_info.hid_info->sub_class,
743                          arg->set_info.hid_info->app_id, dscp_info);
744         } else {
745             BTC_TRACE_ERROR("%s malloc dsc_list failed!", __func__);
746             ret = ESP_HIDH_ERR;
747             break;
748         }
749     } while(0);
750     utl_freebuf((void **)&dscp_info.descriptor.dsc_list);
751 
752     if (ret != ESP_HIDH_OK) {
753         param.set_info.status = ret;
754         param.set_info.handle = BTA_HH_INVALID_HANDLE;
755         memcpy(param.set_info.bd_addr, arg->set_info.bd_addr, BD_ADDR_LEN);
756         btc_hh_cb_to_app(ESP_HIDH_SET_INFO_EVT, &param);
757     }
758 }
759 
760 /*******************************************************************************
761  *
762  * Function         btc_hh_get_protocol
763  *
764  * Description      Get the HID proto mode.
765  *
766  * Returns          void
767  *
768  ******************************************************************************/
btc_hh_get_protocol(btc_hidh_args_t * arg)769 static void btc_hh_get_protocol(btc_hidh_args_t *arg)
770 {
771     BTC_TRACE_API("%s", __func__);
772     esp_hidh_status_t ret = ESP_HIDH_OK;
773     esp_hidh_cb_param_t param;
774     btc_hh_device_t *p_dev;
775 
776     do {
777         if (!is_hidh_init()) {
778             BTC_TRACE_ERROR("%s HH has not been initiated, shall init first!", __func__);
779             ret = ESP_HIDH_NEED_INIT;
780             break;
781         }
782         p_dev = btc_hh_find_connected_dev_by_bda(arg->get_protocol.bd_addr);
783         if (p_dev == NULL) {
784             ret = ESP_HIDH_NO_CONNECTION;
785             BTC_TRACE_ERROR("%s Error: device not connected!", __func__);
786             break;
787         }
788         BTA_HhGetProtoMode(p_dev->dev_handle);
789     } while(0);
790 
791     if (ret != ESP_HIDH_OK) {
792         param.get_proto.proto_mode = ESP_HIDH_UNSUPPORTED_MODE;
793         param.get_proto.handle = BTA_HH_INVALID_HANDLE;
794         param.get_proto.status = ret;
795         btc_hh_cb_to_app(ESP_HIDH_GET_PROTO_EVT, &param);
796     }
797 }
798 
799 /*******************************************************************************
800  *
801  * Function         btc_hh_set_protocol
802  *
803  * Description      Set the HID proto mode.
804  *
805  * Returns          void
806  *
807  ******************************************************************************/
btc_hh_set_protocol(btc_hidh_args_t * arg)808 static void btc_hh_set_protocol(btc_hidh_args_t *arg)
809 {
810     BTC_TRACE_API("%s", __func__);
811     esp_hidh_status_t ret = ESP_HIDH_OK;
812     esp_hidh_cb_param_t param;
813     btc_hh_device_t *p_dev;
814 
815     do {
816         if (!is_hidh_init()) {
817             BTC_TRACE_ERROR("%s HH has not been initiated, shall init first!", __func__);
818             ret = ESP_HIDH_NEED_INIT;
819             break;
820         }
821         p_dev = btc_hh_find_connected_dev_by_bda(arg->set_protocol.bd_addr);
822         if (p_dev == NULL) {
823             ret = ESP_HIDH_NO_CONNECTION;
824             BTC_TRACE_ERROR("%s Error: device not connected!", __func__);
825             break;
826         } else if (arg->set_protocol.protocol_mode != ESP_HIDH_REPORT_MODE && arg->set_protocol.protocol_mode != ESP_HIDH_BOOT_MODE) {
827             BTC_TRACE_ERROR("%s: Error, device proto_mode = %d.", __func__, arg->set_protocol.protocol_mode);
828             ret = ESP_HIDH_HS_INVALID_PARAM;
829             break;
830         } else {
831             BTA_HhSetProtoMode(p_dev->dev_handle, proto_mode_change_to_lower_layer(arg->set_protocol.protocol_mode));
832         }
833     } while (0);
834 
835     if (ret != ESP_HIDH_OK) {
836         param.set_proto.handle = BTA_HH_INVALID_HANDLE;
837         param.set_proto.status = ret;
838         btc_hh_cb_to_app(ESP_HIDH_SET_PROTO_EVT, &param);
839     }
840 }
841 
842 /*******************************************************************************
843  *
844  * Function         btc_hh_get_report
845  *
846  * Description      Send a GET_REPORT to HID device.
847  *
848  * Returns          void
849  *
850  ******************************************************************************/
btc_hh_get_report(btc_hidh_args_t * arg)851 static void btc_hh_get_report(btc_hidh_args_t *arg)
852 {
853     BTC_TRACE_API("%s", __func__);
854     esp_hidh_status_t ret = ESP_HIDH_OK;
855     esp_hidh_cb_param_t param;
856     btc_hh_device_t *p_dev;
857 
858     do {
859         if (!is_hidh_init()) {
860             BTC_TRACE_ERROR("%s HH has not been initiated, shall init first!", __func__);
861             ret = ESP_HIDH_NEED_INIT;
862             break;
863         }
864 
865         p_dev = btc_hh_find_connected_dev_by_bda(arg->get_report.bd_addr);
866         if (p_dev == NULL) {
867             ret = ESP_HIDH_NO_CONNECTION;
868             BTC_TRACE_ERROR("%s Error: device not connected!", __func__);
869             break;
870         } else if (((int)arg->get_report.report_type) <= BTA_HH_RPTT_RESRV ||
871                    ((int)arg->get_report.report_type) > BTA_HH_RPTT_FEATURE) {
872             BTC_TRACE_ERROR("%s Error: report type=%d not supported!", __func__, arg->get_report.report_type);
873             ret = ESP_HIDH_HS_INVALID_PARAM;
874             break;
875         } else {
876             BTA_HhGetReport(p_dev->dev_handle, arg->get_report.report_type, arg->get_report.report_id,
877                             arg->get_report.buffer_size);
878         }
879     } while (0);
880 
881     if (ret != ESP_HIDH_OK) {
882         param.get_rpt.handle = BTA_HH_INVALID_HANDLE;
883         param.get_rpt.status = ret;
884         param.get_rpt.len = 0;
885         param.get_rpt.data = NULL;
886         btc_hh_cb_to_app(ESP_HIDH_GET_RPT_EVT, &param);
887     }
888 }
889 
890 /*******************************************************************************
891  *
892  * Function         create_pbuf
893  *
894  * Description      Helper function to create p_buf for send_data or set_report
895  *
896  * Returns          BT_HDR *
897  *
898  ******************************************************************************/
create_pbuf(uint16_t len,uint8_t * data)899 static BT_HDR *create_pbuf(uint16_t len, uint8_t *data)
900 {
901     uint8_t *pbuf_data;
902     BT_HDR *p_buf = (BT_HDR *)osi_malloc(len + BTA_HH_MIN_OFFSET + sizeof(BT_HDR));
903     if (p_buf == NULL) {
904         BTC_TRACE_ERROR("%s failed!", __func__);
905         return NULL;
906     }
907     p_buf->len = len;
908     p_buf->offset = BTA_HH_MIN_OFFSET;
909 
910     pbuf_data = (uint8_t *)(p_buf + 1) + p_buf->offset;
911     memcpy(pbuf_data, data, len);
912 
913     return p_buf;
914 }
915 
916 /*******************************************************************************
917  *
918  * Function         btc_hh_set_report
919  *
920  * Description      Send a SET_REPORT to HID device.
921  *
922  * Returns          void
923  *
924  ******************************************************************************/
btc_hh_set_report(btc_hidh_args_t * arg)925 static void btc_hh_set_report(btc_hidh_args_t *arg)
926 {
927     BTC_TRACE_API("%s", __func__);
928     esp_hidh_status_t ret = ESP_HIDH_OK;
929     esp_hidh_cb_param_t param;
930     btc_hh_device_t *p_dev;
931 
932     do {
933         if (!is_hidh_init()) {
934             BTC_TRACE_ERROR("%s HH has not been initiated, shall init first!", __func__);
935             ret = ESP_HIDH_NEED_INIT;
936             break;
937         }
938 
939         p_dev = btc_hh_find_connected_dev_by_bda(arg->set_report.bd_addr);
940         if (p_dev == NULL) {
941             ret = ESP_HIDH_NO_CONNECTION;
942             BTC_TRACE_ERROR("%s Error: device not connected!", __func__);
943             break;
944         } else if (((int)arg->set_report.report_type) <= BTA_HH_RPTT_RESRV ||
945                    ((int)arg->set_report.report_type) > BTA_HH_RPTT_FEATURE) {
946             BTC_TRACE_ERROR("%s Error: report type=%d not supported!", __func__, arg->set_report.report_type);
947             ret = ESP_HIDH_HS_INVALID_PARAM;
948             break;
949         } else if (arg->set_report.report == NULL || arg->set_report.len == 0) {
950             BTC_TRACE_ERROR("%s Error: report is empty!", __func__);
951             ret = ESP_HIDH_HS_INVALID_PARAM;
952             break;
953         } else {
954             BT_HDR* p_buf = create_pbuf(arg->set_report.len, arg->set_report.report);
955             if (p_buf == NULL) {
956                 ret = ESP_HIDH_ERR_NO_RES;
957                 break;
958             }
959             BTA_HhSetReport(p_dev->dev_handle, arg->set_report.report_type, p_buf);
960         }
961     } while(0);
962 
963     if (ret != ESP_HIDH_OK) {
964         param.set_rpt.handle = BTA_HH_INVALID_HANDLE;
965         param.set_rpt.status = ret;
966         btc_hh_cb_to_app(ESP_HIDH_SET_RPT_EVT, &param);
967     }
968 }
969 
970 /*******************************************************************************
971  *
972  * Function         btc_hh_send_data
973  *
974  * Description      Send a SEND_DATA to HID device.
975  *
976  * Returns          void
977  *
978  ******************************************************************************/
btc_hh_send_data(btc_hidh_args_t * arg)979 static void btc_hh_send_data(btc_hidh_args_t *arg)
980 {
981     BTC_TRACE_API("%s", __func__);
982     esp_hidh_status_t ret = ESP_HIDH_OK;
983     esp_hidh_cb_param_t param;
984     btc_hh_device_t *p_dev;
985 
986     do {
987         if (!is_hidh_init()) {
988             BTC_TRACE_ERROR("%s HH has not been initiated, shall init first!", __func__);
989             ret = ESP_HIDH_NEED_INIT;
990             break;
991         }
992 
993         p_dev = btc_hh_find_connected_dev_by_bda(arg->send_data.bd_addr);
994         if (p_dev == NULL) {
995             ret = ESP_HIDH_NO_CONNECTION;
996             BTC_TRACE_ERROR("%s Error: device not connected!", __func__);
997             break;
998         } else if (arg->send_data.data == NULL || arg->send_data.len == 0) {
999             BTC_TRACE_ERROR("%s Error: send data is empty!", __func__);
1000             ret = ESP_HIDH_HS_INVALID_PARAM;
1001             break;
1002         } else {
1003             BT_HDR *p_buf = create_pbuf(arg->send_data.len, arg->send_data.data);
1004             if (p_buf == NULL) {
1005                 ret = ESP_HIDH_ERR_NO_RES;
1006                 break;
1007             }
1008             p_buf->layer_specific = BTA_HH_RPTT_OUTPUT;
1009             BTA_HhSendData(p_dev->dev_handle, arg->send_data.bd_addr, p_buf);
1010         }
1011     } while(0);
1012 
1013     if (ret != ESP_HIDH_OK) {
1014         param.send_data.handle = BTA_HH_INVALID_HANDLE;
1015         param.send_data.status = ret;
1016         param.send_data.reason = 0;
1017         btc_hh_cb_to_app(ESP_HIDH_DATA_EVT, &param);
1018     }
1019 }
1020 
1021 /*******************************************************************************
1022 **
1023 ** Function         btc_hh_get_idle_time
1024 **
1025 ** Description      Get the HID idle time
1026 **
1027 ** Returns          void
1028 **
1029 *******************************************************************************/
btc_hh_get_idle_time(btc_hidh_args_t * arg)1030 static void btc_hh_get_idle_time(btc_hidh_args_t *arg)
1031 {
1032     BTC_TRACE_API("%s", __func__);
1033     esp_hidh_status_t ret = ESP_HIDH_OK;
1034     esp_hidh_cb_param_t param;
1035     btc_hh_device_t *p_dev;
1036 
1037     do {
1038         if (!is_hidh_init()) {
1039             BTC_TRACE_ERROR("%s HH has not been initiated, shall init first!", __func__);
1040             ret = ESP_HIDH_NEED_INIT;
1041             break;
1042         }
1043 
1044         p_dev = btc_hh_find_connected_dev_by_bda(arg->get_idle.bd_addr);
1045         if (p_dev == NULL) {
1046             ret = ESP_HIDH_NO_CONNECTION;
1047             BTC_TRACE_ERROR("%s Error: device not connected!", __func__);
1048             break;
1049         }
1050         BTA_HhGetIdle(p_dev->dev_handle);
1051     } while (0);
1052 
1053     if (ret != ESP_HIDH_OK) {
1054         param.get_idle.handle = BTA_HH_INVALID_HANDLE;
1055         param.get_idle.status = ret;
1056         param.get_idle.idle_rate = 0;
1057         btc_hh_cb_to_app(ESP_HIDH_GET_IDLE_EVT, &param);
1058     }
1059 }
1060 
1061 /*******************************************************************************
1062 **
1063 ** Function         btc_hh_set_idle_time
1064 **
1065 ** Description      Set the HID idle time
1066 **
1067 ** Returns          void
1068 **
1069 *******************************************************************************/
btc_hh_set_idle_time(btc_hidh_args_t * arg)1070 static void btc_hh_set_idle_time(btc_hidh_args_t *arg)
1071 {
1072     BTC_TRACE_API("%s", __func__);
1073     esp_hidh_status_t ret = ESP_HIDH_OK;
1074     esp_hidh_cb_param_t param;
1075     btc_hh_device_t *p_dev;
1076 
1077     do {
1078         if (!is_hidh_init()) {
1079             BTC_TRACE_ERROR("%s HH has not been initiated, shall init first!", __func__);
1080             ret = ESP_HIDH_NEED_INIT;
1081             break;
1082         }
1083 
1084         p_dev = btc_hh_find_connected_dev_by_bda(arg->set_idle.bd_addr);
1085         if (p_dev == NULL) {
1086             ret = ESP_HIDH_NO_CONNECTION;
1087             BTC_TRACE_ERROR("%s Error: device not connected!", __func__);
1088             break;
1089         }
1090         BTA_HhSetIdle(p_dev->dev_handle, arg->set_idle.idle_time);
1091     } while (0);
1092 
1093     if (ret != ESP_HIDH_OK) {
1094         param.set_idle.handle = BTA_HH_INVALID_HANDLE;
1095         param.set_idle.status = ret;
1096         btc_hh_cb_to_app(ESP_HIDH_SET_IDLE_EVT, &param);
1097     }
1098 }
1099 
btc_hh_call_arg_deep_free(btc_msg_t * msg)1100 static void btc_hh_call_arg_deep_free(btc_msg_t *msg)
1101 {
1102     btc_hidh_args_t *arg = (btc_hidh_args_t *)msg->arg;
1103 
1104     switch (msg->act) {
1105     case BTC_HH_SET_INFO_EVT:
1106         utl_freebuf((void **)&arg->set_info.hid_info);
1107         break;
1108     case BTC_HH_SET_REPORT_EVT:
1109         utl_freebuf((void **)&arg->set_report.report);
1110         break;
1111     case BTC_HH_SEND_DATA_EVT:
1112         utl_freebuf((void **)&arg->send_data.data);
1113         break;
1114     default:
1115         break;
1116     }
1117 }
1118 
btc_hh_call_handler(btc_msg_t * msg)1119 void btc_hh_call_handler(btc_msg_t *msg)
1120 {
1121     btc_hidh_args_t *arg = (btc_hidh_args_t *)(msg->arg);
1122     switch (msg->act) {
1123     case BTC_HH_INIT_EVT:
1124         btc_hh_init();
1125         break;
1126     case BTC_HH_CONNECT_EVT:
1127         btc_hh_connect(arg);
1128         break;
1129     case BTC_HH_DISCONNECT_EVT:
1130         btc_hh_disconnect(arg);
1131         break;
1132     case BTC_HH_UNPLUG_EVT:
1133         btc_hh_virtual_unplug(arg);
1134         break;
1135     case BTC_HH_SET_INFO_EVT:
1136         btc_hh_set_info(arg);
1137         break;
1138     case BTC_HH_GET_PROTO_EVT:
1139         btc_hh_get_protocol(arg);
1140         break;
1141     case BTC_HH_SET_PROTO_EVT:
1142         btc_hh_set_protocol(arg);
1143         break;
1144     case BTC_HH_GET_IDLE_EVT:
1145         btc_hh_get_idle_time(arg);
1146         break;
1147     case BTC_HH_SET_IDLE_EVT:
1148         btc_hh_set_idle_time(arg);
1149         break;
1150     case BTC_HH_GET_REPORT_EVT:
1151         btc_hh_get_report(arg);
1152         break;
1153     case BTC_HH_SET_REPORT_EVT:
1154         btc_hh_set_report(arg);
1155         break;
1156     case BTC_HH_SEND_DATA_EVT:
1157         btc_hh_send_data(arg);
1158         break;
1159     case BTC_HH_DEINIT_EVT:
1160         btc_hh_deinit();
1161         break;
1162     default:
1163         BTC_TRACE_WARNING("unknown hidh action %d", msg->act);
1164         break;
1165     }
1166     btc_hh_call_arg_deep_free(msg);
1167 }
1168 
btc_hh_cb_arg_deep_free(btc_msg_t * msg)1169 void btc_hh_cb_arg_deep_free(btc_msg_t *msg)
1170 {
1171     tBTA_HH *arg = (tBTA_HH *)msg->arg;
1172 
1173     switch (msg->act) {
1174     case BTA_HH_GET_RPT_EVT:
1175         utl_freebuf((void **)&arg->hs_data.rsp_data.p_rpt_data);
1176         break;
1177     case BTA_HH_DATA_IND_EVT:
1178         utl_freebuf((void **)&arg->int_data.p_data);
1179         break;
1180     default:
1181         break;
1182     }
1183 }
1184 
btc_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO * dest,tBTA_HH_DEV_DSCP_INFO * src)1185 bool btc_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO *dest, tBTA_HH_DEV_DSCP_INFO *src)
1186 {
1187     dest->descriptor.dl_len = 0;
1188     if (src->descriptor.dl_len > 0) {
1189         dest->descriptor.dsc_list = (uint8_t *)osi_malloc(src->descriptor.dl_len);
1190     }
1191     if (dest->descriptor.dsc_list) {
1192         memcpy(dest->descriptor.dsc_list, src->descriptor.dsc_list, src->descriptor.dl_len);
1193         dest->descriptor.dl_len = src->descriptor.dl_len;
1194     }
1195     dest->vendor_id = src->vendor_id;
1196     dest->product_id = src->product_id;
1197     dest->version = src->version;
1198     dest->ctry_code = src->ctry_code;
1199     dest->ssr_max_latency = src->ssr_max_latency;
1200     dest->ssr_min_tout = src->ssr_min_tout;
1201     return true;
1202 }
1203 
btc_hh_cb_copy_hid_info(esp_hidh_cb_param_t * param,tBTA_HH_DEV_DSCP_INFO * src)1204 bool btc_hh_cb_copy_hid_info(esp_hidh_cb_param_t *param, tBTA_HH_DEV_DSCP_INFO *src)
1205 {
1206     param->dscp.dl_len = 0;
1207     if (src->descriptor.dl_len > 0) {
1208         param->dscp.dsc_list = (uint8_t *)osi_malloc(src->descriptor.dl_len);
1209     }
1210     if (param->dscp.dsc_list) {
1211         memcpy(param->dscp.dsc_list, src->descriptor.dsc_list, src->descriptor.dl_len);
1212         param->dscp.dl_len = src->descriptor.dl_len;
1213     }
1214     param->dscp.vendor_id = src->vendor_id;
1215     param->dscp.product_id = src->product_id;
1216     param->dscp.version = src->version;
1217     param->dscp.ctry_code = src->ctry_code;
1218     param->dscp.ssr_max_latency = src->ssr_max_latency;
1219     param->dscp.ssr_min_tout = src->ssr_min_tout;
1220     return true;
1221 }
1222 
btc_hh_cb_handler(btc_msg_t * msg)1223 void btc_hh_cb_handler(btc_msg_t *msg)
1224 {
1225     esp_hidh_cb_param_t param = {0};
1226     tBTA_HH *p_data = (tBTA_HH *)msg->arg;
1227     btc_hh_device_t *p_dev = NULL;
1228     int len, i;
1229     BTC_TRACE_DEBUG("%s: event=%s dereg = %d", __func__, dump_hh_event(msg->act), btc_hh_cb.service_dereg_active);
1230     switch (msg->act) {
1231     case BTA_HH_ENABLE_EVT:
1232         if (p_data->status == BTA_HH_OK) {
1233             btc_hh_cb.status = BTC_HH_ENABLED;
1234             BTC_TRACE_DEBUG("Loading added devices");
1235             /* Add hid descriptors for already bonded hid devices*/
1236             // btc_storage_load_bonded_hid_info();
1237         } else {
1238             btc_hh_cb.status = BTC_HH_DISABLED;
1239             BTC_TRACE_ERROR("Error, HH enabling failed, status = %d", p_data->status);
1240         }
1241         param.init.status = p_data->status;
1242         btc_hh_cb_to_app(ESP_HIDH_INIT_EVT, &param);
1243         break;
1244     case BTA_HH_DISABLE_EVT:
1245         btc_hh_cb.status = BTC_HH_DISABLED;
1246         if (btc_hh_cb.service_dereg_active) {
1247             BTIF_TRACE_DEBUG("BTA_HH_DISABLE_EVT: enabling HID Device service");
1248             // btif_hd_service_registration();
1249             btc_hh_cb.service_dereg_active = FALSE;
1250         }
1251         if (p_data->status == BTA_HH_OK) {
1252             // Clear the control block
1253             for (uint8_t i = 0; i < BTC_HH_MAX_HID; i++) {
1254                 if (btc_hh_cb.devices[i].vup_timer) {
1255                     osi_alarm_free(btc_hh_cb.devices[i].vup_timer);
1256                 }
1257             }
1258             memset(&btc_hh_cb, 0, sizeof(btc_hh_cb));
1259             for (i = 0; i < BTC_HH_MAX_HID; i++) {
1260                 btc_hh_cb.devices[i].dev_status = ESP_HIDH_CONN_STATE_UNKNOWN;
1261             }
1262         } else {
1263             BTC_TRACE_ERROR("Error, HH disabling failed, status = %d", p_data->status);
1264         }
1265         param.deinit.status = p_data->status;
1266         btc_hh_cb_to_app(ESP_HIDH_DEINIT_EVT, &param);
1267         break;
1268     case BTA_HH_OPEN_EVT:
1269         BTC_TRACE_DEBUG("handle=%d, status =%d", p_data->conn.handle, p_data->conn.status);
1270         memset(btc_hh_cb.pending_conn_address, 0, BD_ADDR_LEN);
1271         if (p_data->conn.status == BTA_HH_OK) {
1272             p_dev = btc_hh_find_connected_dev_by_handle(p_data->conn.handle);
1273             if (p_dev == NULL) {
1274                 BTC_TRACE_ERROR("Error, cannot find device with handle %d", p_data->conn.handle);
1275                 btc_hh_cb.status = (BTC_HH_STATUS)BTC_HH_DEV_DISCONNECTED;
1276                 // The connect request must come from device side and exceeded the
1277                 // connected HID device number.
1278                 BTA_HhClose(p_data->conn.handle);
1279 
1280                 param.open.status = ESP_HIDH_ERR;
1281                 param.open.conn_status = ESP_HIDH_CONN_STATE_DISCONNECTED;
1282             } else {
1283                 BTC_TRACE_DEBUG("Found device...Getting dscp info for handle "
1284                                 "... %d",
1285                                 p_data->conn.handle);
1286                 memcpy(p_dev->bd_addr, p_data->conn.bda, BD_ADDR_LEN);
1287                 btc_hh_cb.status = (BTC_HH_STATUS)BTC_HH_DEV_CONNECTED;
1288                 // Send set_idle if the peer_device is a keyboard [boblane]
1289                 // if (check_cod(&p_data->conn.bda, COD_HID_KEYBOARD) || check_cod(&p_data->conn.bda, COD_HID_COMBO))
1290                 //     BTA_HhSetIdle(p_data->conn.handle, 0);
1291                 btc_hh_cb.p_curr_dev = btc_hh_find_connected_dev_by_handle(p_data->conn.handle);
1292                 BTA_HhGetDscpInfo(p_data->conn.handle);
1293                 p_dev->dev_status = ESP_HIDH_CONN_STATE_CONNECTED;
1294 
1295                 param.open.status = ESP_HIDH_OK;
1296                 param.open.conn_status = ESP_HIDH_CONN_STATE_CONNECTED;
1297             }
1298         } else {
1299             p_dev = btc_hh_find_dev_by_bda(p_data->conn.bda);
1300             if (p_dev != NULL) {
1301                 btc_hh_stop_vup_timer(p_dev->bd_addr);
1302                 p_dev->dev_status = ESP_HIDH_CONN_STATE_DISCONNECTED;
1303             }
1304             btc_hh_cb.status = (BTC_HH_STATUS)BTC_HH_DEV_DISCONNECTED;
1305 
1306             param.open.status = p_data->conn.status;
1307             param.open.conn_status = ESP_HIDH_CONN_STATE_DISCONNECTED;
1308         }
1309         param.open.handle = p_data->conn.handle;
1310         param.open.is_orig = p_data->conn.is_orig;
1311         memcpy(param.open.bd_addr, p_data->conn.bda, BD_ADDR_LEN);
1312         btc_hh_cb_to_app(ESP_HIDH_OPEN_EVT, &param);
1313         break;
1314     case BTA_HH_GET_DSCP_EVT:
1315         len = p_data->dscp_info.descriptor.dl_len;
1316         BTC_TRACE_DEBUG("len = %d", len);
1317         do {
1318             param.dscp.status = ESP_HIDH_OK;
1319             param.dscp.handle = BTA_HH_INVALID_HANDLE;
1320             param.dscp.added = false;
1321             p_dev = btc_hh_cb.p_curr_dev;
1322             if (p_dev == NULL) {
1323                 BTC_TRACE_ERROR("No HID device is currently connected");
1324                 param.dscp.status = ESP_HIDH_NO_CONNECTION;
1325                 break;
1326             }
1327 
1328             if (btc_hh_add_added_dev(p_dev->bd_addr, p_dev->attr_mask)) {
1329                 tBTA_HH_DEV_DSCP_INFO dscp_info;
1330                 bt_status_t ret;
1331                 btc_hh_copy_hid_info(&dscp_info, &p_data->dscp_info);
1332                 btc_hh_cb.add_event = BTC_HH_CONNECT_EVT;
1333                 BTA_HhAddDev(p_dev->bd_addr, p_dev->attr_mask, p_dev->sub_class, p_dev->app_id, dscp_info);
1334                 // write hid info to nvs
1335                 ret = btc_storage_add_hid_device_info((bt_bdaddr_t *)p_dev->bd_addr, p_dev->attr_mask, p_dev->sub_class, p_dev->app_id,
1336                                                       p_data->dscp_info.vendor_id, p_data->dscp_info.product_id,
1337                                                       p_data->dscp_info.version, p_data->dscp_info.ctry_code,
1338                                                       p_data->dscp_info.ssr_max_latency, p_data->dscp_info.ssr_min_tout,
1339                                                       len, p_data->dscp_info.descriptor.dsc_list);
1340 
1341                 if (ret != BT_STATUS_SUCCESS) {
1342                     BTC_TRACE_ERROR("write hid info to nvs failed!");
1343                 }
1344                 // Free buffer created for dscp_info;
1345                 if (dscp_info.descriptor.dl_len > 0 && dscp_info.descriptor.dsc_list != NULL) {
1346                     utl_freebuf((void **)&dscp_info.descriptor.dsc_list);
1347                     dscp_info.descriptor.dl_len = 0;
1348                 }
1349             } else {
1350                 // Device already added.
1351                 BTC_TRACE_WARNING("%s: Device already added ", __func__);
1352                 param.dscp.added = true;
1353             }
1354             btc_hh_cb_copy_hid_info(&param, &p_data->dscp_info);
1355             param.dscp.handle = p_dev->dev_handle;
1356         } while(0);
1357         btc_hh_cb_to_app(ESP_HIDH_GET_DSCP_EVT, &param);
1358         if (param.dscp.dl_len > 0 && param.dscp.dsc_list != NULL) {
1359             utl_freebuf((void **)&param.dscp.dsc_list);
1360             param.dscp.dl_len = 0;
1361         }
1362         break;
1363     case BTA_HH_CLOSE_EVT:
1364         BTC_TRACE_DEBUG("status = %d, handle = %d", p_data->dev_status.status,
1365                          p_data->dev_status.handle);
1366         p_dev = btc_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
1367         if (p_dev != NULL) {
1368             BTC_TRACE_DEBUG("uhid local_vup=%d", p_dev->local_vup);
1369             btc_hh_stop_vup_timer(p_dev->bd_addr);
1370             /* If this is a locally initiated VUP, remove the bond as ACL got
1371              *  disconnected while VUP being processed.
1372              */
1373             if (p_dev->local_vup) {
1374                 p_dev->local_vup = false;
1375                 BTA_DmRemoveDevice(p_dev->bd_addr, BT_TRANSPORT_BR_EDR);
1376             }
1377 
1378             btc_hh_cb.status = (BTC_HH_STATUS)BTC_HH_DEV_DISCONNECTED;
1379             p_dev->dev_status = ESP_HIDH_CONN_STATE_DISCONNECTED;
1380             param.close.status = p_data->dev_status.status;
1381         } else {
1382             BTC_TRACE_ERROR("Error: cannot find device with handle %d", p_data->dev_status.handle);
1383             param.close.status = ESP_HIDH_NO_CONNECTION;
1384         }
1385         param.close.handle = p_data->dev_status.handle;
1386         param.close.conn_status = ESP_HIDH_CONN_STATE_DISCONNECTED;
1387         btc_hh_cb_to_app(ESP_HIDH_CLOSE_EVT, &param);
1388         break;
1389     case BTA_HH_VC_UNPLUG_EVT:
1390         BTC_TRACE_DEBUG("status = %d, handle = %d", p_data->dev_status.status,
1391                         p_data->dev_status.handle);
1392         p_dev = btc_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
1393         btc_hh_cb.status = (BTC_HH_STATUS)BTC_HH_DEV_DISCONNECTED;
1394         if (p_dev != NULL) {
1395             /* Stop the VUP timer */
1396             btc_hh_stop_vup_timer(p_dev->bd_addr);
1397             p_dev->dev_status = ESP_HIDH_CONN_STATE_DISCONNECTED;
1398             BTC_TRACE_DEBUG("%s---Sending connection state change", __func__);
1399             param.close.status = ESP_HIDH_OK;
1400             param.close.handle = p_data->dev_status.handle;
1401             param.close.conn_status = ESP_HIDH_CONN_STATE_DISCONNECTED;
1402             btc_hh_cb_to_app(ESP_HIDH_CLOSE_EVT, &param);
1403             BTC_TRACE_DEBUG("%s---Removing HID bond", __func__);
1404             /* If it is locally initiated VUP or remote device has its major COD as
1405             Peripheral removed the bond.*/
1406             // [boblane]
1407             if (p_dev->local_vup) {
1408                 p_dev->local_vup = false;
1409                 BTA_DmRemoveDevice(p_dev->bd_addr, BT_TRANSPORT_BR_EDR);
1410             } else {
1411                 btc_hh_remove_device(p_dev->bd_addr);
1412             }
1413             param.unplug.status = p_data->dev_status.status;
1414         } else {
1415             BTC_TRACE_ERROR("Error: cannot find device with handle %d", p_data->dev_status.handle);
1416             param.unplug.status = ESP_HIDH_NO_CONNECTION;
1417         }
1418         param.unplug.handle = p_data->dev_status.handle;
1419         param.unplug.conn_status = ESP_HIDH_CONN_STATE_DISCONNECTED;
1420         btc_hh_cb_to_app(ESP_HIDH_VC_UNPLUG_EVT, &param);
1421         break;
1422     case BTA_HH_DATA_EVT:
1423         BTC_TRACE_DEBUG("status = %d, handle = %d", p_data->send_data.status,
1424                          p_data->send_data.handle);
1425         param.send_data.handle = p_data->send_data.handle;
1426         param.send_data.status = p_data->send_data.status;
1427         param.send_data.reason = p_data->send_data.reason;
1428         btc_hh_cb_to_app(ESP_HIDH_DATA_EVT, &param);
1429         break;
1430     case BTA_HH_GET_PROTO_EVT:
1431         BTC_TRACE_DEBUG("status = %d, handle = %d, proto = [%d], %s", p_data->hs_data.status,
1432                         p_data->hs_data.handle, p_data->hs_data.rsp_data.proto_mode,
1433                         (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE)
1434                             ? "Report Mode"
1435                             : (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_BOOT_MODE) ? "Boot Mode"
1436                                                                                               : "Unsupported");
1437         param.get_proto.proto_mode = proto_mode_change_to_upper_layer(p_data->hs_data.rsp_data.proto_mode);
1438         param.get_proto.handle = p_data->hs_data.handle;
1439         param.get_proto.status = p_data->hs_data.status;
1440         btc_hh_cb_to_app(ESP_HIDH_GET_PROTO_EVT, &param);
1441         break;
1442     case BTA_HH_SET_PROTO_EVT:
1443         BTIF_TRACE_DEBUG("status = %d, handle = %d", p_data->dev_status.status,
1444                          p_data->dev_status.handle);
1445         param.set_proto.handle = p_data->dev_status.handle;
1446         param.set_proto.status = p_data->dev_status.status;
1447         btc_hh_cb_to_app(ESP_HIDH_SET_PROTO_EVT, &param);
1448         break;
1449     case BTA_HH_GET_RPT_EVT: {
1450         BT_HDR *hdr = p_data->hs_data.rsp_data.p_rpt_data;
1451         uint8_t *data = NULL;
1452         uint16_t len = 0;
1453         BTC_TRACE_DEBUG("status = %d, handle = %d", p_data->hs_data.status, p_data->hs_data.handle);
1454         /* p_rpt_data is NULL in HANDSHAKE response case */
1455         if (hdr) {
1456             data = (uint8_t *)(hdr + 1) + hdr->offset;
1457             len = hdr->len;
1458         }
1459         param.get_rpt.handle = p_data->hs_data.handle;
1460         param.get_rpt.status = p_data->hs_data.status;
1461         param.get_rpt.len = len;
1462         param.get_rpt.data = data;
1463         btc_hh_cb_to_app(ESP_HIDH_GET_RPT_EVT, &param);
1464         break;
1465     }
1466     case BTA_HH_SET_RPT_EVT:
1467         BTC_TRACE_DEBUG("status = %d, handle = %d", p_data->dev_status.status,
1468                          p_data->dev_status.handle);
1469         param.set_rpt.handle = p_data->dev_status.handle;
1470         param.set_rpt.status = p_data->dev_status.status;
1471         btc_hh_cb_to_app(ESP_HIDH_SET_RPT_EVT, &param);
1472         break;
1473     case BTA_HH_GET_IDLE_EVT:
1474         BTC_TRACE_DEBUG("handle = %d, status = %d, rate = %d", p_data->hs_data.handle, p_data->hs_data.status,
1475                         p_data->hs_data.rsp_data.idle_rate);
1476         param.get_idle.handle = p_data->hs_data.handle;
1477         param.get_idle.status = p_data->hs_data.status;
1478         param.get_idle.idle_rate = p_data->hs_data.rsp_data.idle_rate;
1479         btc_hh_cb_to_app(ESP_HIDH_GET_IDLE_EVT, &param);
1480         break;
1481     case BTA_HH_SET_IDLE_EVT:
1482         BTC_TRACE_DEBUG("status = %d, handle = %d", p_data->dev_status.status, p_data->dev_status.handle);
1483         param.set_idle.handle = p_data->dev_status.handle;
1484         param.set_idle.status = p_data->dev_status.status;
1485         btc_hh_cb_to_app(BTA_HH_SET_IDLE_EVT, &param);
1486         break;
1487     case BTA_HH_ADD_DEV_EVT:
1488         BTC_TRACE_DEBUG("status = %d, handle = %d", p_data->dev_info.status, p_data->dev_info.handle);
1489         for (uint8_t i = 0; i < BTC_HH_MAX_ADDED_DEV; i++) {
1490             if (memcmp(btc_hh_cb.added_devices[i].bd_addr, p_data->dev_info.bda, BD_ADDR_LEN) == 0) {
1491                 if (p_data->dev_info.status == BTA_HH_OK) {
1492                     btc_hh_cb.added_devices[i].dev_handle = p_data->dev_info.handle;
1493                 } else {
1494                     memset(btc_hh_cb.added_devices[i].bd_addr, 0, BD_ADDR_LEN);
1495                     btc_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE;
1496                 }
1497                 break;
1498             }
1499         }
1500         if (btc_hh_cb.add_event == BTC_HH_SET_INFO_EVT) {
1501             param.set_info.handle = p_data->dev_info.handle;
1502             param.set_info.status = p_data->dev_info.status;
1503             memcpy(param.set_info.bd_addr, p_data->dev_info.bda, BD_ADDR_LEN);
1504             btc_hh_cb_to_app(ESP_HIDH_SET_INFO_EVT, &param);
1505         } else {
1506             param.add_dev.handle = p_data->dev_info.handle;
1507             param.add_dev.status = p_data->dev_info.status;
1508             memcpy(param.add_dev.bd_addr, p_data->dev_info.bda, BD_ADDR_LEN);
1509             btc_hh_cb_to_app(ESP_HIDH_ADD_DEV_EVT, &param);
1510         }
1511         break;
1512     case BTA_HH_RMV_DEV_EVT:
1513         BTC_TRACE_DEBUG("status = %d, handle = %d", p_data->dev_info.status, p_data->dev_info.handle);
1514         param.rmv_dev.handle = p_data->dev_info.status;
1515         param.rmv_dev.status = p_data->dev_info.handle;
1516         memcpy(param.rmv_dev.bd_addr, p_data->dev_info.bda, BD_ADDR_LEN);
1517         btc_hh_cb_to_app(ESP_HIDH_RMV_DEV_EVT, &param);
1518         break;
1519     case BTA_HH_DATA_IND_EVT:
1520         BTC_TRACE_DEBUG("status = %d, handle = %d", p_data->int_data.status, p_data->int_data.handle);
1521         if (p_data->int_data.status == BTA_HH_OK && p_data->int_data.p_data) {
1522             param.data_ind.len = p_data->int_data.p_data->len;
1523             param.data_ind.data = p_data->int_data.p_data->data + p_data->int_data.p_data->offset;
1524         }
1525         param.data_ind.handle = p_data->int_data.handle;
1526         param.data_ind.status = p_data->int_data.status;
1527         param.data_ind.proto_mode = proto_mode_change_to_upper_layer(p_data->int_data.proto_mode);
1528         btc_hh_cb_to_app(ESP_HIDH_DATA_IND_EVT, &param);
1529         break;
1530     case BTA_HH_API_ERR_EVT:
1531         break;
1532     default:
1533         BTC_TRACE_WARNING("%s: Unhandled event: %d", __func__, msg->act);
1534         break;
1535     }
1536     btc_hh_cb_arg_deep_free(msg);
1537 }
1538 
btc_hh_arg_deep_copy(btc_msg_t * msg,void * p_dest,void * p_src)1539 void btc_hh_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
1540 {
1541     btc_hidh_args_t *dst = (btc_hidh_args_t *)p_dest;
1542     btc_hidh_args_t *src = (btc_hidh_args_t *)p_src;
1543 
1544     switch (msg->act) {
1545     case BTC_HH_SET_INFO_EVT:
1546         dst->set_info.hid_info = (esp_hidh_hid_info_t *)osi_malloc(sizeof(esp_hidh_hid_info_t));
1547         if (dst->set_info.hid_info) {
1548             memcpy(dst->set_info.hid_info, src->set_info.hid_info, sizeof(esp_hidh_hid_info_t));
1549         } else {
1550             BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, msg->act);
1551         }
1552         break;
1553     case BTC_HH_SET_REPORT_EVT:
1554         dst->set_report.report = (uint8_t *)osi_malloc(src->set_report.len);
1555         if (dst->set_report.report) {
1556             memcpy(dst->set_report.report, src->set_report.report, src->set_report.len);
1557         } else {
1558             BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, msg->act);
1559         }
1560         break;
1561     case BTC_HH_SEND_DATA_EVT:
1562         dst->send_data.data = (uint8_t *)osi_malloc(src->send_data.len);
1563         if (dst->send_data.data) {
1564             memcpy(dst->send_data.data, src->send_data.data, src->send_data.len);
1565         } else {
1566             BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, msg->act);
1567         }
1568         break;
1569     default:
1570         break;
1571     }
1572 }
1573 
1574 #endif // HID_HOST_INCLUDED == TRUE
1575