Skip to content

Commit 55a8a18

Browse files
committed
Merge branch 'bugfix/fix_hid_connection_failed_bug_v5.3' into 'release/v5.3'
fix(bt/bluedroid): Fix HID Device connection failed bug[backport 5.3] See merge request espressif/esp-idf!30586
2 parents c19e762 + 91c4a94 commit 55a8a18

File tree

8 files changed

+69
-26
lines changed

8 files changed

+69
-26
lines changed

components/bt/host/bluedroid/bta/hd/bta_hd_act.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,26 @@ extern void bta_hd_exit_suspend_act(tBTA_HD_DATA *p_data)
722722
bta_sys_idle(BTA_ID_HD, 1, p_cback->addr);
723723
}
724724

725+
/*******************************************************************************
726+
*
727+
* Function bta_hd_open_failure
728+
*
729+
* Description
730+
*
731+
* Returns void
732+
*
733+
******************************************************************************/
734+
extern void bta_hd_open_failure(tBTA_HD_DATA *p_data)
735+
{
736+
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
737+
tBTA_HD cback_data = {0};
738+
739+
bdcpy(cback_data.conn.bda, p_cback->addr);
740+
cback_data.conn.status = BTA_HD_ERROR;
741+
cback_data.conn.conn_status = BTA_HD_CONN_STATE_DISCONNECTED;
742+
bta_hd_cb.p_cback(BTA_HD_OPEN_EVT, &cback_data);
743+
}
744+
725745
/*******************************************************************************
726746
*
727747
* Function bta_hd_cback

components/bt/host/bluedroid/bta/hd/bta_hd_main.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ enum {
6262
BTA_HD_VC_UNPLUG_DONE_ACT,
6363
BTA_HD_SUSPEND_ACT,
6464
BTA_HD_EXIT_SUSPEND_ACT,
65+
BTA_HD_OPEN_FAILURE,
6566
BTA_HD_NUM_ACTIONS
6667
};
6768

@@ -74,7 +75,7 @@ const tBTA_HD_ACTION bta_hd_action[] = {
7475
bta_hd_disconnect_act, bta_hd_add_device_act, bta_hd_remove_device_act, bta_hd_send_report_act,
7576
bta_hd_report_error_act, bta_hd_vc_unplug_act, bta_hd_open_act, bta_hd_close_act,
7677
bta_hd_intr_data_act, bta_hd_get_report_act, bta_hd_set_report_act, bta_hd_set_protocol_act,
77-
bta_hd_vc_unplug_done_act, bta_hd_suspend_act, bta_hd_exit_suspend_act,
78+
bta_hd_vc_unplug_done_act, bta_hd_suspend_act, bta_hd_exit_suspend_act, bta_hd_open_failure
7879
};
7980

8081
/* state table information */
@@ -118,7 +119,7 @@ const uint8_t bta_hd_st_idle[][BTA_HD_NUM_COLS] = {
118119
/* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
119120
/* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_VC_UNPLUG_ACT, BTA_HD_IDLE_ST},
120121
/* BTA_HD_INT_OPEN_EVT */ {BTA_HD_OPEN_ACT, BTA_HD_CONN_ST},
121-
/* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
122+
/* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_OPEN_FAILURE, BTA_HD_IDLE_ST},
122123
/* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
123124
/* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
124125
/* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},

components/bt/host/bluedroid/bta/hd/include/bta_hd_int.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,5 +164,6 @@ extern void bta_hd_set_protocol_act(tBTA_HD_DATA *p_data);
164164
extern void bta_hd_vc_unplug_done_act(tBTA_HD_DATA *p_data);
165165
extern void bta_hd_suspend_act(tBTA_HD_DATA *p_data);
166166
extern void bta_hd_exit_suspend_act(tBTA_HD_DATA *p_data);
167+
extern void bta_hd_open_failure(tBTA_HD_DATA *p_data);
167168

168169
#endif

components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ static void btc_hd_deinit(void)
261261
}
262262

263263
btc_hd_cb.service_dereg_active = FALSE;
264-
// unresgister app will also relase the connection
264+
// unregister app will also release the connection
265265
// and disable after receiving unregister event from lower layer
266266
if (is_hidd_app_register()) {
267267
btc_hd_unregister_app(true);
@@ -844,6 +844,8 @@ void btc_hd_cb_handler(btc_msg_t *msg)
844844
// }
845845
// btc_storage_set_hidd((bt_bdaddr_t *)&p_data->conn.bda);
846846
btc_hd_cb.status = BTC_HD_CONNECTED;
847+
} else if (p_data->conn.conn_status == BTA_HD_CONN_STATE_DISCONNECTED) {
848+
btc_hd_cb.status = BTC_HD_DISCONNECTED;
847849
}
848850
param.open.status = p_data->conn.status;
849851
param.open.conn_status = p_data->conn.conn_status;

components/bt/host/bluedroid/stack/hid/hidd_conn.c

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ static void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result)
231231
tHID_CONN *p_hcon = &hd_cb.device.conn;
232232
HIDD_TRACE_EVENT("%s: cid=%04x result=%d, conn_state=%d", __func__, cid, result, p_hcon->conn_state);
233233
if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) {
234-
HIDD_TRACE_WARNING("%s: unknown cid", __func__);
234+
HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid);
235235
return;
236236
}
237237
if (!(p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) ||
@@ -243,10 +243,12 @@ static void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result)
243243
}
244244
if (result != L2CAP_CONN_OK) {
245245
HIDD_TRACE_WARNING("%s: connection failed, now disconnect", __func__);
246-
if (cid == p_hcon->ctrl_cid)
246+
if (cid == p_hcon->ctrl_cid) {
247247
p_hcon->ctrl_cid = 0;
248-
else
248+
} else {
249249
p_hcon->intr_cid = 0;
250+
}
251+
250252
hidd_conn_disconnect();
251253
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, HID_L2CAP_CONN_FAIL | (uint32_t)result, NULL);
252254
return;
@@ -278,7 +280,7 @@ static void hidd_l2cif_config_ind(uint16_t cid, tL2CAP_CFG_INFO *p_cfg)
278280
HIDD_TRACE_EVENT("%s: cid=%04x", __func__, cid);
279281
p_hcon = &hd_cb.device.conn;
280282
if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) {
281-
HIDD_TRACE_WARNING("%s: unknown cid", __func__);
283+
HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid);
282284
return;
283285
}
284286
if ((!p_cfg->mtu_present) || (p_cfg->mtu > HID_DEV_MTU_SIZE))
@@ -297,7 +299,8 @@ static void hidd_l2cif_config_ind(uint16_t cid, tL2CAP_CFG_INFO *p_cfg)
297299
// update flags
298300
if (cid == p_hcon->ctrl_cid) {
299301
p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_CTRL_CFG_DONE;
300-
if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE)) {
302+
if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE) &&
303+
(p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR)) {
301304
p_hcon->disc_reason = HID_L2CAP_CONN_FAIL;
302305
if ((p_hcon->intr_cid = L2CA_ConnectReq(HID_PSM_INTERRUPT, hd_cb.device.addr)) == 0) {
303306
p_hcon->conn_state = HID_CONN_STATE_UNUSED;
@@ -330,7 +333,7 @@ static void hidd_l2cif_config_cfm(uint16_t cid, tL2CAP_CFG_INFO *p_cfg)
330333
HIDD_TRACE_EVENT("%s: cid=%04x pcfg->result=%d", __func__, cid, p_cfg->result);
331334
p_hcon = &hd_cb.device.conn;
332335
if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) {
333-
HIDD_TRACE_WARNING("%s: unknown cid", __func__);
336+
HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid);
334337
return;
335338
}
336339
if (p_hcon->intr_cid == cid && p_cfg->result == L2CAP_CFG_UNACCEPTABLE_PARAMS && p_cfg->qos_present) {
@@ -357,7 +360,8 @@ static void hidd_l2cif_config_cfm(uint16_t cid, tL2CAP_CFG_INFO *p_cfg)
357360
// update flags
358361
if (cid == p_hcon->ctrl_cid) {
359362
p_hcon->conn_flags |= HID_CONN_FLAGS_MY_CTRL_CFG_DONE;
360-
if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE)) {
363+
if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE) &&
364+
(p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR)) {
361365
p_hcon->disc_reason = HID_L2CAP_CONN_FAIL;
362366
if ((p_hcon->intr_cid = L2CA_ConnectReq(HID_PSM_INTERRUPT, hd_cb.device.addr)) == 0) {
363367
p_hcon->conn_state = HID_CONN_STATE_UNUSED;
@@ -389,11 +393,14 @@ static void hidd_l2cif_disconnect_ind(uint16_t cid, bool ack_needed)
389393
HIDD_TRACE_EVENT("%s: cid=%04x ack_needed=%d", __func__, cid, ack_needed);
390394
p_hcon = &hd_cb.device.conn;
391395
if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) {
392-
HIDD_TRACE_WARNING("%s: unknown cid", __func__);
396+
HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid);
393397
return;
394398
}
395-
if (ack_needed)
399+
400+
if (ack_needed) {
396401
L2CA_DisconnectRsp(cid);
402+
}
403+
397404
if (cid == p_hcon->ctrl_cid) {
398405
p_hcon->ctrl_cid = 0;
399406
p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING_CTRL;
@@ -417,7 +424,7 @@ static void hidd_l2cif_disconnect_ind(uint16_t cid, bool ack_needed)
417424
*
418425
* Function hidd_l2cif_disconnect_cfm
419426
*
420-
* Description Handles L2CAP disconection response
427+
* Description Handles L2CAP disconnection response
421428
*
422429
* Returns void
423430
*
@@ -428,7 +435,7 @@ static void hidd_l2cif_disconnect_cfm(uint16_t cid, uint16_t result)
428435
HIDD_TRACE_EVENT("%s: cid=%04x result=%d", __func__, cid, result);
429436
p_hcon = &hd_cb.device.conn;
430437
if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) {
431-
HIDD_TRACE_WARNING("%s: unknown cid", __func__);
438+
HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid);
432439
return;
433440
}
434441
if (cid == p_hcon->ctrl_cid) {
@@ -465,7 +472,7 @@ static void hidd_l2cif_cong_ind(uint16_t cid, bool congested)
465472
HIDD_TRACE_EVENT("%s: cid=%04x congested=%d", __func__, cid, congested);
466473
p_hcon = &hd_cb.device.conn;
467474
if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) {
468-
HIDD_TRACE_WARNING("%s: unknown cid", __func__);
475+
HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid);
469476
return;
470477
}
471478
if (congested) {
@@ -492,7 +499,7 @@ static void hidd_l2cif_data_ind(uint16_t cid, BT_HDR *p_msg)
492499
HIDD_TRACE_EVENT("%s: cid=%04x", __func__, cid);
493500
p_hcon = &hd_cb.device.conn;
494501
if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) {
495-
HIDD_TRACE_WARNING("%s: unknown cid", __func__);
502+
HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid);
496503
osi_free(p_msg);
497504
return;
498505
}
@@ -645,7 +652,7 @@ tHID_STATUS hidd_conn_initiate(void)
645652
p_dev->conn.ctrl_cid = 0;
646653
p_dev->conn.intr_cid = 0;
647654
p_dev->conn.disc_reason = HID_L2CAP_CONN_FAIL;
648-
p_dev->conn.conn_flags = HID_CONN_FLAGS_IS_ORIG;
655+
p_dev->conn.conn_flags |= HID_CONN_FLAGS_IS_ORIG;
649656
BTM_SetOutService(p_dev->addr, BTM_SEC_SERVICE_HIDD_SEC_CTRL, HIDD_SEC_CHN);
650657
/* Check if L2CAP started the connection process */
651658
if ((p_dev->conn.ctrl_cid = L2CA_ConnectReq(HID_PSM_CONTROL, p_dev->addr)) == 0) {

components/bt/host/bluedroid/stack/hid/hidh_api.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,6 @@ tHID_STATUS HID_HostAddDev ( BD_ADDR addr, UINT16 attr_mask, UINT8 *handle )
379379
if (!hh_cb.devices[i].in_use) {
380380
hh_cb.devices[i].in_use = TRUE;
381381
hh_cb.devices[i].delay_remove = FALSE;
382-
hh_cb.devices[i].is_orig = FALSE;
383382
memcpy( hh_cb.devices[i].addr, addr, sizeof( BD_ADDR ) ) ;
384383
hh_cb.devices[i].state = HID_DEV_NO_CONN;
385384
hh_cb.devices[i].conn_tries = 0 ;
@@ -487,7 +486,6 @@ tHID_STATUS HID_HostOpenDev ( UINT8 dev_handle )
487486
}
488487

489488
hh_cb.devices[dev_handle].conn_tries = 1;
490-
hh_cb.devices[dev_handle].is_orig = TRUE;
491489
return hidh_conn_initiate( dev_handle );
492490
}
493491

@@ -666,7 +664,7 @@ BOOLEAN HID_HostConnectOrig(UINT8 dev_handle)
666664
break;
667665
}
668666

