Laczen commented on code in PR #15732: URL: https://github.com/apache/nuttx/pull/15732#discussion_r1941042832
########## arch/xtensa/src/esp32/esp32_espnow_pktradio.c: ########## @@ -0,0 +1,1696 @@ +/**************************************************************************** + * arch/xtensa/src/esp32/esp32_espnow_pktradio.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> +#include <string.h> +#include <errno.h> +#include <assert.h> +#include <debug.h> + +#include <arpa/inet.h> +#include <net/if.h> + +#include <nuttx/wqueue.h> +#include <nuttx/mm/iob.h> +#include <nuttx/net/net.h> +#include <nuttx/net/ip.h> +#include <nuttx/spinlock.h> +#include <nuttx/net/radiodev.h> +#include <nuttx/net/sixlowpan.h> +#include <nuttx/wireless/pktradio.h> +#include <nuttx/wdog.h> + +#include "xtensa.h" +#include "xtensa_attr.h" +#include "esp_now.h" +#include "esp_mac.h" +#include "esp32_espnow_pktradio.h" + +#ifdef CONFIG_ESP32_ESPNOW_PKTRADIO + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* TX timeout = 1 minute */ + +#define ESP32_ESPNOW_TXTOUT (60 * CLK_TCK) + +/* We need to have the work queue */ + +#if !defined(CONFIG_SCHED_WORKQUEUE) +# error Worker thread support is required (CONFIG_SCHED_WORKQUEUE) +#else +# if defined(CONFIG_SCHED_LPWORK) +# define LPBKWORK LPWORK +# elif defined(CONFIG_SCHED_HPWORK) +# define LPBKWORK HPWORK +# else +# error Neither CONFIG_SCHED_LPWORK nor CONFIG_SCHED_HPWORK defined +# endif +#endif + +#ifndef CONFIG_WIRELESS_PKTRADIO +# error CONFIG_WIRELESS_PKTRADIO=y is required. +#endif + +#ifndef CONFIG_NET_6LOWPAN +# error CONFIG_NET_6LOWPAN=y is required. +#endif + +#if (CONFIG_PKTRADIO_ADDRLEN != 1) && (CONFIG_PKTRADIO_ADDRLEN != 2) && \ + (CONFIG_PKTRADIO_ADDRLEN != 8) +# error No support for CONFIG_PKTRADIO_ADDRLEN other than {1, 2 or 8} +#endif + +/**************************************************************************** + * MAC HDR: 3 byte MAGIC, 2 byte PANID, 1 byte INFO, SRC addr, DST addr + * INFO: BIT0-1: address size: 00 (2^0) -> 1 BYTE address size + * 01 (2^1) -> 2 BYTE address size + * 11 (2^3) -> 8 BYTE address size + * Future expansion: INFO BIT2: cypher info added to MAC HDR + * + ****************************************************************************/ + +#define MAC_MAGIC "6lo" +#define MAC_PANIDOFFSET sizeof(MAC_MAGIC) - 1 +#define MAC_PANIDLEN 2 +#define MAC_INFOOFFSET MAC_PANIDOFFSET + MAC_PANIDLEN +#define MAC_INFOLEN 1 +#define MAC_ADDRLEN CONFIG_PKTRADIO_ADDRLEN +#define MAC_SRCOFFSET MAC_INFOOFFSET + MAC_INFOLEN +#define MAC_DSTOFFSET MAC_SRCOFFSET + MAC_ADDRLEN +#define MAC_HDRSIZE MAC_DSTOFFSET + MAC_ADDRLEN +#if MAC_ADDRLEN == 1 +#define MAC_INFOADDRLEN 0x0 +#elif MAC_ADDRLEN == 2 +#define MAC_INFOADDRLEN 0x1 +#elif MAC_ADDRLEN == 8 +#define MAC_INFOADDRLEN 0x3 +#endif +#define MAC_INFOADDRMASK 0x3 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * The espnow_driver_s encapsulates all state information for a single + * hardware interface + * + ****************************************************************************/ + +struct espnow_driver_s +{ + bool bifup; /* true:ifup false:ifdown */ + + uint8_t mac_address[MAC_ADDRLEN]; /* node address */ + uint8_t panid[MAC_PANIDLEN]; /* network id */ + + struct sixlowpan_reassbuf_s iobuffer; /* buffer for packet reassembly */ + + FAR struct iob_s *rxhead; /* Head of IOBs queued for rx */ + FAR struct iob_s *rxtail; /* Tail of IOBs queued for rx */ + FAR struct iob_s *txhead; /* Head of IOBs queued for tx */ + FAR struct iob_s *txtail; /* Tail of IOBs queued for tx */ + + bool txblocked; /* Indicates a blocked/failed tx */ + + struct wdog_s txtimeout; /* TX timeout timer */ + + struct work_s work; /* Defer tx and rx work to the work queue */ + struct work_s pollwork; /* Defer pollwork to the work queue */ + struct work_s toutwork; /* Defer driver reset to the work queue */ + + spinlock_t lock; /* Device specific lock */ + + struct radio_driver_s radio; /* Interface understood by the network */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct espnow_driver_s g_espnow; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Utility functions */ + +static void espnow_addr(FAR struct net_driver_s *dev); +static void espnow_addr2ip(FAR struct net_driver_s *dev); +static inline void espnow_netmask(FAR struct net_driver_s *dev); + +/* Queue functions */ + +static void espnow_txtailadd(FAR struct espnow_driver_s *priv, + FAR struct iob_s *iob); +static void espnow_txheadadd(FAR struct espnow_driver_s *priv, + FAR struct iob_s *iob); +static FAR struct iob_s *espnow_txtailget(FAR struct espnow_driver_s *priv); +static void espnow_rxtailadd(FAR struct espnow_driver_s *priv, + FAR struct iob_s *iob); +static FAR struct iob_s *espnow_rxtailget(FAR struct espnow_driver_s *priv); + +/* ESPNOW low level routines */ + +static int espnow_error_to_errno(esp_err_t err); +static int espnow_send(FAR struct iob_s *iob); +static void espnow_recv_cb(const esp_now_recv_info_t * esp_now_info, + const uint8_t *data, int data_len); + +/* Translate pktmeta to MAC header and vice versa */ + +static void espnow_add_header(struct espnow_driver_s *espnow, + FAR struct pktradio_metadata_s *pktmeta, + FAR struct iob_s *iob); +static void espnow_extract_pktmeta(FAR struct iob_s *iob, + FAR struct pktradio_metadata_s *pktmeta); + +/* TX and RX work */ + +static void espnow_work(FAR void *arg); + +/* TX polling logic */ + +static void espnow_txavail_work(FAR void *arg); +static int espnow_txpoll_callback(FAR struct net_driver_s *dev); + +/* Watchdog timer expirations */ + +static void espnow_txtimeout_work(void *arg); +static void espnow_txtimeout_expiry(wdparm_t arg); + +/* NuttX callback functions */ + +static int espnow_ifup(FAR struct net_driver_s *dev); +static int espnow_ifdown(FAR struct net_driver_s *dev); +static int espnow_txavail(FAR struct net_driver_s *dev); +#ifdef CONFIG_NET_MCASTGROUP +static int espnow_addmac(FAR struct net_driver_s *dev, + FAR const uint8_t *mac); +static int espnow_rmmac(FAR struct net_driver_s *dev, + FAR const uint8_t *mac); +#endif +#ifdef CONFIG_NETDEV_IOCTL +static int espnow_ioctl(FAR struct net_driver_s *dev, int cmd, + unsigned long arg); +#endif +static int espnow_get_mhrlen(FAR struct radio_driver_s *netdev, + FAR const void *meta); +static int espnow_req_data(FAR struct radio_driver_s *netdev, + FAR const void *meta, FAR struct iob_s *framelist); +static int espnow_properties(FAR struct radio_driver_s *netdev, + FAR struct radiodev_properties_s *properties); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: espnow_addr + * + * Description: + * Set the address based on config values. + * + ****************************************************************************/ + +static void espnow_addr(FAR struct net_driver_s *dev) +{ + FAR struct espnow_driver_s *priv = + (FAR struct espnow_driver_s *)dev->d_private; + +#if CONFIG_PKTRADIO_ADDRLEN == 1 + /* Set the mac address based on the 1 byte address */ + + priv->mac_address[0] = CONFIG_ESP32_ESPNOW_PKTRADIO_NODE_ADDR_0; + +#elif CONFIG_PKTRADIO_ADDRLEN == 2 + /* Set the mac address based on the 2 byte address */ + + priv->mac_address[0] = CONFIG_ESP32_ESPNOW_PKTRADIO_NODE_ADDR_0; + priv->mac_address[1] = CONFIG_ESP32_ESPNOW_PKTRADIO_NODE_ADDR_1; + +#elif CONFIG_PKTRADIO_ADDRLEN == 8 + /* Set the mac address based on the 8 byte address */ + + priv->mac_address[0] = CONFIG_ESP32_ESPNOW_PKTRADIO_NODE_ADDR_0; + priv->mac_address[1] = CONFIG_ESP32_ESPNOW_PKTRADIO_NODE_ADDR_1; + priv->mac_address[2] = CONFIG_ESP32_ESPNOW_PKTRADIO_NODE_ADDR_2; + priv->mac_address[3] = CONFIG_ESP32_ESPNOW_PKTRADIO_NODE_ADDR_3; + priv->mac_address[4] = CONFIG_ESP32_ESPNOW_PKTRADIO_NODE_ADDR_4; + priv->mac_address[5] = CONFIG_ESP32_ESPNOW_PKTRADIO_NODE_ADDR_5; + priv->mac_address[6] = CONFIG_ESP32_ESPNOW_PKTRADIO_NODE_ADDR_6; + priv->mac_address[7] = CONFIG_ESP32_ESPNOW_PKTRADIO_NODE_ADDR_7; + +#endif +} + +/**************************************************************************** + * Name: espnow_addr2ip + * + * Description: + * Create a MAC-based IP address from the pktradio address assigned to the + * node. + * + * 128 112 96 80 64 48 32 16 + * ---- ---- ---- ---- ---- ---- ---- ---- + * fe80 0000 0000 0000 0000 00ff fe00 00xx 1-byte pktradio address + * fe80 0000 0000 0000 0000 00ff fe00 xxxx 2-byte pktradio address + * fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte pktradio address + * + ****************************************************************************/ + +static void espnow_addr2ip(FAR struct net_driver_s *dev) +{ + FAR struct espnow_driver_s *priv = + (FAR struct espnow_driver_s *)dev->d_private; + uint8_t mac_addr[MAC_ADDRLEN]; + + /* Copy the MAC address */ + + memcpy(mac_addr, priv->mac_address, MAC_ADDRLEN); + + /* Set the MAC address as the saddr */ + + dev->d_mac.radio.nv_addrlen = MAC_ADDRLEN; + memcpy(dev->d_mac.radio.nv_addr, mac_addr, MAC_ADDRLEN); + + /* Set the IP address */ + + dev->d_ipv6addr[0] = HTONS(0xfe80); + dev->d_ipv6addr[1] = 0; + dev->d_ipv6addr[2] = 0; + dev->d_ipv6addr[3] = 0; + +#if CONFIG_PKTRADIO_ADDRLEN == 1 + /* Set the IP address based on the 1 byte address */ + + dev->d_ipv6addr[4] = 0; + dev->d_ipv6addr[5] = HTONS(0x00ff); + dev->d_ipv6addr[6] = HTONS(0xfe00); + dev->d_ipv6addr[7] = (uint16_t)mac_addr[0] << 8; + +#elif CONFIG_PKTRADIO_ADDRLEN == 2 + /* Set the IP address based on the 2 byte address */ + + dev->d_ipv6addr[4] = 0; + dev->d_ipv6addr[5] = HTONS(0x00ff); + dev->d_ipv6addr[6] = HTONS(0xfe00); + dev->d_ipv6addr[7] = (uint16_t)mac_addr[0] << 8 | + (uint16_t)mac_addr[1]; + +#elif CONFIG_PKTRADIO_ADDRLEN == 8 + /* Set the IP address based on the 8-byte address */ + + dev->d_ipv6addr[4] = (uint16_t)mac_addr[0] << 8 | + (uint16_t)mac_addr[1]; + dev->d_ipv6addr[5] = (uint16_t)mac_addr[2] << 8 | + (uint16_t)mac_addr[3]; + dev->d_ipv6addr[6] = (uint16_t)mac_addr[4] << 8 | + (uint16_t)mac_addr[5]; + dev->d_ipv6addr[7] = (uint16_t)mac_addr[6] << 8 | + (uint16_t)mac_addr[7]; + +#endif +} + +/**************************************************************************** + * Name: espnow_netmask + * + * Description: + * Create a netmask of a MAC-based IP address for pktradio address. + * + * 128 112 96 80 64 48 32 16 + * ---- ---- ---- ---- ---- ---- ---- ---- + * ffff ffff ffff ffff ffff ffff ffff ff00 1-byte pktradio address + * ffff ffff ffff ffff ffff ffff ffff 0000 2-byte pktradio address + * ffff ffff ffff ffff 0000 0000 0000 0000 8-byte pktradio address + * + ****************************************************************************/ + +static inline void espnow_netmask(FAR struct net_driver_s *dev) +{ + dev->d_ipv6netmask[0] = 0xffff; + dev->d_ipv6netmask[1] = 0xffff; + dev->d_ipv6netmask[2] = 0xffff; + dev->d_ipv6netmask[3] = 0xffff; + +#if CONFIG_PKTRADIO_ADDRLEN == 1 + dev->d_ipv6netmask[4] = 0xffff; + dev->d_ipv6netmask[5] = 0xffff; + dev->d_ipv6netmask[6] = 0xffff; + dev->d_ipv6netmask[7] = HTONS(0xff00); + +#elif CONFIG_PKTRADIO_ADDRLEN == 2 + dev->d_ipv6netmask[4] = 0xffff; + dev->d_ipv6netmask[5] = 0xffff; + dev->d_ipv6netmask[6] = 0xffff; + dev->d_ipv6netmask[7] = 0; + +#elif CONFIG_PKTRADIO_ADDRLEN == 8 + dev->d_ipv6netmask[4] = 0; + dev->d_ipv6netmask[5] = 0; + dev->d_ipv6netmask[6] = 0; + dev->d_ipv6netmask[7] = 0; +#endif +} + +/**************************************************************************** + * Name: espnow_add_header + * + * Description + * Create and add the mac header to iob for TX + * + * Input Parameters: + * priv - Reference to the driver state structure + * pktmeta - pktmeta + * iob - iob to add the header to + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void espnow_add_header(struct espnow_driver_s *priv, + FAR struct pktradio_metadata_s *pktmeta, + FAR struct iob_s *iob) +{ + uint8_t info = MAC_INFOADDRLEN; + + memcpy(&iob->io_data[0], MAC_MAGIC, sizeof(MAC_MAGIC) - 1); + memcpy(&iob->io_data[MAC_PANIDOFFSET], priv->panid, MAC_PANIDLEN); + memcpy(&iob->io_data[MAC_INFOOFFSET], &info, sizeof(info)); + memcpy(&iob->io_data[MAC_SRCOFFSET], pktmeta->pm_src.pa_addr, MAC_ADDRLEN); + memcpy(&iob->io_data[MAC_DSTOFFSET], pktmeta->pm_dest.pa_addr, + MAC_ADDRLEN); +} + +/**************************************************************************** + * Name: espnow_extract_pktmeta + * + * Description + * Extract pktmeta from received iob + * + * Input Parameters: + * iob - iob to extract pktmeta from + * pktmeta - pktmeta to update + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void espnow_extract_pktmeta(FAR struct iob_s *iob, + FAR struct pktradio_metadata_s *pktmeta) +{ + pktmeta->pm_src.pa_addrlen = MAC_ADDRLEN; + pktmeta->pm_dest.pa_addrlen = MAC_ADDRLEN; + + memcpy(pktmeta->pm_src.pa_addr, &iob->io_data[MAC_SRCOFFSET], MAC_ADDRLEN); + memcpy(pktmeta->pm_dest.pa_addr, &iob->io_data[MAC_DSTOFFSET], + MAC_ADDRLEN); + iob->io_offset = MAC_HDRSIZE; +} + +/**************************************************************************** + * Name: espnow_txtailadd + * + * Description + * Add a iob to txtail + * + * Input Parameters: + * priv - Reference to the driver state structure + * iob - iob to add + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void espnow_txtailadd(FAR struct espnow_driver_s *priv, + FAR struct iob_s *iob) +{ + irqstate_t flags; + + flags = spin_lock_irqsave(&priv->lock); + + if (priv->txhead == NULL) + { + /* Add iob to empty list */ + + priv->txhead = iob; + } + else + { + /* Update tx tail io_flink */ + + priv->txtail->io_flink = iob; + } + + /* Add iob to list */ + + priv->txtail = iob; + + spin_unlock_irqrestore(&priv->lock, flags); +} + +/**************************************************************************** + * Name: espnow_txheadadd + * + * Description + * Add a iob to txhead + * + * Input Parameters: + * priv - Reference to the driver state structure + * iob - iob to add + * + * Returned Value: + * None + ****************************************************************************/ + +static void espnow_txheadadd(FAR struct espnow_driver_s *priv, + FAR struct iob_s *iob) +{ + irqstate_t flags; + + flags = spin_lock_irqsave(&priv->lock); + + if (priv->txhead == NULL) + { + /* add iob to empty list */ + + priv->txhead = iob; + priv->txtail = iob; + } + else + { + /* update iob->io_flink and txhead */ + + iob->io_flink = priv->txhead; + priv->txhead = iob; + } + + spin_unlock_irqrestore(&priv->lock, flags); +} + +/**************************************************************************** + * Name: espnow_txtailget + * + * Description + * Remove the iob from txhead + * + * Input Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * iob pointer + * + ****************************************************************************/ + +static FAR struct iob_s *espnow_txtailget(FAR struct espnow_driver_s *priv) +{ + FAR struct iob_s *iob; + irqstate_t flags; + + if (priv->txhead == NULL) + { + return NULL; + } + + flags = spin_lock_irqsave(&priv->lock); + + /* Remove the IOB from the tx list */ + + iob = priv->txhead; + priv->txhead = iob->io_flink; + iob->io_flink = NULL; + + /* Did the tx list become empty? */ + + if (priv->txhead == NULL) + { + priv->txtail = NULL; + } + + spin_unlock_irqrestore(&priv->lock, flags); + + return iob; +} + +/**************************************************************************** + * Name: espnow_rxtailadd + * + * Description + * Add a iob to rxtail + * + * Input Parameters: + * priv - Reference to the driver state structure + * iob - iob to add + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void espnow_rxtailadd(FAR struct espnow_driver_s *priv, + FAR struct iob_s *iob) +{ + irqstate_t flags; + + flags = spin_lock_irqsave(&priv->lock); + + if (priv->rxhead == NULL) + { + /* Add iob to rx list */ + + priv->rxhead = iob; + } + else + { + /* Update rx tail io_flink */ + + priv->rxtail->io_flink = iob; + } + + /* Add iob to rxtail */ + + priv->rxtail = iob; + + spin_unlock_irqrestore(&priv->lock, flags); +} + +/**************************************************************************** + * Name: espnow_rxtailget + * + * Description + * Remove the iob from txhead + * + * Input Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * iob + * + ****************************************************************************/ + +static FAR struct iob_s *espnow_rxtailget(FAR struct espnow_driver_s *priv) +{ + FAR struct iob_s *iob; + irqstate_t flags; + + if (priv->rxhead == NULL) + { + return NULL; + } + + flags = spin_lock_irqsave(&priv->lock); + + /* Remove the IOB from the tx queue */ + + iob = priv->rxhead; + priv->rxhead = iob->io_flink; + iob->io_flink = NULL; + + /* Did the framelist become empty? */ + + if (priv->rxhead == NULL) + { + priv->rxtail = NULL; + } + + spin_unlock_irqrestore(&priv->lock, flags); + + return iob; +} + +/**************************************************************************** + * Name: espnow_error_to_nuttx + * + * Description: + * Translate espnow_error to nuttx + * + * Input Parameters: + * err - espnow error + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +static int espnow_error_to_errno(esp_err_t err) +{ + int ret; + + switch (err) + { + case ESP_OK: + ret = OK; + break; + case ESP_ERR_ESPNOW_NOT_INIT: + case ESP_ERR_ESPNOW_INTERNAL: + ret = -EIO; + break; + case ESP_ERR_ESPNOW_ARG: + ret = -EINVAL; + break; + case ESP_ERR_ESPNOW_NO_MEM: + ret = -ENOMEM; + break; + case ESP_ERR_ESPNOW_NOT_FOUND: + case ESP_ERR_ESPNOW_IF: + ret = -ENOSYS; + break; + default: + ret = ERROR; + break; + } + + if (ret != OK) + { + wlerr("ERROR: %d\n", ret); + } + + return ret; +} + +/**************************************************************************** + * Name: espnow_send + * + * Description: + * Broadcast a frame over espnow + * + * Input Parameters: + * iob - iob to send + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +static int espnow_send(FAR struct iob_s *iob) +{ + const uint8_t broadcast[] = + { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + esp_err_t err; + + err = esp_now_send(broadcast, iob->io_data, iob->io_len); + return espnow_error_to_errno(err); +} + +/**************************************************************************** + * Name: espnow_recv_cb + * + * Description: + * Callback when data is received over espnow, allocate a new iob, copy the + * received data and add the iob to the rx queue. + * + * Input Parameters: + * esp_now_info - info of the broadcasting node (unused), + * data - received data + * len - received data size + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void espnow_recv_cb(const esp_now_recv_info_t * esp_now_info, + const uint8_t *data, int data_len) +{ + FAR struct espnow_driver_s *priv = &g_espnow; + FAR struct iob_s *iob; + uint8_t info; + irqstate_t flags; + + /* Drop received data if interface not up */ + + if (!priv->bifup) + { + return; + } + + /* Drop received data if header is too small */ + + if (data_len < (MAC_DSTOFFSET + MAC_ADDRLEN)) + { + return; + } + + /* Drop received data if header does not start with magic */ + + if (memcmp(data, MAC_MAGIC, sizeof(MAC_MAGIC) - 1)) + { + return; + } + + /* Drop received data if header PANID is not ours + * todo: add support for multiple PANID's + */ + + if (memcmp(&data[MAC_PANIDOFFSET], priv->panid, MAC_PANIDLEN)) + { + return; + } + + /* Drop received data if different address length is used */ + + memcpy(&info, &data[MAC_INFOOFFSET], 1); + + if ((info & MAC_INFOADDRMASK) != MAC_INFOADDRLEN) + { + return; + } + + /* Header data seems ok, continue with processing */ + + iob = iob_tryalloc(false); + + /* Ignore the packet if allocation fails or packet too large */ + + if ((iob == NULL) || (data_len > CONFIG_IOB_BUFSIZE)) + { + return; + } Review Comment: Wouldn't 250 be too large given that 6lowpan frames are smaller than 127 octets (I could be making an error since 6lowpan, espnow and NuttX are all new for me) ? -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org