mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
pkg/nimble/netif: fix randomized conn intervals
This commit is contained in:
parent
c5a1012695
commit
46f6bf1987
@ -42,6 +42,7 @@ extern "C" {
|
||||
typedef struct {
|
||||
struct ble_l2cap_chan *coc; /**< l2cap context as exposed by NimBLE */
|
||||
uint16_t gaphandle; /**< GAP handle exposed by NimBLE */
|
||||
uint16_t itvl; /**< currently used connection interval */
|
||||
uint16_t state; /**< the current state of the context */
|
||||
uint8_t addr[BLE_ADDR_LEN]; /**< BLE address of connected peer
|
||||
(in network byte order) */
|
||||
@ -181,10 +182,10 @@ void nimble_netif_conn_free(int handle, uint8_t *addr);
|
||||
*
|
||||
* @param[in] handle connection handle
|
||||
*
|
||||
* @return used connection interval on success, multiples of 1.25ms
|
||||
* @return used connection interval in milliseconds on success
|
||||
* @return 0 if unable to get connection interval
|
||||
*/
|
||||
uint16_t nimble_netif_conn_get_itvl(int handle);
|
||||
uint16_t nimble_netif_conn_get_itvl_ms(int handle);
|
||||
|
||||
/**
|
||||
* @brief Check if the given connection interval is used, taking the minimal
|
||||
@ -200,17 +201,6 @@ uint16_t nimble_netif_conn_get_itvl(int handle);
|
||||
*/
|
||||
bool nimble_netif_conn_itvl_used(uint16_t itvl, int skip_handle);
|
||||
|
||||
/**
|
||||
* @brief Check if connection interval used by the given connection is valid
|
||||
*
|
||||
* @param[in] handle connection to verify
|
||||
*
|
||||
* @return true if the connection interval of the given connection collides
|
||||
* with the connection interval of another BLE connection
|
||||
* @return false if the connection interval of the given connection is valid
|
||||
*/
|
||||
bool nimble_netif_conn_itvl_invalid(int handle);
|
||||
|
||||
/**
|
||||
* @brief Generate a pseudorandom connection interval from the given range
|
||||
*
|
||||
|
@ -364,20 +364,32 @@ static int _on_l2cap_server_evt(struct ble_l2cap_event *event, void *arg)
|
||||
conn = nimble_netif_conn_get(handle);
|
||||
assert(conn);
|
||||
|
||||
/* in the unlikely event the L2CAP connection establishment fails,
|
||||
* we close the GAP connection */
|
||||
if (event->connect.status != 0) {
|
||||
/* in the unlikely event the L2CAP connection establishment
|
||||
* fails, we close the GAP connection */
|
||||
ble_gap_terminate(conn->gaphandle, BLE_ERR_REM_USER_CONN_TERM);
|
||||
break;
|
||||
}
|
||||
|
||||
/* we need to update the state to keep everything in sync */
|
||||
conn->coc = event->connect.chan;
|
||||
conn->state |= NIMBLE_NETIF_L2CAP_SERVER;
|
||||
conn->state &= ~(NIMBLE_NETIF_ADV | NIMBLE_NETIF_CONNECTING);
|
||||
|
||||
/* in case conn itvl spacing is enabled, make sure that the conn
|
||||
* itvl of the new connection is sufficiently spaced */
|
||||
if ((NIMBLE_NETIF_CONN_ITVL_SPACING > 0) &&
|
||||
nimble_netif_conn_itvl_used(conn->itvl, handle)) {
|
||||
ble_gap_terminate(conn->gaphandle, BLE_ERR_REM_USER_CONN_TERM);
|
||||
break;
|
||||
}
|
||||
|
||||
_notify(handle, NIMBLE_NETIF_CONNECTED_SLAVE, conn->addr);
|
||||
break;
|
||||
case BLE_L2CAP_EVENT_COC_DISCONNECTED:
|
||||
conn = nimble_netif_conn_from_gaphandle(event->disconnect.conn_handle);
|
||||
assert(conn && (conn->state & NIMBLE_NETIF_L2CAP_SERVER));
|
||||
conn->coc = NULL;
|
||||
conn->state &= ~NIMBLE_NETIF_L2CAP_CONNECTED;
|
||||
break;
|
||||
case BLE_L2CAP_EVENT_COC_ACCEPT: {
|
||||
@ -411,9 +423,21 @@ static void _on_gap_connected(nimble_netif_conn_t *conn, uint16_t conn_handle)
|
||||
(void)res;
|
||||
|
||||
conn->gaphandle = conn_handle;
|
||||
conn->itvl = desc.conn_itvl;
|
||||
bluetil_addr_swapped_cp(desc.peer_id_addr.val, conn->addr);
|
||||
}
|
||||
|
||||
static void _on_gap_param_update(int handle, nimble_netif_conn_t *conn)
|
||||
{
|
||||
struct ble_gap_conn_desc desc;
|
||||
int res = ble_gap_conn_find(conn->gaphandle, &desc);
|
||||
assert(res == 0) ;
|
||||
(void)res;
|
||||
|
||||
conn->itvl = desc.conn_itvl;
|
||||
_notify(handle, NIMBLE_NETIF_CONN_UPDATED, conn->addr);
|
||||
}
|
||||
|
||||
static int _on_gap_master_evt(struct ble_gap_event *event, void *arg)
|
||||
{
|
||||
int res = 0;
|
||||
@ -458,7 +482,7 @@ static int _on_gap_master_evt(struct ble_gap_event *event, void *arg)
|
||||
break;
|
||||
}
|
||||
case BLE_GAP_EVENT_CONN_UPDATE:
|
||||
_notify(handle, NIMBLE_NETIF_CONN_UPDATED, conn->addr);
|
||||
_on_gap_param_update(handle, conn);
|
||||
break;
|
||||
case BLE_GAP_EVENT_CONN_UPDATE_REQ:
|
||||
case BLE_GAP_EVENT_MTU:
|
||||
@ -485,11 +509,6 @@ static int _on_gap_slave_evt(struct ble_gap_event *event, void *arg)
|
||||
_notify(handle, NIMBLE_NETIF_ABORT_SLAVE, addr);
|
||||
break;
|
||||
}
|
||||
if ((NIMBLE_NETIF_CONN_ITVL_SPACING > 0) &&
|
||||
nimble_netif_conn_itvl_invalid(handle)) {
|
||||
nimble_netif_close(handle);
|
||||
break;
|
||||
}
|
||||
_on_gap_connected(conn, event->connect.conn_handle);
|
||||
assert(conn->state == NIMBLE_NETIF_ADV);
|
||||
conn->state = NIMBLE_NETIF_GAP_SLAVE;
|
||||
@ -507,7 +526,7 @@ static int _on_gap_slave_evt(struct ble_gap_event *event, void *arg)
|
||||
break;
|
||||
}
|
||||
case BLE_GAP_EVENT_CONN_UPDATE:
|
||||
_notify(handle, NIMBLE_NETIF_CONN_UPDATED, conn->addr);
|
||||
_on_gap_param_update(handle, conn);
|
||||
break;
|
||||
case BLE_GAP_EVENT_CONN_UPDATE_REQ:
|
||||
/* nothing to do here */
|
||||
|
@ -222,33 +222,24 @@ unsigned nimble_netif_conn_count(uint16_t filter)
|
||||
return cnt;
|
||||
}
|
||||
|
||||
uint16_t nimble_netif_conn_get_itvl(int handle)
|
||||
uint16_t nimble_netif_conn_get_itvl_ms(int handle)
|
||||
{
|
||||
assert((handle >= 0) && (handle < CONN_CNT));
|
||||
struct ble_gap_conn_desc desc;
|
||||
|
||||
if (!(_conn[handle].state & NIMBLE_NETIF_GAP_CONNECTED)) {
|
||||
return 0;
|
||||
}
|
||||
int res = ble_gap_conn_find(_conn[handle].gaphandle, &desc);
|
||||
if (res != 0) {
|
||||
if ((handle == 0) || (handle >= CONN_CNT)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return desc.conn_itvl;
|
||||
return ((_conn[handle].itvl * BLE_HCI_CONN_ITVL) / 1000);
|
||||
}
|
||||
|
||||
bool nimble_netif_conn_itvl_used(uint16_t itvl, int skip_handle)
|
||||
{
|
||||
for (unsigned i = 0; i < CONN_CNT; i++) {
|
||||
if (i != skip_handle) {
|
||||
uint16_t conn_itvl = nimble_netif_conn_get_itvl(i);
|
||||
if (conn_itvl != 0) {
|
||||
uint16_t diff = (conn_itvl < itvl) ? itvl - conn_itvl
|
||||
: conn_itvl - itvl;
|
||||
if (diff < NIMBLE_NETIF_CONN_ITVL_SPACING) {
|
||||
return true;
|
||||
}
|
||||
for (int handle = 0; handle < CONN_CNT; handle++) {
|
||||
if ((handle != skip_handle) && (_conn[handle].itvl != 0)) {
|
||||
uint16_t diff = (_conn[handle].itvl < itvl)
|
||||
? itvl - _conn[handle].itvl
|
||||
: _conn[handle].itvl - itvl;
|
||||
if (diff < NIMBLE_NETIF_CONN_ITVL_SPACING) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -256,19 +247,6 @@ bool nimble_netif_conn_itvl_used(uint16_t itvl, int skip_handle)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nimble_netif_conn_itvl_invalid(int handle)
|
||||
{
|
||||
if (NIMBLE_NETIF_CONN_ITVL_SPACING == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t to_check = nimble_netif_conn_get_itvl(handle);
|
||||
if (to_check == 0) {
|
||||
return false;
|
||||
}
|
||||
return nimble_netif_conn_itvl_used(to_check, handle);
|
||||
}
|
||||
|
||||
uint16_t nimble_netif_conn_gen_itvl(uint16_t min, uint16_t max)
|
||||
{
|
||||
assert(min <= max);
|
||||
|
Loading…
Reference in New Issue
Block a user