pkt/nimble/netif: fix deadlock on connection loss
This commit is contained in:
parent
61f37ce395
commit
6ee2c1025b
@ -216,6 +216,18 @@ static inline int nimble_netif_conn_connected(const uint8_t *addr)
|
|||||||
return (nimble_netif_conn_get_by_addr(addr) != NIMBLE_NETIF_CONN_INVALID);
|
return (nimble_netif_conn_get_by_addr(addr) != NIMBLE_NETIF_CONN_INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test if the given connection is (still) open
|
||||||
|
*
|
||||||
|
* @param[in] conn Connection to test
|
||||||
|
*
|
||||||
|
* @return != 0 if true
|
||||||
|
* @return 0 if false
|
||||||
|
*/
|
||||||
|
static inline int nimble_netif_conn_is_open(const nimble_netif_conn_t *conn)
|
||||||
|
{
|
||||||
|
return (conn->coc != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Convenience function to check if any context is currently in the
|
* @brief Convenience function to check if any context is currently in the
|
||||||
|
|||||||
@ -62,6 +62,8 @@
|
|||||||
|
|
||||||
/* thread flag used for signaling transmit readiness */
|
/* thread flag used for signaling transmit readiness */
|
||||||
#define FLAG_TX_UNSTALLED (1u << 13)
|
#define FLAG_TX_UNSTALLED (1u << 13)
|
||||||
|
#define FLAG_TX_NOTCONN (1u << 12)
|
||||||
|
#define FLAG_ALL (FLAG_TX_UNSTALLED | FLAG_TX_NOTCONN)
|
||||||
|
|
||||||
/* allocate a stack for the netif device */
|
/* allocate a stack for the netif device */
|
||||||
static char _stack[THREAD_STACKSIZE_DEFAULT];
|
static char _stack[THREAD_STACKSIZE_DEFAULT];
|
||||||
@ -130,7 +132,11 @@ static int _send_pkt(nimble_netif_conn_t *conn, gnrc_pktsnip_t *pkt)
|
|||||||
do {
|
do {
|
||||||
res = ble_l2cap_send(conn->coc, sdu);
|
res = ble_l2cap_send(conn->coc, sdu);
|
||||||
if (res == BLE_HS_EBUSY) {
|
if (res == BLE_HS_EBUSY) {
|
||||||
thread_flags_wait_all(FLAG_TX_UNSTALLED);
|
thread_flags_t state = thread_flags_wait_any(FLAG_ALL);
|
||||||
|
/* abort if the active connection was lost in the mean time */
|
||||||
|
if ((state & FLAG_TX_NOTCONN) && !nimble_netif_conn_is_open(conn)) {
|
||||||
|
return -ECONNRESET;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (res == BLE_HS_EBUSY);
|
} while (res == BLE_HS_EBUSY);
|
||||||
|
|
||||||
@ -455,6 +461,7 @@ static int _on_gap_master_evt(struct ble_gap_event *event, void *arg)
|
|||||||
: NIMBLE_NETIF_ABORT_MASTER;
|
: NIMBLE_NETIF_ABORT_MASTER;
|
||||||
uint8_t addr[BLE_ADDR_LEN];
|
uint8_t addr[BLE_ADDR_LEN];
|
||||||
nimble_netif_conn_free(handle, addr);
|
nimble_netif_conn_free(handle, addr);
|
||||||
|
thread_flags_set(_netif_thread, FLAG_TX_NOTCONN);
|
||||||
_notify(handle, type, addr);
|
_notify(handle, type, addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -498,6 +505,7 @@ static int _on_gap_slave_evt(struct ble_gap_event *event, void *arg)
|
|||||||
: NIMBLE_NETIF_ABORT_SLAVE;
|
: NIMBLE_NETIF_ABORT_SLAVE;
|
||||||
uint8_t addr[BLE_ADDR_LEN];
|
uint8_t addr[BLE_ADDR_LEN];
|
||||||
nimble_netif_conn_free(handle, addr);
|
nimble_netif_conn_free(handle, addr);
|
||||||
|
thread_flags_set(_netif_thread, FLAG_TX_NOTCONN);
|
||||||
_notify(handle, type, addr);
|
_notify(handle, type, addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user