net/ieee802154: Make RAW mode generic

- Renaming NET_L2_RAW_CHANNEL to NET_RAW_MODE
- Create a generic IEEE 802.15.4 raw mode for drivers
- Modify the IEEE 802.15.4 drivers so it passes the packet unmodified,
up to code using that mode to apply the necessary changes on the
received net_pkt according to their needs
- Modify wpanusb/wpan_serial relevantly

Fixes #5004

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2017-11-16 11:11:51 +01:00 committed by Anas Nashif
commit b52c0f24a6
19 changed files with 111 additions and 185 deletions

View file

@ -31,6 +31,16 @@ config SYS_LOG_IEEE802154_DRIVER_LEVEL
- 4 DEBUG, write SYS_LOG_DBG in addition to previous levels
config IEEE802154_RAW_MODE
bool "Use IEEE 802.15.4 driver without the MAC stack"
default n if NET_L2_IEEE802154
select NET_RAW_MODE
help
This option enables using the drivers in a so-called "raw" mode,
i.e. without a MAC stack (the net L2 layer for 802.15.4 will not
be built). Used only for very specific cases, such as wpan_serial
and wpanusb samples.
source "drivers/ieee802154/Kconfig.cc2520"
source "drivers/ieee802154/Kconfig.kw41z"

View file

@ -9,7 +9,6 @@
menuconfig IEEE802154_CC2520
bool "TI CC2520 Driver support"
depends on NETWORKING
select NET_L2_IEEE802154
default n
if IEEE802154_CC2520
@ -122,14 +121,4 @@ config IEEE802154_CC2520_CRYPTO_INIT_PRIO
you know what you are doing. It should be initialized after CC2520
as it shares the same runtime context.
config IEEE802154_CC2520_RAW
bool "TI CC2520 Driver RAW channel"
select NET_L2_RAW_CHANNEL
default n
help
Enable IEEE802154_CC2520 driver with RAW channel
The CC2520 driver with RAW channel allows to export radio interface
over USB making an USB 802.15.4 dongle.
endif # IEEE802154_CC2520

View file

@ -9,21 +9,9 @@
menuconfig IEEE802154_MCR20A
bool "NXP MCR20A Driver support"
depends on NETWORKING && SPI
select NET_L2_IEEE802154
default n
menuconfig IEEE802154_MCR20A_RAW
bool "NXP MCR20A Driver RAW channel"
depends on SPI
select NET_L2_RAW_CHANNEL
default n
help
Enable IEEE802154_MCR20A driver with RAW channel
The MCR20A driver with RAW channel allows to export radio interface
over USB making an USB 802.15.4 dongle.
if IEEE802154_MCR20A || IEEE802154_MCR20A_RAW
if IEEE802154_MCR20A
config IEEE802154_MCR20A_DRV_NAME
string "NXP MCR20A Driver's name"

View file

@ -6,32 +6,12 @@
# SPDX-License-Identifier: Apache-2.0
#
choice IEEE802154_NRF5_DRIVER_SUPPORT
prompt "nRF52 series IEEE 802.15.4 Driver support"
menuconfig IEEE802154_NRF5
prompt "nRF52 series IEEE 802.15.4 Driver"
depends on NETWORKING && SOC_NRF52840
default IEEE802154_NRF5_DISABLED
default n
config IEEE802154_NRF5_DISABLED
bool "Driver disabled"
config IEEE802154_NRF5
bool "Regular mode"
select NET_L2_IEEE802154
select HAS_NORDIC_DRIVERS
config IEEE802154_NRF5_RAW
bool "RAW mode"
select NET_L2_RAW_CHANNEL
select HAS_NORDIC_DRIVERS
help
Enable IEEE802154_CC2520 driver with RAW channel
The CC2520 driver with RAW channel allows to export radio interface
over USB making an USB 802.15.4 dongle.
endchoice
if IEEE802154_NRF5 || IEEE802154_NRF5_RAW
if IEEE802154_NRF5
config IEEE802154_NRF5_DRV_NAME
string "nRF52 IEEE 802.15.4 Driver's name"

View file

