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