1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-14 17:13:50 +01:00

nimble/netif: notify on BLE connection events

This commit is contained in:
Elena Frank 2025-12-09 14:29:28 +01:00
parent 19a4ba04d1
commit 72c65e3a81
4 changed files with 76 additions and 4 deletions

View File

@ -27,6 +27,7 @@
#include "net/ble.h"
#include "net/bluetil/addr.h"
#include "net/gnrc/netapi/notify.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/netif/hdr.h"
#include "net/gnrc/netreg.h"
@ -39,6 +40,7 @@
#include "host/ble_gap.h"
#include "host/util/util.h"
#include "mem/mem.h"
#include <string.h>
#define ENABLE_DEBUG 0
#include "debug.h"
@ -331,6 +333,29 @@ end:
ble_l2cap_recv_ready(event->receive.chan, rxb);
}
/**
* @brief Sends a netapi notification for a connection event.
*
* @param[in] notify The type of notification event.
* @param[in] addr BLE address of the node that (dis-)connected.
*/
static inline void _dispatch_connection_event(netapi_notify_t notify, const void *addr)
{
if (!IS_USED(MODULE_GNRC_NETAPI_NOTIFY)) {
return;
}
netapi_notify_l2_connection_t event = {
.l2addr_len = BLE_ADDR_LEN,
.if_pid = _netif.pid,
};
memcpy(event.l2addr, addr, BLE_ADDR_LEN);
gnrc_netapi_notify(GNRC_NETTYPE_L2_DISCOVERY, GNRC_NETREG_DEMUX_CTX_ALL,
notify, &event, sizeof(netapi_notify_l2_connection_t));
}
static int _on_l2cap_client_evt(struct ble_l2cap_event *event, void *arg)
{
int handle = (int)arg;
@ -349,6 +374,7 @@ static int _on_l2cap_client_evt(struct ble_l2cap_event *event, void *arg)
conn->state |= NIMBLE_NETIF_L2CAP_CLIENT;
conn->state &= ~NIMBLE_NETIF_CONNECTING;
_notify(handle, NIMBLE_NETIF_CONNECTED_MASTER, conn->addr);
_dispatch_connection_event(NETAPI_NOTIFY_L2_NEIGH_CONNECTED, conn->addr);
break;
case BLE_L2CAP_EVENT_COC_DISCONNECTED:
assert(conn->state & NIMBLE_NETIF_L2CAP_CLIENT);
@ -404,6 +430,7 @@ static int _on_l2cap_server_evt(struct ble_l2cap_event *event, void *arg)
}
_notify(handle, NIMBLE_NETIF_CONNECTED_SLAVE, conn->addr);
_dispatch_connection_event(NETAPI_NOTIFY_L2_NEIGH_CONNECTED, conn->addr);
break;
case BLE_L2CAP_EVENT_COC_DISCONNECTED:
conn = nimble_netif_conn_from_gaphandle(event->disconnect.conn_handle);
@ -498,6 +525,7 @@ static int _on_gap_master_evt(struct ble_gap_event *event, void *arg)
nimble_netif_conn_free(handle, addr);
thread_flags_set(_netif_thread, FLAG_TX_NOTCONN);
_notify(handle, type, addr);
_dispatch_connection_event(NETAPI_NOTIFY_L2_NEIGH_DISCONNECTED, addr);
break;
}
case BLE_GAP_EVENT_CONN_UPDATE:
@ -542,6 +570,7 @@ static int _on_gap_slave_evt(struct ble_gap_event *event, void *arg)
nimble_netif_conn_free(handle, addr);
thread_flags_set(_netif_thread, FLAG_TX_NOTCONN);
_notify(handle, type, addr);
_dispatch_connection_event(NETAPI_NOTIFY_L2_NEIGH_DISCONNECTED, addr);
break;
}
case BLE_GAP_EVENT_CONN_UPDATE:

View File

@ -46,7 +46,8 @@ extern "C" {
* be added for parsing the data and calling @ref gnrc_netapi_notify_ack.
*/
typedef enum {
PLACEHOLDER
NETAPI_NOTIFY_L2_NEIGH_CONNECTED, /**< Connection established on layer 2. */
NETAPI_NOTIFY_L2_NEIGH_DISCONNECTED, /**< Connection closed on layer 2. */
} netapi_notify_t;
/**
@ -59,6 +60,16 @@ typedef struct {
sema_inv_t ack; /**< inverse semaphore for collecting ack's */
} gnrc_netapi_notify_t;
/**
* @brief L2 connection event data associated with @ref NETAPI_NOTIFY_L2_NEIGH_CONNECTED or
* @ref NETAPI_NOTIFY_L2_NEIGH_DISCONNECTED events.
*/
typedef struct {
uint8_t l2addr[GNRC_NETIF_L2ADDR_MAXLEN]; /**< L2 address of the node */
uint8_t l2addr_len; /**< length of L2 address in byte */
kernel_pid_t if_pid; /**< PID of network interface */
} netapi_notify_l2_connection_t;
/**
* @brief Acknowledge that a notify event was received and its data read.
*

View File

@ -132,6 +132,13 @@ typedef enum {
* }
*/
/**
* @brief Reports the reachability of link-layer neighbors.
* Connection-oriented links such as BLE can use this to inform
* the IPv6-layer, e.g., about new connected or disconnected nodes
* and their l2 address.
*/
GNRC_NETTYPE_L2_DISCOVERY,
/** @} */
/**

View File

@ -12,18 +12,43 @@
* @author Elena Frank <elena.frank@tu-dresden.de>
*/
#include <assert.h>
#include <errno.h>
#include "net/gnrc/netapi/notify.h"
#include "net/ipv6/addr.h"
int _copy_l2_connection_data(gnrc_netapi_notify_t *notify, netapi_notify_l2_connection_t *data)
{
assert(notify->_data_len == sizeof(netapi_notify_l2_connection_t));
/* Parse event data */
netapi_notify_l2_connection_t *recv_data = notify->_data;
if (recv_data->l2addr_len > GNRC_NETIF_L2ADDR_MAXLEN) {
return -EINVAL;
}
memcpy(data->l2addr, recv_data->l2addr, recv_data->l2addr_len);
data->l2addr_len = recv_data->l2addr_len;
data->if_pid = recv_data->if_pid;
return sizeof(netapi_notify_l2_connection_t);
}
int gnrc_netapi_notify_copy_event_data(gnrc_netapi_notify_t *notify, uint8_t data_len, void *data)
{
(void) data_len;
(void) data;
int res;
switch (notify->event) {
case NETAPI_NOTIFY_L2_NEIGH_CONNECTED:
case NETAPI_NOTIFY_L2_NEIGH_DISCONNECTED:
if (data_len != sizeof(netapi_notify_l2_connection_t)) {
res = -EINVAL;
break;
}
res = _copy_l2_connection_data(notify, data);
break;
default:
res = -EINVAL;
break;