mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
Merge pull request #16932 from benpicco/socket_zep-hal
socket_zep: port to radio HAL
This commit is contained in:
commit
ce8cda2fd8
@ -14,11 +14,4 @@ ifneq (,$(filter periph_can,$(FEATURES_USED)))
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter socket_zep,$(USEMODULE)))
|
|
||||||
USEMODULE += iolist
|
|
||||||
USEMODULE += netdev_ieee802154
|
|
||||||
USEMODULE += checksum
|
|
||||||
USEMODULE += random
|
|
||||||
endif
|
|
||||||
|
|
||||||
USEMODULE += native_drivers
|
USEMODULE += native_drivers
|
||||||
|
@ -30,6 +30,16 @@ ifneq (,$(filter native_cli_eui_provider,$(USEMODULE)))
|
|||||||
USEMODULE += l2util
|
USEMODULE += l2util
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(filter socket_zep,$(USEMODULE)))
|
||||||
|
USEMODULE += iolist
|
||||||
|
USEMODULE += checksum
|
||||||
|
USEMODULE += random
|
||||||
|
USEMODULE += ieee802154
|
||||||
|
ifneq (,$(filter netdev,$(USEMODULE)))
|
||||||
|
USEMODULE += netdev_ieee802154_submac
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
USEMODULE += periph
|
USEMODULE += periph
|
||||||
|
|
||||||
# UART is needed by startup.c
|
# UART is needed by startup.c
|
||||||
|
@ -58,31 +58,13 @@
|
|||||||
|
|
||||||
#include "net/netdev.h"
|
#include "net/netdev.h"
|
||||||
#include "net/netdev/ieee802154.h"
|
#include "net/netdev/ieee802154.h"
|
||||||
|
#include "net/ieee802154/radio.h"
|
||||||
#include "net/zep.h"
|
#include "net/zep.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief ZEP device state
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
netdev_ieee802154_t netdev; /**< netdev internal member */
|
|
||||||
int sock_fd; /**< socket fd */
|
|
||||||
netdev_event_t last_event; /**< event triggered */
|
|
||||||
uint32_t seq; /**< ZEP sequence number */
|
|
||||||
/**
|
|
||||||
* @brief Receive buffer
|
|
||||||
*/
|
|
||||||
uint8_t rcv_buf[sizeof(zep_v2_data_hdr_t) + IEEE802154_FRAME_LEN_MAX];
|
|
||||||
/**
|
|
||||||
* @brief Buffer for send header
|
|
||||||
*/
|
|
||||||
uint8_t snd_hdr_buf[sizeof(zep_v2_data_hdr_t)];
|
|
||||||
uint16_t chksum_buf; /**< buffer for send checksum calculation */
|
|
||||||
} socket_zep_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ZEP device initialization parameters
|
* @brief ZEP device initialization parameters
|
||||||
*/
|
*/
|
||||||
@ -93,15 +75,47 @@ typedef struct {
|
|||||||
char *remote_port; /**< local address string */
|
char *remote_port; /**< local address string */
|
||||||
} socket_zep_params_t;
|
} socket_zep_params_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ZEP device state
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief command line parameters
|
||||||
|
*/
|
||||||
|
const socket_zep_params_t *params;
|
||||||
|
int sock_fd; /**< socket fd */
|
||||||
|
uint32_t seq; /**< ZEP sequence number */
|
||||||
|
/**
|
||||||
|
* @brief Receive buffer
|
||||||
|
*/
|
||||||
|
uint8_t rcv_buf[sizeof(zep_v2_data_hdr_t) + IEEE802154_FRAME_LEN_MAX];
|
||||||
|
/**
|
||||||
|
* @brief Send buffer
|
||||||
|
*/
|
||||||
|
uint8_t snd_buf[sizeof(zep_v2_data_hdr_t) + IEEE802154_FRAME_LEN_MAX];
|
||||||
|
uint8_t snd_len; /**< bytes to send */
|
||||||
|
uint16_t pan_id; /**< PAN ID of the ZEP network */
|
||||||
|
uint16_t chan; /**< virtual radio channel */
|
||||||
|
/**
|
||||||
|
* @brief Short address of the virtual radio
|
||||||
|
*/
|
||||||
|
uint8_t addr_short[IEEE802154_SHORT_ADDRESS_LEN];
|
||||||
|
/**
|
||||||
|
* @brief Long address of the virtual radio
|
||||||
|
*/
|
||||||
|
uint8_t addr_long[IEEE802154_LONG_ADDRESS_LEN];
|
||||||
|
ieee802154_filter_mode_t filter_mode; /**< frame filter mode */
|
||||||
|
ieee802154_trx_state_t state; /**< radio state */
|
||||||
|
bool send_hello; /**< send HELLO packet on connect */
|
||||||
|
} socket_zep_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup socket_zep_t structure
|
* @brief Setup socket_zep_t structure
|
||||||
*
|
*
|
||||||
* @param[in] dev the preallocated socket_zep_t device handle to setup
|
* @param[in] dev the preallocated socket_zep_t device handle to setup
|
||||||
* @param[in] params initialization parameters
|
* @param[in] params initialization parameters
|
||||||
* @param[in] index index of @p params in a global parameter struct array.
|
|
||||||
* If initialized manually, pass a unique identifier instead.
|
|
||||||
*/
|
*/
|
||||||
void socket_zep_setup(socket_zep_t *dev, const socket_zep_params_t *params, uint8_t index);
|
void socket_zep_setup(socket_zep_t *dev, const socket_zep_params_t *params);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Cleanup socket resources
|
* @brief Cleanup socket resources
|
||||||
@ -110,6 +124,14 @@ void socket_zep_setup(socket_zep_t *dev, const socket_zep_params_t *params, uint
|
|||||||
*/
|
*/
|
||||||
void socket_zep_cleanup(socket_zep_t *dev);
|
void socket_zep_cleanup(socket_zep_t *dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Setup socket ZEP in order to be used with the IEEE 802.15.4 Radio HAL
|
||||||
|
*
|
||||||
|
* @param[in] dev pointer to the socket ZEP instance
|
||||||
|
* @param[in] hal pointer to the HAL descriptor associated to the device
|
||||||
|
*/
|
||||||
|
void socket_zep_hal_setup(socket_zep_t *dev, ieee802154_dev_t *hal);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
17
cpu/native/socket_zep/Kconfig
Normal file
17
cpu/native/socket_zep/Kconfig
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
menuconfig MODULE_SOCKET_ZEP
|
||||||
|
bool "Socket-based ZEP"
|
||||||
|
depends on CPU_MODEL_NATIVE
|
||||||
|
depends on TEST_KCONFIG
|
||||||
|
select MODULE_IOLIST
|
||||||
|
select MODULE_CHECKSUM
|
||||||
|
select MODULE_RANDOM
|
||||||
|
select MODULE_IEEE802154
|
||||||
|
help
|
||||||
|
UDP socket-based IEEE 802.15.4 device over ZEP
|
||||||
|
|
||||||
|
config MODULE_SOCKET_ZEP_HELLO
|
||||||
|
bool "Send a dummy HELLO packet on startup"
|
||||||
|
depends on MODULE_SOCKET_ZEP
|
||||||
|
help
|
||||||
|
Say y to send a dummy HELLO packet on startup. This is used to make
|
||||||
|
dispatchers aware of the node.
|
@ -11,6 +11,7 @@
|
|||||||
*
|
*
|
||||||
* @file
|
* @file
|
||||||
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||||
|
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -28,11 +29,11 @@
|
|||||||
#include "byteorder.h"
|
#include "byteorder.h"
|
||||||
#include "checksum/ucrc16.h"
|
#include "checksum/ucrc16.h"
|
||||||
#include "native_internal.h"
|
#include "native_internal.h"
|
||||||
#include "random.h"
|
|
||||||
|
|
||||||
|
#include "net/ieee802154/radio.h"
|
||||||
#include "socket_zep.h"
|
#include "socket_zep.h"
|
||||||
|
|
||||||
#define ENABLE_DEBUG 0
|
#define ENABLE_DEBUG 0
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define _UNIX_NTP_ERA_OFFSET (2208988800U)
|
#define _UNIX_NTP_ERA_OFFSET (2208988800U)
|
||||||
@ -51,10 +52,10 @@ static size_t _zep_hdr_fill_v2_data(socket_zep_t *dev, zep_v2_data_hdr_t *hdr,
|
|||||||
real_gettimeofday(&tv, NULL);
|
real_gettimeofday(&tv, NULL);
|
||||||
hdr->hdr.version = 2;
|
hdr->hdr.version = 2;
|
||||||
hdr->type = ZEP_V2_TYPE_DATA;
|
hdr->type = ZEP_V2_TYPE_DATA;
|
||||||
hdr->chan = dev->netdev.chan;
|
hdr->chan = dev->chan;
|
||||||
hdr->dev = byteorder_htons((uint16_t)((((intptr_t)dev)) & 0xffff));
|
hdr->dev = byteorder_htons((uint16_t)((((intptr_t)dev)) & 0xffff));
|
||||||
hdr->lqi_mode = 1;
|
hdr->lqi_mode = 1;
|
||||||
hdr->lqi_val = 0xff; /* TODO: set */
|
hdr->lqi_val = 0xff; /* set by ZEP dispatcher */
|
||||||
hdr->time.seconds = byteorder_htonl(tv.tv_sec + _UNIX_NTP_ERA_OFFSET);
|
hdr->time.seconds = byteorder_htonl(tv.tv_sec + _UNIX_NTP_ERA_OFFSET);
|
||||||
assert(tv.tv_usec < TV_USEC_PER_SEC);
|
assert(tv.tv_usec < TV_USEC_PER_SEC);
|
||||||
hdr->time.fraction = byteorder_htonl(
|
hdr->time.fraction = byteorder_htonl(
|
||||||
@ -78,62 +79,6 @@ static inline size_t _zep_hdr_fill(socket_zep_t *dev, zep_hdr_t *hdr,
|
|||||||
payload_len);
|
payload_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t _prep_vector(socket_zep_t *dev, const iolist_t *iolist,
|
|
||||||
unsigned n, struct iovec *out)
|
|
||||||
{
|
|
||||||
size_t bytes;
|
|
||||||
dev->chksum_buf = 0;
|
|
||||||
|
|
||||||
bytes = iolist_size(iolist);
|
|
||||||
bytes += sizeof(uint16_t); /* FCS field */
|
|
||||||
out[0].iov_base = &dev->snd_hdr_buf;
|
|
||||||
out[0].iov_len = _zep_hdr_fill(dev, out[0].iov_base, bytes);
|
|
||||||
for (unsigned i = 0; i < n; i++) {
|
|
||||||
/* discard const qualifier, we won't change anything. Promise! */
|
|
||||||
out[i + 1].iov_base = iolist->iol_base;
|
|
||||||
out[i + 1].iov_len = iolist->iol_len;
|
|
||||||
dev->chksum_buf = ucrc16_calc_le(out[i + 1].iov_base, out[i + 1].iov_len,
|
|
||||||
UCRC16_CCITT_POLY_LE, dev->chksum_buf);
|
|
||||||
iolist = iolist->iol_next;
|
|
||||||
}
|
|
||||||
dev->chksum_buf = byteorder_btols(byteorder_htons(dev->chksum_buf)).u16;
|
|
||||||
out[n + 1].iov_base = &dev->chksum_buf;
|
|
||||||
out[n + 1].iov_len = sizeof(uint16_t);
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _send(netdev_t *netdev, const iolist_t *iolist)
|
|
||||||
{
|
|
||||||
netdev_ieee802154_t *netdev_ieee802154 = container_of(netdev, netdev_ieee802154_t, netdev);
|
|
||||||
socket_zep_t *dev = container_of(netdev_ieee802154, socket_zep_t, netdev);
|
|
||||||
unsigned n = iolist_count(iolist);
|
|
||||||
struct iovec v[n + 2];
|
|
||||||
int res;
|
|
||||||
|
|
||||||
assert((dev != NULL) && (dev->sock_fd != 0));
|
|
||||||
_prep_vector(dev, iolist, n, v);
|
|
||||||
DEBUG("socket_zep::send(%p, %p, %u)\n", (void *)netdev, (void *)iolist, n);
|
|
||||||
/* simulate TX_STARTED interrupt */
|
|
||||||
if (netdev->event_callback) {
|
|
||||||
dev->last_event = NETDEV_EVENT_TX_STARTED;
|
|
||||||
netdev_trigger_event_isr(netdev);
|
|
||||||
thread_yield();
|
|
||||||
}
|
|
||||||
res = writev(dev->sock_fd, v, n + 2);
|
|
||||||
if (res < 0) {
|
|
||||||
DEBUG("socket_zep::send: error writing packet: %s\n", strerror(errno));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
/* simulate TX_COMPLETE interrupt */
|
|
||||||
if (netdev->event_callback) {
|
|
||||||
dev->last_event = NETDEV_EVENT_TX_COMPLETE;
|
|
||||||
netdev_trigger_event_isr(netdev);
|
|
||||||
thread_yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
return res - v[0].iov_len - v[n + 1].iov_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _continue_reading(socket_zep_t *dev)
|
static void _continue_reading(socket_zep_t *dev)
|
||||||
{
|
{
|
||||||
/* work around lost signals */
|
/* work around lost signals */
|
||||||
@ -148,8 +93,7 @@ static void _continue_reading(socket_zep_t *dev)
|
|||||||
if (real_select(dev->sock_fd + 1, &rfds, NULL, NULL, &t) == 1) {
|
if (real_select(dev->sock_fd + 1, &rfds, NULL, NULL, &t) == 1) {
|
||||||
int sig = SIGIO;
|
int sig = SIGIO;
|
||||||
extern int _sig_pipefd[2];
|
extern int _sig_pipefd[2];
|
||||||
extern ssize_t (*real_write)(int fd, const void * buf, size_t count);
|
real_write(_sig_pipefd[1], &sig, sizeof(sig));
|
||||||
real_write(_sig_pipefd[1], &sig, sizeof(int));
|
|
||||||
_native_sigpend++;
|
_native_sigpend++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -164,173 +108,44 @@ static inline bool _dst_not_me(socket_zep_t *dev, const void *buf)
|
|||||||
uint8_t dst_addr[IEEE802154_LONG_ADDRESS_LEN] = { 0 };
|
uint8_t dst_addr[IEEE802154_LONG_ADDRESS_LEN] = { 0 };
|
||||||
int dst_len;
|
int dst_len;
|
||||||
le_uint16_t dst_pan = { .u16 = 0 };
|
le_uint16_t dst_pan = { .u16 = 0 };
|
||||||
|
bool is_ack = *(uint8_t *)buf & IEEE802154_FCF_TYPE_ACK;
|
||||||
|
|
||||||
|
/* no need to check address if we are in promiscuous mode */
|
||||||
|
if (dev->filter_mode == IEEE802154_FILTER_PROMISC ||
|
||||||
|
dev->filter_mode == IEEE802154_FILTER_SNIFFER) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ignore everything but ACK frames */
|
||||||
|
if ((dev->filter_mode == IEEE802154_FILTER_ACK_ONLY) && !is_ack) {
|
||||||
|
DEBUG("socket_zep::dst_not_me: ignoring non-ACK frame\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ACKs carry no address */
|
||||||
|
if (is_ack) {
|
||||||
|
DEBUG("socket_zep::dst_not_me: got ACK\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst_len = ieee802154_get_dst(buf, dst_addr, &dst_pan);
|
||||||
|
|
||||||
|
if (dst_pan.u16 != dev->pan_id) {
|
||||||
|
DEBUG("socket_zep::dst_not_me: PAN ID %x != %x\n", dst_pan.u16, dev->pan_id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
dst_len = ieee802154_get_dst(buf, dst_addr,
|
|
||||||
&dst_pan);
|
|
||||||
switch (dst_len) {
|
switch (dst_len) {
|
||||||
case IEEE802154_LONG_ADDRESS_LEN:
|
case IEEE802154_LONG_ADDRESS_LEN:
|
||||||
return memcmp(dst_addr, dev->netdev.long_addr, dst_len) != 0;
|
return memcmp(dst_addr, dev->addr_long, dst_len);
|
||||||
case IEEE802154_SHORT_ADDRESS_LEN:
|
case IEEE802154_SHORT_ADDRESS_LEN:
|
||||||
return (memcmp(dst_addr, ieee802154_addr_bcast, dst_len) != 0) &&
|
return memcmp(dst_addr, ieee802154_addr_bcast, dst_len) &&
|
||||||
(memcmp(dst_addr, dev->netdev.short_addr, dst_len) != 0);
|
memcmp(dst_addr, dev->addr_short, dst_len);
|
||||||
default:
|
default:
|
||||||
return false; /* better safe than sorry ;-) */
|
return false; /* better safe than sorry ;-) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _recv(netdev_t *netdev, void *buf, size_t len, void *info)
|
|
||||||
{
|
|
||||||
netdev_ieee802154_t *netdev_ieee802154 = container_of(netdev, netdev_ieee802154_t, netdev);
|
|
||||||
socket_zep_t *dev = container_of(netdev_ieee802154, socket_zep_t, netdev);
|
|
||||||
int size = 0;
|
|
||||||
|
|
||||||
DEBUG("socket_zep::recv(%p, %p, %u, %p)\n", (void *)netdev, buf,
|
|
||||||
(unsigned)len, (void *)info);
|
|
||||||
if ((buf == NULL) || (len == 0)) {
|
|
||||||
int res = real_ioctl(dev->sock_fd, FIONREAD, &size);
|
|
||||||
|
|
||||||
if (IS_ACTIVE(ENABLE_DEBUG)) {
|
|
||||||
if (res < 0) {
|
|
||||||
DEBUG("socket_zep::recv: error reading FIONREAD: %s",
|
|
||||||
strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
else if (len > 0) {
|
|
||||||
size = real_read(dev->sock_fd, dev->rcv_buf, sizeof(dev->rcv_buf));
|
|
||||||
|
|
||||||
if (size > 0) {
|
|
||||||
zep_hdr_t *tmp = (zep_hdr_t *)&dev->rcv_buf;
|
|
||||||
|
|
||||||
if ((tmp->preamble[0] != 'E') || (tmp->preamble[1] != 'X')) {
|
|
||||||
DEBUG("socket_zep::recv: invalid ZEP header");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
switch (tmp->version) {
|
|
||||||
case 2: {
|
|
||||||
zep_v2_data_hdr_t *zep = (zep_v2_data_hdr_t *)tmp;
|
|
||||||
void *payload = &dev->rcv_buf[sizeof(zep_v2_data_hdr_t)];
|
|
||||||
|
|
||||||
if (zep->type != ZEP_V2_TYPE_DATA) {
|
|
||||||
DEBUG("socket_zep::recv: unexpected ZEP type\n");
|
|
||||||
/* don't support ACK frames for now*/
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (((sizeof(zep_v2_data_hdr_t) + zep->length) != (unsigned)size) ||
|
|
||||||
(zep->length > len) || (zep->chan != dev->netdev.chan) ||
|
|
||||||
/* TODO promiscuous mode */
|
|
||||||
_dst_not_me(dev, payload)) {
|
|
||||||
/* TODO: check checksum */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/* don't hand FCS to stack */
|
|
||||||
size = zep->length - sizeof(uint16_t);
|
|
||||||
if (buf != NULL) {
|
|
||||||
memcpy(buf, payload, size);
|
|
||||||
if (info != NULL) {
|
|
||||||
struct netdev_radio_rx_info *rx_info = info;
|
|
||||||
rx_info->lqi = zep->lqi_val;
|
|
||||||
rx_info->rssi = UINT8_MAX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
DEBUG("socket_zep::recv: unexpected ZEP version\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (size == 0) {
|
|
||||||
DEBUG("socket_zep::recv: ignoring null-event\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if (size == -1) {
|
|
||||||
if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
err(EXIT_FAILURE, "zep: read");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
errx(EXIT_FAILURE, "internal error _rx_event");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_continue_reading(dev);
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _isr(netdev_t *netdev)
|
|
||||||
{
|
|
||||||
if (netdev->event_callback) {
|
|
||||||
netdev_ieee802154_t *netdev_ieee802154 = container_of(netdev, netdev_ieee802154_t, netdev);
|
|
||||||
socket_zep_t *dev = container_of(netdev_ieee802154, socket_zep_t, netdev);
|
|
||||||
|
|
||||||
DEBUG("socket_zep::isr: firing %u\n", (unsigned)dev->last_event);
|
|
||||||
netdev->event_callback(netdev, dev->last_event);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _socket_isr(int fd, void *arg)
|
|
||||||
{
|
|
||||||
(void)fd;
|
|
||||||
(void)arg;
|
|
||||||
netdev_t *netdev = arg;
|
|
||||||
|
|
||||||
DEBUG("socket_zep::_socket_isr: %d, %p (netdev == %p)\n",
|
|
||||||
fd, arg, (void *)netdev);
|
|
||||||
if (netdev == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (netdev->event_callback) {
|
|
||||||
netdev_ieee802154_t *netdev_ieee802154 = container_of(netdev, netdev_ieee802154_t, netdev);
|
|
||||||
socket_zep_t *dev = container_of(netdev_ieee802154, socket_zep_t, netdev);
|
|
||||||
|
|
||||||
dev->last_event = NETDEV_EVENT_RX_COMPLETE;
|
|
||||||
netdev_trigger_event_isr(netdev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _init(netdev_t *netdev)
|
|
||||||
{
|
|
||||||
netdev_ieee802154_t *netdev_ieee802154 = container_of(netdev, netdev_ieee802154_t, netdev);
|
|
||||||
socket_zep_t *dev = container_of(netdev_ieee802154, socket_zep_t, netdev);
|
|
||||||
|
|
||||||
netdev_ieee802154_reset(&dev->netdev);
|
|
||||||
|
|
||||||
assert(dev != NULL);
|
|
||||||
dev->netdev.chan = CONFIG_IEEE802154_DEFAULT_CHANNEL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _get(netdev_t *netdev, netopt_t opt, void *value, size_t max_len)
|
|
||||||
{
|
|
||||||
assert(netdev != NULL);
|
|
||||||
return netdev_ieee802154_get(container_of(netdev, netdev_ieee802154_t, netdev),
|
|
||||||
opt, value, max_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _set(netdev_t *netdev, netopt_t opt, const void *value,
|
|
||||||
size_t value_len)
|
|
||||||
{
|
|
||||||
assert(netdev != NULL);
|
|
||||||
return netdev_ieee802154_set(container_of(netdev, netdev_ieee802154_t, netdev), opt,
|
|
||||||
value, value_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const netdev_driver_t socket_zep_driver = {
|
|
||||||
.send = _send,
|
|
||||||
.recv = _recv,
|
|
||||||
.init = _init,
|
|
||||||
.isr = _isr,
|
|
||||||
.get = _get,
|
|
||||||
.set = _set,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int _bind_local(const socket_zep_params_t *params)
|
static int _bind_local(const socket_zep_params_t *params)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
@ -401,55 +216,46 @@ static int _connect_remote(socket_zep_t *dev, const socket_zep_params_t *params)
|
|||||||
|
|
||||||
static void _send_zep_hello(socket_zep_t *dev)
|
static void _send_zep_hello(socket_zep_t *dev)
|
||||||
{
|
{
|
||||||
if (IS_USED(MODULE_SOCKET_ZEP_HELLO)) {
|
if (IS_USED(MODULE_SOCKET_ZEP_HELLO) && dev->send_hello) {
|
||||||
/* dummy packet */
|
/* dummy packet */
|
||||||
zep_v2_data_hdr_t hdr = {
|
zep_v2_data_hdr_t hdr = {
|
||||||
.hdr.preamble = "EX",
|
.hdr.preamble = "EX",
|
||||||
.hdr.version = 2,
|
.hdr.version = 2,
|
||||||
.type = SOCKET_ZEP_V2_TYPE_HELLO,
|
.type = SOCKET_ZEP_V2_TYPE_HELLO,
|
||||||
.resv = "HELLO",
|
.resv = "HELLO",
|
||||||
.length = sizeof(dev->netdev.long_addr),
|
.length = sizeof(dev->addr_long),
|
||||||
};
|
};
|
||||||
|
|
||||||
/* append HW addr */
|
/* append HW addr */
|
||||||
real_send(dev->sock_fd, &hdr, sizeof(hdr), MSG_MORE);
|
real_send(dev->sock_fd, &hdr, sizeof(hdr), MSG_MORE);
|
||||||
real_send(dev->sock_fd, dev->netdev.long_addr, sizeof(dev->netdev.long_addr), 0);
|
real_send(dev->sock_fd, dev->addr_long, sizeof(dev->addr_long), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void socket_zep_setup(socket_zep_t *dev, const socket_zep_params_t *params, uint8_t index)
|
static void _socket_isr(int fd, void *arg)
|
||||||
{
|
{
|
||||||
int res;
|
ieee802154_dev_t *dev = arg;
|
||||||
|
socket_zep_t *zepdev = dev->priv;
|
||||||
|
|
||||||
|
DEBUG("socket_zep::_socket_isr: bytes on %d\n", fd);
|
||||||
|
|
||||||
|
if (zepdev->state == IEEE802154_TRX_STATE_RX_ON) {
|
||||||
|
dev->cb(dev, IEEE802154_RADIO_INDICATION_RX_DONE);
|
||||||
|
} else {
|
||||||
|
/* discard frame */
|
||||||
|
uint8_t tmp;
|
||||||
|
real_read(fd, &tmp, sizeof(tmp));
|
||||||
|
_continue_reading(zepdev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void socket_zep_setup(socket_zep_t *dev, const socket_zep_params_t *params)
|
||||||
|
{
|
||||||
DEBUG("socket_zep_setup(%p, %p)\n", (void *)dev, (void *)params);
|
DEBUG("socket_zep_setup(%p, %p)\n", (void *)dev, (void *)params);
|
||||||
assert((params->remote_addr != NULL) && (params->remote_port != NULL));
|
assert((params->remote_addr != NULL) && (params->remote_port != NULL));
|
||||||
|
|
||||||
memset(dev, 0, sizeof(socket_zep_t));
|
dev->params = params;
|
||||||
dev->netdev.netdev.driver = &socket_zep_driver;
|
|
||||||
|
|
||||||
netdev_register(&dev->netdev.netdev, NETDEV_SOCKET_ZEP, index);
|
|
||||||
|
|
||||||
res = _bind_local(params);
|
|
||||||
|
|
||||||
if (res < 0) {
|
|
||||||
dev->sock_fd = socket(AF_INET6, SOCK_DGRAM, 0);
|
|
||||||
} else {
|
|
||||||
dev->sock_fd = res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* only send hello if we are connected to a remote */
|
|
||||||
bool send_hello = !_connect_remote(dev, params);
|
|
||||||
|
|
||||||
/* setup hardware address */
|
|
||||||
netdev_ieee802154_setup(&dev->netdev);
|
|
||||||
|
|
||||||
/* send dummy data to connect to dispatcher */
|
|
||||||
if (send_hello) {
|
|
||||||
_send_zep_hello(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
native_async_read_setup();
|
native_async_read_setup();
|
||||||
native_async_read_add_handler(dev->sock_fd, dev, _socket_isr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void socket_zep_cleanup(socket_zep_t *dev)
|
void socket_zep_cleanup(socket_zep_t *dev)
|
||||||
@ -462,4 +268,355 @@ void socket_zep_cleanup(socket_zep_t *dev)
|
|||||||
dev->sock_fd = 0;
|
dev->sock_fd = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _request_on(ieee802154_dev_t *dev)
|
||||||
|
{
|
||||||
|
socket_zep_t *zepdev = dev->priv;
|
||||||
|
|
||||||
|
DEBUG("socket_zep::request_on()\n");
|
||||||
|
|
||||||
|
int res = _bind_local(zepdev->params);
|
||||||
|
|
||||||
|
if (res < 0) {
|
||||||
|
zepdev->sock_fd = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||||
|
res = zepdev->sock_fd;
|
||||||
|
} else {
|
||||||
|
zepdev->sock_fd = res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res < 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
native_async_read_add_handler(zepdev->sock_fd, dev, _socket_isr);
|
||||||
|
|
||||||
|
/* only send hello if we are connected to a remote */
|
||||||
|
zepdev->send_hello = !_connect_remote(zepdev, zepdev->params);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _confirm_on(ieee802154_dev_t *dev)
|
||||||
|
{
|
||||||
|
(void) dev;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _off(ieee802154_dev_t *dev)
|
||||||
|
{
|
||||||
|
socket_zep_t *zepdev = dev->priv;
|
||||||
|
|
||||||
|
DEBUG("socket_zep::off()\n");
|
||||||
|
|
||||||
|
close(zepdev->sock_fd);
|
||||||
|
zepdev->sock_fd = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _set_cca_mode(ieee802154_dev_t *dev, ieee802154_cca_mode_t mode)
|
||||||
|
{
|
||||||
|
(void) dev;
|
||||||
|
(void) mode;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _request_cca(ieee802154_dev_t *dev)
|
||||||
|
{
|
||||||
|
(void) dev;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _confirm_cca(ieee802154_dev_t *dev)
|
||||||
|
{
|
||||||
|
(void) dev;
|
||||||
|
assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _set_cca_threshold(ieee802154_dev_t *dev, int8_t threshold)
|
||||||
|
{
|
||||||
|
(void) dev;
|
||||||
|
(void) threshold;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _set_csma_params(ieee802154_dev_t *dev, const ieee802154_csma_be_t *bd,
|
||||||
|
int8_t retries)
|
||||||
|
{
|
||||||
|
(void) dev;
|
||||||
|
(void) bd;
|
||||||
|
(void) retries;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _config_phy(ieee802154_dev_t *dev, const ieee802154_phy_conf_t *conf)
|
||||||
|
{
|
||||||
|
(void) dev;
|
||||||
|
(void) conf;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _config_addr_filter(ieee802154_dev_t *dev, ieee802154_af_cmd_t cmd, const void *value)
|
||||||
|
{
|
||||||
|
socket_zep_t *zepdev = dev->priv;
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case IEEE802154_AF_SHORT_ADDR:
|
||||||
|
memcpy(zepdev->addr_short, value, IEEE802154_SHORT_ADDRESS_LEN);
|
||||||
|
break;
|
||||||
|
case IEEE802154_AF_EXT_ADDR:
|
||||||
|
memcpy(zepdev->addr_long, value, IEEE802154_LONG_ADDRESS_LEN);
|
||||||
|
_send_zep_hello(zepdev);
|
||||||
|
break;
|
||||||
|
case IEEE802154_AF_PANID:
|
||||||
|
memcpy(&zepdev->pan_id, value, sizeof(zepdev->pan_id));
|
||||||
|
break;
|
||||||
|
case IEEE802154_AF_PAN_COORD:
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _config_src_addr_match(ieee802154_dev_t *dev, ieee802154_src_match_t cmd,
|
||||||
|
const void *value)
|
||||||
|
{
|
||||||
|
(void) dev;
|
||||||
|
(void) cmd;
|
||||||
|
(void) value;
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _set_frame_filter_mode(ieee802154_dev_t *dev, ieee802154_filter_mode_t mode)
|
||||||
|
{
|
||||||
|
socket_zep_t *zepdev = dev->priv;
|
||||||
|
zepdev->filter_mode = mode;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _request_set_trx_state(ieee802154_dev_t *dev, ieee802154_trx_state_t state)
|
||||||
|
{
|
||||||
|
socket_zep_t *zepdev = dev->priv;
|
||||||
|
zepdev->state = state;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _confirm_set_trx_state(ieee802154_dev_t *dev)
|
||||||
|
{
|
||||||
|
(void) dev;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _write(ieee802154_dev_t *dev, const iolist_t *iolist)
|
||||||
|
{
|
||||||
|
socket_zep_t *zepdev = dev->priv;
|
||||||
|
unsigned n = iolist_count(iolist);
|
||||||
|
size_t bytes = iolist_size(iolist) + sizeof(uint16_t); /* FCS field */
|
||||||
|
uint8_t *out = zepdev->snd_buf;
|
||||||
|
uint16_t chksum = 0;
|
||||||
|
|
||||||
|
DEBUG("socket_zep::write(%zu bytes)\n", bytes);
|
||||||
|
|
||||||
|
out += _zep_hdr_fill(zepdev, (void *)out, bytes);
|
||||||
|
|
||||||
|
/* make sure we are not overflowing the TX buffer */
|
||||||
|
if (out + bytes > zepdev->snd_buf + sizeof(zepdev->snd_buf)) {
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < n; i++) {
|
||||||
|
memcpy(out, iolist->iol_base, iolist->iol_len);
|
||||||
|
chksum = ucrc16_calc_le(iolist->iol_base, iolist->iol_len,
|
||||||
|
UCRC16_CCITT_POLY_LE, chksum);
|
||||||
|
out += iolist->iol_len;
|
||||||
|
iolist = iolist->iol_next;
|
||||||
|
}
|
||||||
|
chksum = byteorder_htols(chksum).u16;
|
||||||
|
memcpy(out, &chksum, sizeof(chksum));
|
||||||
|
out += sizeof(chksum);
|
||||||
|
|
||||||
|
zepdev->snd_len = out - zepdev->snd_buf;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _request_transmit(ieee802154_dev_t *dev)
|
||||||
|
{
|
||||||
|
socket_zep_t *zepdev = dev->priv;
|
||||||
|
|
||||||
|
DEBUG("socket_zep::request_transmit(%zu bytes)\n", zepdev->snd_len);
|
||||||
|
|
||||||
|
dev->cb(dev, IEEE802154_RADIO_INDICATION_TX_START);
|
||||||
|
|
||||||
|
int res = real_write(zepdev->sock_fd, zepdev->snd_buf, zepdev->snd_len);
|
||||||
|
|
||||||
|
dev->cb(dev, IEEE802154_RADIO_CONFIRM_TX_DONE);
|
||||||
|
|
||||||
|
if (res < 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _confirm_transmit(ieee802154_dev_t *dev, ieee802154_tx_info_t *info)
|
||||||
|
{
|
||||||
|
(void) dev;
|
||||||
|
|
||||||
|
if (info) {
|
||||||
|
info->status = TX_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _len(ieee802154_dev_t *dev)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
socket_zep_t *zepdev = dev->priv;
|
||||||
|
|
||||||
|
int res = real_ioctl(zepdev->sock_fd, FIONREAD, &size);
|
||||||
|
if (res < 0) {
|
||||||
|
DEBUG("socket_zep::len: error reading FIONREAD: %s", strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG("socket_zep::len %zu bytes on %d\n", size, zepdev->sock_fd);
|
||||||
|
|
||||||
|
if (size < sizeof(zep_v2_data_hdr_t)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* report size without ZEP header and checksum */
|
||||||
|
return size - (sizeof(zep_v2_data_hdr_t) + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _send_ack(socket_zep_t *zepdev, const void *frame)
|
||||||
|
{
|
||||||
|
const uint8_t *rxbuf = frame;
|
||||||
|
uint8_t ack[3];
|
||||||
|
zep_v2_data_hdr_t hdr;
|
||||||
|
|
||||||
|
if ((rxbuf[0] & IEEE802154_FCF_ACK_REQ) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG("socket_zep::send_ack: seq_no: %u\n", rxbuf[2]);
|
||||||
|
|
||||||
|
_zep_hdr_fill(zepdev, &hdr.hdr, sizeof(ack) + 2);
|
||||||
|
|
||||||
|
ack[0] = IEEE802154_FCF_TYPE_ACK; /* FCF */
|
||||||
|
ack[1] = 0; /* FCF */
|
||||||
|
ack[2] = rxbuf[2]; /* SeqNum */
|
||||||
|
|
||||||
|
/* calculate checksum */
|
||||||
|
uint16_t chksum = ucrc16_calc_le(ack, 3, UCRC16_CCITT_POLY_LE, 0);
|
||||||
|
|
||||||
|
real_send(zepdev->sock_fd, &hdr, sizeof(hdr), MSG_MORE);
|
||||||
|
real_send(zepdev->sock_fd, ack, sizeof(ack), MSG_MORE);
|
||||||
|
real_send(zepdev->sock_fd, &chksum, sizeof(chksum), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _read(ieee802154_dev_t *dev, void *buf, size_t max_size,
|
||||||
|
ieee802154_rx_info_t *info)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
socket_zep_t *zepdev = dev->priv;
|
||||||
|
|
||||||
|
DEBUG("socket_zep::read: reading up to %u bytes into %p\n", max_size, buf);
|
||||||
|
|
||||||
|
if (max_size + sizeof(zep_v2_data_hdr_t) > sizeof(zepdev->rcv_buf)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = real_read(zepdev->sock_fd, zepdev->rcv_buf, max_size + sizeof(zep_v2_data_hdr_t));
|
||||||
|
|
||||||
|
DEBUG("socket_zep::read: got %d bytes\n", res);
|
||||||
|
|
||||||
|
if (res <= (int)sizeof(zep_v2_data_hdr_t)) {
|
||||||
|
res = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
zep_hdr_t *tmp = (zep_hdr_t *)zepdev->rcv_buf;
|
||||||
|
|
||||||
|
if ((tmp->preamble[0] != 'E') || (tmp->preamble[1] != 'X')) {
|
||||||
|
DEBUG("socket_zep::read: invalid ZEP header\n");
|
||||||
|
res = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp->version != 2) {
|
||||||
|
DEBUG("socket_zep::read: unsupported ZEP version %u\n", tmp->version);
|
||||||
|
res = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (((zep_v2_ack_hdr_t *)tmp)->type) {
|
||||||
|
case ZEP_V2_TYPE_DATA: {
|
||||||
|
zep_v2_data_hdr_t *zep = (zep_v2_data_hdr_t *)tmp;
|
||||||
|
|
||||||
|
if (info) {
|
||||||
|
info->lqi = zep->lqi_val;
|
||||||
|
info->rssi = -IEEE802154_RADIO_RSSI_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_dst_not_me(zepdev, zep + 1)) {
|
||||||
|
DEBUG("socket_zep::read: dst not me\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_send_ack(zepdev, zep + 1);
|
||||||
|
|
||||||
|
memcpy(buf, zep + 1, max_size);
|
||||||
|
res = max_size;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
DEBUG("socket_zep::read: unknown type %u\n", ((zep_v2_ack_hdr_t *)tmp)->type);
|
||||||
|
res = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
_continue_reading(zepdev);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const ieee802154_radio_ops_t socket_zep_rf_ops = {
|
||||||
|
.caps = IEEE802154_CAP_24_GHZ
|
||||||
|
| IEEE802154_CAP_AUTO_CSMA
|
||||||
|
| IEEE802154_CAP_IRQ_TX_DONE
|
||||||
|
| IEEE802154_CAP_IRQ_TX_START
|
||||||
|
| IEEE802154_CAP_PHY_OQPSK
|
||||||
|
| IEEE802154_CAP_RX_CONTINUOUS,
|
||||||
|
|
||||||
|
.write = _write,
|
||||||
|
.read = _read,
|
||||||
|
.request_transmit = _request_transmit,
|
||||||
|
.confirm_transmit = _confirm_transmit,
|
||||||
|
.len = _len,
|
||||||
|
.off = _off,
|
||||||
|
.request_on = _request_on,
|
||||||
|
.confirm_on = _confirm_on,
|
||||||
|
.request_set_trx_state = _request_set_trx_state,
|
||||||
|
.confirm_set_trx_state = _confirm_set_trx_state,
|
||||||
|
.request_cca = _request_cca,
|
||||||
|
.confirm_cca = _confirm_cca,
|
||||||
|
.set_cca_threshold = _set_cca_threshold,
|
||||||
|
.set_cca_mode = _set_cca_mode,
|
||||||
|
.config_phy = _config_phy,
|
||||||
|
.config_addr_filter = _config_addr_filter,
|
||||||
|
.config_src_addr_match = _config_src_addr_match,
|
||||||
|
.set_csma_params = _set_csma_params,
|
||||||
|
.set_frame_filter_mode = _set_frame_filter_mode,
|
||||||
|
};
|
||||||
|
|
||||||
|
void socket_zep_hal_setup(socket_zep_t *dev, ieee802154_dev_t *hal)
|
||||||
|
{
|
||||||
|
hal->driver = &socket_zep_rf_ops;
|
||||||
|
hal->priv = dev;
|
||||||
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -18,6 +18,7 @@ rsource "ncv7356/Kconfig"
|
|||||||
rsource "pn532/Kconfig"
|
rsource "pn532/Kconfig"
|
||||||
rsource "rn2xx3/Kconfig"
|
rsource "rn2xx3/Kconfig"
|
||||||
rsource "slipdev/Kconfig"
|
rsource "slipdev/Kconfig"
|
||||||
|
rsource "$(RIOTCPU)/native/socket_zep/Kconfig"
|
||||||
rsource "sx126x/Kconfig"
|
rsource "sx126x/Kconfig"
|
||||||
rsource "sx127x/Kconfig"
|
rsource "sx127x/Kconfig"
|
||||||
rsource "tja1042/Kconfig"
|
rsource "tja1042/Kconfig"
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "socket_zep.h"
|
#include "socket_zep.h"
|
||||||
#include "socket_zep_params.h"
|
#include "socket_zep_params.h"
|
||||||
|
#include "net/netdev/ieee802154_submac.h"
|
||||||
|
|
||||||
#include "lwip_init_devs.h"
|
#include "lwip_init_devs.h"
|
||||||
|
|
||||||
@ -29,12 +30,18 @@
|
|||||||
|
|
||||||
static struct netif netif[NETIF_SOCKET_ZEP_NUMOF];
|
static struct netif netif[NETIF_SOCKET_ZEP_NUMOF];
|
||||||
static socket_zep_t socket_zep_devs[NETIF_SOCKET_ZEP_NUMOF];
|
static socket_zep_t socket_zep_devs[NETIF_SOCKET_ZEP_NUMOF];
|
||||||
|
static netdev_ieee802154_submac_t socket_zep_netdev[SOCKET_ZEP_MAX];
|
||||||
|
|
||||||
static void auto_init_socket_zep(void)
|
static void auto_init_socket_zep(void)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < NETIF_SOCKET_ZEP_NUMOF; i++) {
|
for (unsigned i = 0; i < NETIF_SOCKET_ZEP_NUMOF; i++) {
|
||||||
socket_zep_setup(&socket_zep_devs[i], &socket_zep_params[i], i);
|
netdev_register(&socket_zep_netdev[i].dev.netdev, NETDEV_SOCKET_ZEP, i);
|
||||||
if (lwip_add_6lowpan(&netif[i], &socket_zep_devs[i].netdev.netdev) == NULL) {
|
netdev_ieee802154_submac_init(&socket_zep_netdev[i]);
|
||||||
|
socket_zep_hal_setup(&socket_zep_devs[i], &socket_zep_netdev[i].submac.dev);
|
||||||
|
|
||||||
|
socket_zep_setup(&socket_zep_devs[i], &socket_zep_params[i]);
|
||||||
|
|
||||||
|
if (lwip_add_6lowpan(&netif[i], &socket_zep_netdev[i].dev.netdev) == NULL) {
|
||||||
DEBUG("Could not add socket_zep device\n");
|
DEBUG("Could not add socket_zep device\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "socket_zep_params.h"
|
#include "socket_zep_params.h"
|
||||||
#include "net/gnrc/netif/ieee802154.h"
|
#include "net/gnrc/netif/ieee802154.h"
|
||||||
#include "include/init_devs.h"
|
#include "include/init_devs.h"
|
||||||
|
#include "net/netdev/ieee802154_submac.h"
|
||||||
|
|
||||||
#define ENABLE_DEBUG 0
|
#define ENABLE_DEBUG 0
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
@ -40,17 +41,22 @@
|
|||||||
static char _socket_zep_stacks[SOCKET_ZEP_MAX][SOCKET_ZEP_MAC_STACKSIZE];
|
static char _socket_zep_stacks[SOCKET_ZEP_MAX][SOCKET_ZEP_MAC_STACKSIZE];
|
||||||
static socket_zep_t _socket_zeps[SOCKET_ZEP_MAX];
|
static socket_zep_t _socket_zeps[SOCKET_ZEP_MAX];
|
||||||
static gnrc_netif_t _netif[SOCKET_ZEP_MAX];
|
static gnrc_netif_t _netif[SOCKET_ZEP_MAX];
|
||||||
|
static netdev_ieee802154_submac_t _socket_zep_netdev[SOCKET_ZEP_MAX];
|
||||||
|
|
||||||
void auto_init_socket_zep(void)
|
void auto_init_socket_zep(void)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < SOCKET_ZEP_MAX; i++) {
|
for (int i = 0; i < SOCKET_ZEP_MAX; i++) {
|
||||||
LOG_DEBUG("[auto_init_netif: initializing socket ZEP device #%u\n", i);
|
LOG_DEBUG("[auto_init_netif: initializing socket ZEP device #%u\n", i);
|
||||||
/* setup netdev device */
|
/* setup netdev device */
|
||||||
socket_zep_setup(&_socket_zeps[i], &socket_zep_params[i], i);
|
netdev_register(&_socket_zep_netdev[i].dev.netdev, NETDEV_SOCKET_ZEP, i);
|
||||||
|
netdev_ieee802154_submac_init(&_socket_zep_netdev[i]);
|
||||||
|
socket_zep_hal_setup(&_socket_zeps[i], &_socket_zep_netdev[i].submac.dev);
|
||||||
|
|
||||||
|
socket_zep_setup(&_socket_zeps[i], &socket_zep_params[i]);
|
||||||
gnrc_netif_ieee802154_create(&_netif[i], _socket_zep_stacks[i],
|
gnrc_netif_ieee802154_create(&_netif[i], _socket_zep_stacks[i],
|
||||||
SOCKET_ZEP_MAC_STACKSIZE,
|
SOCKET_ZEP_MAC_STACKSIZE,
|
||||||
SOCKET_ZEP_MAC_PRIO, "socket_zep",
|
SOCKET_ZEP_MAC_PRIO, "socket_zep",
|
||||||
&_socket_zeps[i].netdev.netdev);
|
&_socket_zep_netdev[i].dev.netdev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -406,6 +406,10 @@ int ieee802154_send(ieee802154_submac_t *submac, const iolist_t *iolist)
|
|||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (iolist == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t *buf = iolist->iol_base;
|
uint8_t *buf = iolist->iol_base;
|
||||||
bool cnf = buf[0] & IEEE802154_FCF_ACK_REQ;
|
bool cnf = buf[0] & IEEE802154_FCF_ACK_REQ;
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ TERMFLAGS ?= -z "0.0.0.0:17755,localhost:17754"
|
|||||||
|
|
||||||
USEMODULE += socket_zep
|
USEMODULE += socket_zep
|
||||||
USEMODULE += auto_init_gnrc_netif
|
USEMODULE += auto_init_gnrc_netif
|
||||||
|
USEMODULE += netdev
|
||||||
USEMODULE += gnrc
|
USEMODULE += gnrc
|
||||||
USEMODULE += gnrc_netif_ieee802154
|
USEMODULE += gnrc_netif_ieee802154
|
||||||
USEMODULE += gnrc_pktdump
|
USEMODULE += gnrc_pktdump
|
||||||
|
@ -6,6 +6,7 @@ BOARD_WHITELIST := \
|
|||||||
arduino-nano-33-ble \
|
arduino-nano-33-ble \
|
||||||
cc2538dk \
|
cc2538dk \
|
||||||
feather-nrf52840 \
|
feather-nrf52840 \
|
||||||
|
native \
|
||||||
nrf52840dk \
|
nrf52840dk \
|
||||||
nrf52840dongle \
|
nrf52840dongle \
|
||||||
nrf52840-mdk \
|
nrf52840-mdk \
|
||||||
@ -19,6 +20,16 @@ BOARD_WHITELIST := \
|
|||||||
|
|
||||||
DISABLE_MODULE += auto_init_at86rf2xx auto_init_nrf802154
|
DISABLE_MODULE += auto_init_at86rf2xx auto_init_nrf802154
|
||||||
|
|
||||||
|
ifeq ($(BOARD), native)
|
||||||
|
ZEP_PORT_BASE ?= 17754
|
||||||
|
TERMFLAGS += -z [::1]:$(ZEP_PORT_BASE)
|
||||||
|
USEMODULE += socket_zep
|
||||||
|
# the same for Kconfig
|
||||||
|
ifeq (1,$(TEST_KCONFIG))
|
||||||
|
KCONFIG_ADD_CONFIG += $(APPDIR)/app.config.test.native
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
USEMODULE += od
|
USEMODULE += od
|
||||||
USEMODULE += luid
|
USEMODULE += luid
|
||||||
USEMODULE += l2util
|
USEMODULE += l2util
|
||||||
|
6
tests/ieee802154_hal/app.config.test.native
Normal file
6
tests/ieee802154_hal/app.config.test.native
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
CONFIG_MODULE_SOCKET_ZEP=y
|
||||||
|
|
||||||
|
# Should be autoselecting the MODULE_PRNG_HWRNG if possible
|
||||||
|
# Since the makefile cannot we have to override until end of migration
|
||||||
|
# Remove when TEST_KCONFIG is complete
|
||||||
|
CONFIG_MODULE_PRNG_TINYMT32=y
|
@ -19,9 +19,15 @@
|
|||||||
#define COMMON_H
|
#define COMMON_H
|
||||||
|
|
||||||
#include "net/ieee802154/radio.h"
|
#include "net/ieee802154/radio.h"
|
||||||
|
#if IS_USED(MODULE_SOCKET_ZEP)
|
||||||
|
#include "socket_zep_params.h"
|
||||||
|
#else
|
||||||
|
#define SOCKET_ZEP_MAX 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define RADIOS_NUMOF IS_USED(MODULE_CC2538_RF) + \
|
#define RADIOS_NUMOF IS_USED(MODULE_CC2538_RF) + \
|
||||||
IS_USED(MODULE_NRF802154)
|
IS_USED(MODULE_NRF802154) + \
|
||||||
|
SOCKET_ZEP_MAX
|
||||||
|
|
||||||
#if RADIOS_NUMOF == 0
|
#if RADIOS_NUMOF == 0
|
||||||
#error "Radio is not supported"
|
#error "Radio is not supported"
|
||||||
@ -39,6 +45,7 @@ extern "C" {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
IEEE802154_DEV_TYPE_CC2538_RF,
|
IEEE802154_DEV_TYPE_CC2538_RF,
|
||||||
IEEE802154_DEV_TYPE_NRF802154,
|
IEEE802154_DEV_TYPE_NRF802154,
|
||||||
|
IEEE802154_DEV_TYPE_SOCKET_ZEP,
|
||||||
} ieee802154_dev_type_t;
|
} ieee802154_dev_type_t;
|
||||||
|
|
||||||
typedef ieee802154_dev_t* (*ieee802154_dev_cb_t)(ieee802154_dev_type_t type,
|
typedef ieee802154_dev_t* (*ieee802154_dev_cb_t)(ieee802154_dev_type_t type,
|
||||||
|
@ -31,6 +31,11 @@
|
|||||||
#include "nrf802154.h"
|
#include "nrf802154.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODULE_SOCKET_ZEP
|
||||||
|
#include "socket_zep.h"
|
||||||
|
#include "socket_zep_params.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
void ieee802154_hal_test_init_devs(ieee802154_dev_cb_t cb, void *opaque)
|
void ieee802154_hal_test_init_devs(ieee802154_dev_cb_t cb, void *opaque)
|
||||||
{
|
{
|
||||||
/* Call the init function of the device (this should be handled by
|
/* Call the init function of the device (this should be handled by
|
||||||
@ -50,4 +55,12 @@ void ieee802154_hal_test_init_devs(ieee802154_dev_cb_t cb, void *opaque)
|
|||||||
nrf802154_init();
|
nrf802154_init();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODULE_SOCKET_ZEP
|
||||||
|
static socket_zep_t _socket_zeps[SOCKET_ZEP_MAX];
|
||||||
|
if ((radio = cb(IEEE802154_DEV_TYPE_SOCKET_ZEP, opaque)) ){
|
||||||
|
socket_zep_hal_setup(&_socket_zeps[0], radio);
|
||||||
|
socket_zep_setup(&_socket_zeps[0], &socket_zep_params[0]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -248,6 +248,9 @@ static ieee802154_dev_t *_reg_callback(ieee802154_dev_type_t type, void *opaque)
|
|||||||
case IEEE802154_DEV_TYPE_NRF802154:
|
case IEEE802154_DEV_TYPE_NRF802154:
|
||||||
printf("nrf52840");
|
printf("nrf52840");
|
||||||
break;
|
break;
|
||||||
|
case IEEE802154_DEV_TYPE_SOCKET_ZEP:
|
||||||
|
printf("socket_zep");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
puts(".");
|
puts(".");
|
||||||
|
@ -6,6 +6,7 @@ BOARD_WHITELIST := \
|
|||||||
arduino-nano-33-ble \
|
arduino-nano-33-ble \
|
||||||
cc2538dk \
|
cc2538dk \
|
||||||
feather-nrf52840 \
|
feather-nrf52840 \
|
||||||
|
native \
|
||||||
nrf52840dk \
|
nrf52840dk \
|
||||||
nrf52840dongle \
|
nrf52840dongle \
|
||||||
nrf52840-mdk \
|
nrf52840-mdk \
|
||||||
@ -29,6 +30,12 @@ USEMODULE += ieee802154
|
|||||||
USEMODULE += ieee802154_submac
|
USEMODULE += ieee802154_submac
|
||||||
USEMODULE += ztimer_usec
|
USEMODULE += ztimer_usec
|
||||||
|
|
||||||
|
ifeq ($(BOARD), native)
|
||||||
|
ZEP_PORT_BASE ?= 17754
|
||||||
|
TERMFLAGS += -z [::1]:$(ZEP_PORT_BASE)
|
||||||
|
USEMODULE += socket_zep
|
||||||
|
endif
|
||||||
|
|
||||||
CFLAGS += -DEVENT_THREAD_MEDIUM_STACKSIZE=1024
|
CFLAGS += -DEVENT_THREAD_MEDIUM_STACKSIZE=1024
|
||||||
|
|
||||||
include $(RIOTBASE)/Makefile.include
|
include $(RIOTBASE)/Makefile.include
|
||||||
|
@ -187,6 +187,9 @@ static ieee802154_dev_t *_reg_callback(ieee802154_dev_type_t type, void *opaque)
|
|||||||
case IEEE802154_DEV_TYPE_NRF802154:
|
case IEEE802154_DEV_TYPE_NRF802154:
|
||||||
printf("nrf52840");
|
printf("nrf52840");
|
||||||
break;
|
break;
|
||||||
|
case IEEE802154_DEV_TYPE_SOCKET_ZEP:
|
||||||
|
printf("socket_zep");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
puts(".");
|
puts(".");
|
||||||
|
@ -8,6 +8,7 @@ TEST_ON_CI_BLACKLIST += native
|
|||||||
|
|
||||||
USEMODULE += od
|
USEMODULE += od
|
||||||
USEMODULE += socket_zep
|
USEMODULE += socket_zep
|
||||||
|
USEMODULE += netdev
|
||||||
|
|
||||||
TERMFLAGS ?= -z [::1]:17754
|
TERMFLAGS ?= -z [::1]:17754
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "byteorder.h"
|
#include "byteorder.h"
|
||||||
#include "net/ieee802154.h"
|
#include "net/ieee802154.h"
|
||||||
|
#include "net/netdev/ieee802154_submac.h"
|
||||||
#include "sched.h"
|
#include "sched.h"
|
||||||
#include "socket_zep.h"
|
#include "socket_zep.h"
|
||||||
#include "socket_zep_params.h"
|
#include "socket_zep_params.h"
|
||||||
@ -40,6 +41,7 @@
|
|||||||
static uint8_t _recvbuf[RECVBUF_SIZE];
|
static uint8_t _recvbuf[RECVBUF_SIZE];
|
||||||
static msg_t _msg_queue[MSG_QUEUE_SIZE];
|
static msg_t _msg_queue[MSG_QUEUE_SIZE];
|
||||||
static socket_zep_t _dev;
|
static socket_zep_t _dev;
|
||||||
|
static netdev_ieee802154_submac_t _socket_zep_netdev;
|
||||||
static kernel_pid_t _main_pid;
|
static kernel_pid_t _main_pid;
|
||||||
|
|
||||||
static void _event_cb(netdev_t *dev, netdev_event_t event);
|
static void _event_cb(netdev_t *dev, netdev_event_t event);
|
||||||
@ -48,11 +50,14 @@ static void _print_info(netdev_t *netdev);
|
|||||||
static void test_init(void)
|
static void test_init(void)
|
||||||
{
|
{
|
||||||
const socket_zep_params_t *p = &socket_zep_params[0];
|
const socket_zep_params_t *p = &socket_zep_params[0];
|
||||||
netdev_t *netdev = &_dev.netdev.netdev;
|
netdev_t *netdev = &_socket_zep_netdev.dev.netdev;
|
||||||
|
|
||||||
printf("Initializing socket ZEP with (local: [%s]:%s, remote: [%s]:%s)\n",
|
printf("Initializing socket ZEP with (local: [%s]:%s, remote: [%s]:%s)\n",
|
||||||
p->local_addr, p->local_port, p->remote_addr, p->remote_port);
|
p->local_addr, p->local_port, p->remote_addr, p->remote_port);
|
||||||
socket_zep_setup(&_dev, p, 0);
|
netdev_register(&_socket_zep_netdev.dev.netdev, NETDEV_SOCKET_ZEP, 0);
|
||||||
|
netdev_ieee802154_submac_init(&_socket_zep_netdev);
|
||||||
|
socket_zep_hal_setup(&_dev, &_socket_zep_netdev.submac.dev);
|
||||||
|
socket_zep_setup(&_dev, p);
|
||||||
netdev->event_callback = _event_cb;
|
netdev->event_callback = _event_cb;
|
||||||
expect(netdev->driver->init(netdev) >= 0);
|
expect(netdev->driver->init(netdev) >= 0);
|
||||||
_print_info(netdev);
|
_print_info(netdev);
|
||||||
@ -60,7 +65,7 @@ static void test_init(void)
|
|||||||
|
|
||||||
static void test_send__iolist_NULL(void)
|
static void test_send__iolist_NULL(void)
|
||||||
{
|
{
|
||||||
netdev_t *netdev = &_dev.netdev.netdev;
|
netdev_t *netdev = &_socket_zep_netdev.dev.netdev;
|
||||||
|
|
||||||
puts("Send zero-length packet");
|
puts("Send zero-length packet");
|
||||||
int res = netdev->driver->send(netdev, NULL);
|
int res = netdev->driver->send(netdev, NULL);
|
||||||
@ -77,11 +82,11 @@ static void test_send__iolist_not_NULL(void)
|
|||||||
|
|
||||||
iolist[0].iol_next = &iolist[1];
|
iolist[0].iol_next = &iolist[1];
|
||||||
|
|
||||||
netdev_t *netdev = &_dev.netdev.netdev;
|
netdev_t *netdev = &_socket_zep_netdev.dev.netdev;
|
||||||
|
|
||||||
puts("Send 'Hello\\0World\\0'");
|
puts("Send 'Hello\\0World\\0'");
|
||||||
int res = netdev->driver->send(netdev, iolist);
|
int res = netdev->driver->send(netdev, iolist);
|
||||||
expect((res < 0) || (res == (sizeof("Hello")) + sizeof("World")));
|
expect((res < 0) || (res == 0));
|
||||||
if ((res < 0) && (errno == ECONNREFUSED)) {
|
if ((res < 0) && (errno == ECONNREFUSED)) {
|
||||||
puts("No remote socket exists (use scripts in `tests/` to have proper tests)");
|
puts("No remote socket exists (use scripts in `tests/` to have proper tests)");
|
||||||
}
|
}
|
||||||
@ -91,7 +96,7 @@ static void test_recv(void)
|
|||||||
{
|
{
|
||||||
puts("Waiting for an incoming message (use `make test`)");
|
puts("Waiting for an incoming message (use `make test`)");
|
||||||
while (1) {
|
while (1) {
|
||||||
netdev_t *netdev = &_dev.netdev.netdev;
|
netdev_t *netdev = &_socket_zep_netdev.dev.netdev;
|
||||||
msg_t msg;
|
msg_t msg;
|
||||||
|
|
||||||
msg_receive(&msg);
|
msg_receive(&msg);
|
||||||
|
Loading…
Reference in New Issue
Block a user