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