669-
ret = hh_cb.devices[dev_handle].is_orig;
667+
ret = hidh_conn_is_orig(dev_handle);
670668
} while (0);
671669

672670
return ret;

components/bt/host/bluedroid/stack/hid/hidh_conn.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,8 @@ static void hidh_l2cif_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
457457

458458
if (l2cap_cid == p_hcon->ctrl_cid) {
459459
p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_CTRL_CFG_DONE;
460-
if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) &&
461-
(p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE)) {
460+
if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE) &&
461+
(p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR)) {
462462
/* Connect interrupt channel */
463463
p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; /* Reset initial reason for CLOSE_EVT: Connection Attempt was made but failed */
464464
if ((p_hcon->intr_cid = L2CA_ConnectReq (HID_PSM_INTERRUPT, hh_cb.devices[dhandle].addr)) == 0) {
@@ -528,8 +528,8 @@ static void hidh_l2cif_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
528528

529529
if (l2cap_cid == p_hcon->ctrl_cid) {
530530
p_hcon->conn_flags |= HID_CONN_FLAGS_MY_CTRL_CFG_DONE;
531-
if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) &&
532-
(p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE)) {
531+
if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE) &&
532+
(p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR)) {
533533
/* Connect interrupt channel */
534534
p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; /* Reset initial reason for CLOSE_EVT: Connection Attempt was made but failed */
535535
if ((p_hcon->intr_cid = L2CA_ConnectReq (HID_PSM_INTERRUPT, hh_cb.devices[dhandle].addr)) == 0) {
@@ -968,7 +968,7 @@ tHID_STATUS hidh_conn_initiate (UINT8 dhandle)
968968
p_dev->conn.disc_reason = HID_L2CAP_CONN_FAIL; /* Reset initial reason for CLOSE_EVT: Connection Attempt was made but failed */
969969

970970
/* We are the originator of this connection */
971-
p_dev->conn.conn_flags = HID_CONN_FLAGS_IS_ORIG;
971+
p_dev->conn.conn_flags |= HID_CONN_FLAGS_IS_ORIG;
972972

973973
if (p_dev->attr_mask & HID_SEC_REQUIRED) {
974974
service_id = BTM_SEC_SERVICE_HIDH_SEC_CTRL;
@@ -989,6 +989,20 @@ tHID_STATUS hidh_conn_initiate (UINT8 dhandle)
989989
return ( HID_SUCCESS );
990990
}
991991

992+
/*******************************************************************************
993+
**
994+
** Function hidh_conn_is_orig
995+
**
996+
** Description This function check if we are the originator of this connection
997+
**
998+
** Returns BOOLEAN
999+
**
1000+
*******************************************************************************/
1001+
BOOLEAN hidh_conn_is_orig(UINT8 dhandle)
1002+
{
1003+
tHID_HOST_DEV_CTB *p_dev = &hh_cb.devices[dhandle];
1004+
return (p_dev->conn.conn_flags & HID_CONN_FLAGS_IS_ORIG);
1005+
}
9921006

9931007
/*******************************************************************************
9941008
**

components/bt/host/bluedroid/stack/hid/include/hid_int.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ enum { HID_DEV_NO_CONN, HID_DEV_CONNECTED };
3535
typedef struct per_device_ctb {
3636
BOOLEAN in_use;
3737
BOOLEAN delay_remove;
38-
BOOLEAN is_orig;
3938
BD_ADDR addr; /* BD-Addr of the host device */
4039
UINT16 attr_mask; /* 0x01- virtual_cable; 0x02- normally_connectable; 0x03- reconn_initiate;
4140
0x04- sdp_disable; */
@@ -66,6 +65,7 @@ extern tHID_STATUS hidh_conn_reg (void);
6665
extern void hidh_conn_dereg( void );
6766
extern tHID_STATUS hidh_conn_disconnect (UINT8 dhandle);
6867
extern tHID_STATUS hidh_conn_initiate (UINT8 dhandle);
68+
extern BOOLEAN hidh_conn_is_orig(UINT8 dhandle);
6969
extern void hidh_proc_repage_timeout (TIMER_LIST_ENT *p_tle);
7070
#ifdef __cplusplus
7171
extern "C" {

0 commit comments

Comments
 (0)