@ -620,22 +620,35 @@ static inline void insert_radio_noise_details(struct net_pkt *pkt, u8_t *buf)
static inline bool verify_crc(struct cc2520_context *cc2520,
struct net_pkt *pkt)
{
cc2520->spi.cmd_buf[0] = CC2520_INS_RXBUF;
cc2520->spi.cmd_buf[1] = 0;
cc2520->spi.cmd_buf[2] = 0;
u8_t *noise_buf;
spi_slave_select(cc2520->spi.dev, cc2520->spi.slave);
if (!IS_ENABLED(CONFIG_IEEE802154_RAW_MODE)) {
cc2520->spi.cmd_buf[0] = CC2520_INS_RXBUF;
cc2520->spi.cmd_buf[1] = 0;
cc2520->spi.cmd_buf[2] = 0;
if (spi_transceive(cc2520->spi.dev, cc2520->spi.cmd_buf, 3,
cc2520->spi.cmd_buf, 3) != 0) {
return false;
spi_slave_select(cc2520->spi.dev, cc2520->spi.slave);
if (spi_transceive(cc2520->spi.dev, cc2520->spi.cmd_buf, 3,
cc2520->spi.cmd_buf, 3) != 0) {
return false;
}
if (!(cc2520->spi.cmd_buf[2] & CC2520_FCS_CRC_OK)) {
return false;
}
noise_buf = &cc2520->spi.cmd_buf[1];
} else {
if (!(pkt->frags->data[pkt->frags->len - 1] &
CC2520_FCS_CRC_OK)) {
return false;
}
noise_buf = &pkt->frags->data[pkt->frags->len - 2];
}
if (!(cc2520->spi.cmd_buf[2] & CC2520_FCS_CRC_OK)) {
return false;
}
insert_radio_noise_details(pkt, &cc2520->spi.cmd_buf[1]);
insert_radio_noise_details(pkt, noise_buf);
return true;
}
@ -682,12 +695,6 @@ static void cc2520_rx(int arg)
goto flush;
}
#if defined(CONFIG_IEEE802154_CC2520_RAW)
/**
* Reserve 1 byte for length
*/
net_pkt_set_ll_reserve(pkt, 1);
#endif
pkt_frag = net_pkt_get_frag(pkt, K_NO_WAIT);
if (!pkt_frag) {
SYS_LOG_ERR("No pkt_frag available");
@ -696,30 +703,19 @@ static void cc2520_rx(int arg)
net_pkt_frag_insert(pkt, pkt_frag);
#if defined(CONFIG_IEEE802154_CC2520_RAW)
if (!IS_ENABLED(CONFIG_IEEE802154_RAW_MODE)) {
pkt_len -= 2;
}
if (!read_rxfifo_content(&cc2520->spi, pkt_frag, pkt_len)) {
SYS_LOG_ERR("No content read");
goto flush;
}
if (!(pkt_frag->data[pkt_len - 1] & CC2520_FCS_CRC_OK)) {
goto out;
}
insert_radio_noise_details(pkt, &pkt_frag->data[pkt_len - 2]);
net_buf_add_u8(pkt_frag, net_pkt_ieee802154_lqi(pkt));
#else
if (!read_rxfifo_content(&cc2520->spi, pkt_frag, pkt_len - 2)) {
SYS_LOG_ERR("No content read");
goto flush;
}
if (!verify_crc(cc2520, pkt)) {
SYS_LOG_ERR("Bad packet CRC");
goto out;
}
#endif
if (ieee802154_radio_handle_ack(cc2520->iface, pkt) == NET_OK) {
SYS_LOG_DBG("ACK packet handled");
@ -1132,7 +1128,7 @@ static struct ieee802154_radio_api cc2520_radio_api = {
.tx = cc2520_tx,
};
#if defined(CONFIG_IEEE802154_CC2520_RAW)
#if defined(CONFIG_IEEE802154_RAW_MODE)
DEVICE_AND_API_INIT(cc2520, CONFIG_IEEE802154_CC2520_DRV_NAME,
cc2520_init, &cc2520_context_data, NULL,
POST_KERNEL, CONFIG_IEEE802154_CC2520_INIT_PRIO,

View file

@ -557,13 +557,6 @@ static inline void mcr20a_rx(struct mcr20a_context *mcr20a, u8_t len)
goto out;
}
#if defined(CONFIG_IEEE802154_MCR20A_RAW)
/* TODO: Test raw mode */
/**
* Reserve 1 byte for length
*/
net_pkt_set_ll_reserve(pkt, 1);
#endif
frag = net_pkt_get_frag(pkt, K_NO_WAIT);
if (!frag) {
SYS_LOG_ERR("No frag available");
@ -590,10 +583,6 @@ static inline void mcr20a_rx(struct mcr20a_context *mcr20a, u8_t len)
pkt_len, net_pkt_ieee802154_lqi(pkt),
net_pkt_ieee802154_rssi(pkt));
#if defined(CONFIG_IEEE802154_MCR20A_RAW)
net_buf_add_u8(frag, mcr20a->lqi);
#endif
if (net_recv_data(mcr20a->iface, pkt) < 0) {
SYS_LOG_DBG("Packet dropped by NET stack");
goto out;
@ -1492,7 +1481,7 @@ static struct ieee802154_radio_api mcr20a_radio_api = {
.tx = mcr20a_tx,
};
#if defined(CONFIG_IEEE802154_MCR20A_RAW)
#if defined(CONFIG_IEEE802154_RAW_MODE)
DEVICE_AND_API_INIT(mcr20a, CONFIG_IEEE802154_MCR20A_DRV_NAME,
mcr20a_init, &mcr20a_context_data, NULL,
POST_KERNEL, CONFIG_IEEE802154_MCR20A_INIT_PRIO,

View file

@ -78,13 +78,6 @@ static void nrf5_rx_thread(void *arg1, void *arg2, void *arg3)
goto out;
}
#if defined(CONFIG_IEEE802154_NRF5_RAW)
/**
* Reserve 1 byte for length
*/
net_pkt_set_ll_reserve(pkt, 1);
#endif
frag = net_pkt_get_frag(pkt, K_NO_WAIT);
if (!frag) {
SYS_LOG_ERR("No frag available");
@ -97,11 +90,11 @@ static void nrf5_rx_thread(void *arg1, void *arg2, void *arg3)
* The last 2 bytes contain LQI or FCS, depending if
* automatic CRC handling is enabled or not, respectively.
*/
#if defined(CONFIG_IEEE802154_NRF5_RAW)
pkt_len = nrf5_radio->rx_psdu[0];
#else
pkt_len = nrf5_radio->rx_psdu[0] - NRF5_FCS_LENGTH;
#endif
if (IS_ENABLED(CONFIG_IEEE802154_RAW_MODE)) {
pkt_len = nrf5_radio->rx_psdu[0];
} else {
pkt_len = nrf5_radio->rx_psdu[0] - NRF5_FCS_LENGTH;
}
/* Skip length (first byte) and copy the payload */
memcpy(frag->data, nrf5_radio->rx_psdu + 1, pkt_len);
@ -430,7 +423,7 @@ static struct ieee802154_radio_api nrf5_radio_api = {
.tx = nrf5_tx,
};
#if defined(CONFIG_IEEE802154_NRF5_RAW)
#if defined(CONFIG_IEEE802154_RAW_MODE)
DEVICE_AND_API_INIT(nrf5_154_radio, CONFIG_IEEE802154_NRF5_DRV_NAME,
nrf5_init, &nrf5_data, &nrf5_radio_cfg,
POST_KERNEL, CONFIG_IEEE802154_NRF5_INIT_PRIO,

View file

@ -87,6 +87,17 @@ struct ieee802154_radio_api {
int (*stop)(struct device *dev);
} __packed;
/**
* @brief Check if AR flag is set on the frame inside given net_pkt
*
* @param pkt A valid pointer on a net_pkt structure, must not be NULL.
*
* @return True if AR flag is set, False otherwise
*/
bool ieee802154_is_ar_flag_set(struct net_pkt *pkt);
#ifndef CONFIG_IEEE802154_RAW_MODE
/**
* @brief Radio driver sending function that hw drivers should use
*
@ -122,15 +133,23 @@ extern enum net_verdict ieee802154_radio_handle_ack(struct net_if *iface,
*/
void ieee802154_init(struct net_if *iface);
/**
* @brief Check if AR flag is set on the frame inside given net_pkt
*
* @param pkt A valid pointer on a net_pkt structure, must not be NULL.
*
* @return True if AR flag is set, False otherwise
*/
bool ieee802154_is_ar_flag_set(struct net_pkt *pkt);
#else /* CONFIG_IEEE802154_RAW_MODE */
static inline int ieee802154_radio_send(struct net_if *iface,
struct net_pkt *pkt)
{
return 0;
}
static inline enum net_verdict ieee802154_radio_handle_ack(struct net_if *iface,
struct net_pkt *pkt)
{
return NET_CONTINUE;
}
#define ieee802154_init(_iface_)
#endif /* CONFIG_IEEE802154_RAW_MODE */
#ifdef __cplusplus
}

View file

@ -127,7 +127,7 @@ struct sockaddr_in_ptr {
#define NET_SOCKADDR_MAX_SIZE (sizeof(struct sockaddr_in))
#define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct sockaddr_in_ptr))
#else
#if !defined(CONFIG_NET_L2_RAW_CHANNEL)
#if !defined(CONFIG_NET_RAW_MODE)
#error "Either IPv6 or IPv4 needs to be selected."
#else
#define NET_SOCKADDR_MAX_SIZE (sizeof(struct sockaddr_in6))

View file

@ -122,7 +122,7 @@ struct net_pkt {
#endif /* CONFIG_NET_IPV6_FRAGMENT */
#endif /* CONFIG_NET_IPV6 */
#if defined(CONFIG_NET_L2_IEEE802154)
#if defined(CONFIG_NET_L2_IEEE802154) || defined(CONFIG_IEEE802154_RAW_MODE)
u8_t ieee802154_rssi; /* Received Signal Strength Indication */
u8_t ieee802154_lqi; /* Link Quality Indicator */
#endif
@ -424,7 +424,7 @@ static inline void net_pkt_ll_swap(struct net_pkt *pkt)
net_pkt_ll_dst(pkt)->addr = addr;
}
#if defined(CONFIG_NET_L2_IEEE802154)
#if defined(CONFIG_NET_L2_IEEE802154) || defined(CONFIG_IEEE802154_RAW_MODE)
static inline u8_t net_pkt_ieee802154_rssi(struct net_pkt *pkt)
{
return pkt->ieee802154_rssi;

View file

@ -9,8 +9,8 @@ CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_UART_LINE_CTRL=y
CONFIG_IEEE802154_RAW_MODE=y
CONFIG_IEEE802154_CC2520=y
CONFIG_IEEE802154_CC2520_RAW=y
CONFIG_NET_BUF=y
CONFIG_NETWORKING=y

View file

@ -449,10 +449,6 @@ static void tx_thread(void)
hexdump("SLIP <", buf->data, buf->len);
/* Remove LQI */
/* TODO: Reuse get_lqi() */
buf->len -= 1;
/* remove FCS 2 bytes */
buf->len -= 2;
@ -567,6 +563,16 @@ static bool init_ieee802154(void)
return true;
}
int net_recv_data(struct net_if *iface, struct net_pkt *pkt)
{
SYS_LOG_DBG("Got data, pkt %p, frags->len %d",
pkt, net_pkt_get_len(pkt));
k_fifo_put(&tx_queue, pkt);
return 0;
}
void main(void)
{
struct device *dev;
@ -635,34 +641,3 @@ void main(void)
/* Enable tx interrupts */
uart_irq_tx_enable(dev);
}
void ieee802154_init(struct net_if *iface)
{
SYS_LOG_DBG("");
}
int net_recv_data(struct net_if *iface, struct net_pkt *pkt)
{
SYS_LOG_DBG("Got data, pkt %p, frags->len %d",
pkt, net_pkt_get_len(pkt));
k_fifo_put(&tx_queue, pkt);
return 0;
}
extern enum net_verdict ieee802154_radio_handle_ack(struct net_if *iface,
struct net_pkt *pkt)
{
SYS_LOG_DBG("");
/* parse on higher layer */
return NET_CONTINUE;
}
int ieee802154_radio_send(struct net_if *iface, struct net_pkt *pkt)
{
SYS_LOG_DBG("");
return -ENOTSUP;
}

View file

@ -8,14 +8,11 @@ CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_NETWORKING=y
CONFIG_NET_L2_RAW_CHANNEL=y
CONFIG_NET_PKT_TX_COUNT=4
CONFIG_NET_BUF_DATA_SIZE=128
CONFIG_NET_L2_IEEE802154=y
CONFIG_IEEE802154_RAW_MODE=y
CONFIG_IEEE802154_CC2520=y
CONFIG_IEEE802154_CC2520_RAW=y
CONFIG_SYS_LOG=y
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=1

View file

@ -572,25 +572,6 @@ static void init_tx_queue(void)
NULL, NULL, NULL, K_PRIO_COOP(8), 0, K_NO_WAIT);
}
extern enum net_verdict ieee802154_radio_handle_ack(struct net_if *iface,
struct net_pkt *pkt)
{
/* parse on higher layer */
return NET_CONTINUE;
}
int ieee802154_radio_send(struct net_if *iface, struct net_pkt *pkt)
{
SYS_LOG_DBG("");
return -ENOTSUP;
}
void ieee802154_init(struct net_if *iface)
{
SYS_LOG_DBG("");
}
int net_recv_data(struct net_if *iface, struct net_pkt *pkt)
{
struct net_buf *frag;
@ -600,6 +581,10 @@ int net_recv_data(struct net_if *iface, struct net_pkt *pkt)
frag = net_buf_frag_last(pkt->frags);
/* Linux requires LQI to be put at the beginning of the buffer */
memmove(frag->data+1, frag->data, frag->len);
frag->data[0] = net_pkt_ieee802154_lqi(pkt);
/**
* Add length 1 byte, do not forget to reserve it
*/

View file

@ -3,7 +3,7 @@ zephyr_library_sources_ifdef(CONFIG_NET_BUF buf.c)
zephyr_library_sources_ifdef(CONFIG_NET_HOSTNAME_ENABLE hostname.c)
if(CONFIG_NETWORKING)
if(CONFIG_NET_L2_RAW_CHANNEL)
if(CONFIG_NET_RAW_MODE)
zephyr_library_sources(ip/net_pkt.c)
else()
add_subdirectory(ip)

View file

@ -10,11 +10,17 @@ menu "IP stack"
depends on NETWORKING
# Hidden option
config NET_L2_RAW_CHANNEL
config NET_RAW_MODE
bool
default n
help
This is a very specific option used to built only the very minimal
part of the net stack in order to get network drivers working without
any net stack above: core, L2 etc... Basically this will build only
net_pkt part. It is currently used only by IEEE 802.15.4 drivers,
though any type of net drivers could use it.
if !NET_L2_RAW_CHANNEL
if !NET_RAW_MODE
config NET_INIT_PRIO
int
@ -283,7 +289,7 @@ config NET_DEBUG_TRICKLE
help
Enables Trickle library output debug messages
endif # NET_L2_RAW_CHANNEL
endif # NET_RAW_MODE
config NET_PKT_RX_COUNT
int "How many packet receives can be pending at the same time"

View file

@ -49,7 +49,7 @@
#endif /* UDP */
#endif /* TCP */
#if defined(CONFIG_NET_IPV6) || defined(CONFIG_NET_L2_RAW_CHANNEL)
#if defined(CONFIG_NET_IPV6) || defined(CONFIG_NET_RAW_MODE)
#define IP_PROTO_LEN NET_IPV6H_LEN
#else
#if defined(CONFIG_NET_IPV4)

View file

@ -200,7 +200,7 @@ config NET_APP_PEER_IPV4_ADDR
endif # NET_IPV4
if NET_L2_IEEE802154 || NET_L2_RAW_CHANNEL
if NET_L2_IEEE802154 || IEEE802154_RAW_MODE
config NET_APP_IEEE802154_DEV_NAME
string "IEEE 802.15.4 device name"
@ -258,7 +258,7 @@ config NET_APP_IEEE802154_SECURITY_LEVEL
6 encryption/authentication with a 8 bytes length tag
7 encryption/authentication with a 16 bytes length tag
endif # NET_L2_IEEE802154 || NET_L2_RAW_CHANNEL
endif # NET_L2_IEEE802154 || IEEE802154_RAW_MODE
if NET_L2_BT

View file

@ -60,7 +60,6 @@ CONFIG_NET_L2_BT_ZEP1656=y
CONFIG_NET_L2_BT_SEC_LEVEL=4
CONFIG_NET_L2_BT_MGMT=y
CONFIG_NET_L2_BT_SHELL=y
CONFIG_NET_L2_RAW_CHANNEL=y
CONFIG_NET_DEBUG_L2_IEEE802154=y
CONFIG_NET_DEBUG_L2_IEEE802154_FRAGMENT=y
CONFIG_NET_DEBUG_L2_ETHERNET=y