Merge "Merge net branch into master"
This commit is contained in:
commit
31f01f8ed6
121 changed files with 2507 additions and 1034 deletions
|
@ -58,7 +58,7 @@ static int frdm_k64f_pinmux_init(struct device *dev)
|
|||
pinmux_pin_set(porte, 26, PORT_PCR_MUX(kPORT_MuxAsGpio));
|
||||
pinmux_pin_set(portb, 21, PORT_PCR_MUX(kPORT_MuxAsGpio));
|
||||
|
||||
#ifdef CONFIG_NXP_MCR20A
|
||||
#ifdef CONFIG_IEEE802154_MCR20A
|
||||
/* FRDM-MCR20A Reset (D5) */
|
||||
pinmux_pin_set(porta, 2, PORT_PCR_MUX(kPORT_MuxAsGpio));
|
||||
/* FRDM-MCR20A IRQ_B (D2) */
|
||||
|
|
|
@ -46,26 +46,26 @@ endif
|
|||
config BLUETOOTH_MONITOR_ON_DEV_NAME
|
||||
default UART_QMSI_1_NAME if BLUETOOTH_DEBUG_MONITOR
|
||||
|
||||
if TI_CC2520_LEGACY || TI_CC2520 || TI_CC2520_RAW
|
||||
if IEEE802154_CC2520_LEGACY || IEEE802154_CC2520 || IEEE802154_CC2520_RAW
|
||||
|
||||
config SPI
|
||||
def_bool y
|
||||
config GPIO
|
||||
def_bool y
|
||||
|
||||
config TI_CC2520_SPI_DRV_NAME
|
||||
config IEEE802154_CC2520_SPI_DRV_NAME
|
||||
default SPI_1_NAME
|
||||
config TI_CC2520_SPI_FREQ
|
||||
config IEEE802154_CC2520_SPI_FREQ
|
||||
default 4
|
||||
config TI_CC2520_SPI_SLAVE
|
||||
config IEEE802154_CC2520_SPI_SLAVE
|
||||
default 1
|
||||
|
||||
|
||||
if GPIO_QMSI
|
||||
|
||||
config TI_CC2520_GPIO_0_NAME
|
||||
config IEEE802154_CC2520_GPIO_0_NAME
|
||||
default GPIO_QMSI_0_NAME
|
||||
config TI_CC2520_GPIO_1_NAME
|
||||
config IEEE802154_CC2520_GPIO_1_NAME
|
||||
default GPIO_QMSI_1_NAME
|
||||
|
||||
endif # GPIO_QMSI
|
||||
|
@ -77,14 +77,14 @@ config SPI_1_CS_GPIO_PORT
|
|||
default GPIO_QMSI_0_NAME
|
||||
config SPI_1_CS_GPIO_PIN
|
||||
default 11
|
||||
config TI_CC2520_GPIO_0_NAME
|
||||
config IEEE802154_CC2520_GPIO_0_NAME
|
||||
string
|
||||
default GPIO_QMSI_0_NAME
|
||||
config TI_CC2520_GPIO_1_NAME
|
||||
config IEEE802154_CC2520_GPIO_1_NAME
|
||||
string
|
||||
default GPIO_QMSI_1_NAME
|
||||
endif
|
||||
|
||||
endif # TI_CC2520_LEGACY || TI_CC2520 || TI_CC2520_RAW
|
||||
endif # IEEE802154_CC2520_LEGACY || IEEE802154_CC2520 || IEEE802154_CC2520_RAW
|
||||
|
||||
endif # BOARD_QUARK_SE_C1000_DEVBOARD
|
||||
|
|
|
@ -10,9 +10,9 @@
|
|||
#include <device.h>
|
||||
#include <init.h>
|
||||
|
||||
#if defined(CONFIG_TI_CC2520_LEGACY) || \
|
||||
defined(CONFIG_TI_CC2520) || \
|
||||
defined(CONFIG_TI_CC2520_RAW)
|
||||
#if defined(CONFIG_IEEE802154_CC2520_LEGACY) || \
|
||||
defined(CONFIG_IEEE802154_CC2520) || \
|
||||
defined(CONFIG_IEEE802154_CC2520_RAW)
|
||||
|
||||
#include <ieee802154/cc2520.h>
|
||||
#include <gpio.h>
|
||||
|
@ -34,7 +34,7 @@ struct cc2520_gpio_configuration *cc2520_configure_gpios(void)
|
|||
GPIO_INT_ACTIVE_HIGH | GPIO_INT_DEBOUNCE);
|
||||
struct device *gpio;
|
||||
|
||||
gpio = device_get_binding(CONFIG_TI_CC2520_GPIO_1_NAME);
|
||||
gpio = device_get_binding(CONFIG_IEEE802154_CC2520_GPIO_1_NAME);
|
||||
gpio_pin_configure(gpio, cc2520_gpios[CC2520_GPIO_IDX_VREG_EN].pin,
|
||||
flags_noint_out);
|
||||
gpio_pin_configure(gpio, cc2520_gpios[CC2520_GPIO_IDX_RESET].pin,
|
||||
|
@ -43,7 +43,7 @@ struct cc2520_gpio_configuration *cc2520_configure_gpios(void)
|
|||
cc2520_gpios[CC2520_GPIO_IDX_VREG_EN].dev = gpio;
|
||||
cc2520_gpios[CC2520_GPIO_IDX_RESET].dev = gpio;
|
||||
|
||||
gpio = device_get_binding(CONFIG_TI_CC2520_GPIO_0_NAME);
|
||||
gpio = device_get_binding(CONFIG_IEEE802154_CC2520_GPIO_0_NAME);
|
||||
gpio_pin_configure(gpio, cc2520_gpios[CC2520_GPIO_IDX_SFD].pin,
|
||||
flags_int_in);
|
||||
gpio_pin_configure(gpio, cc2520_gpios[CC2520_GPIO_IDX_FIFOP].pin,
|
||||
|
@ -61,4 +61,6 @@ struct cc2520_gpio_configuration *cc2520_configure_gpios(void)
|
|||
return cc2520_gpios;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_TI_CC2520_LEGACY || CONFIG_TI_CC2520 || CONFIG_TI_CC2520_RAW */
|
||||
#endif /* CONFIG_IEEE802154_CC2520_LEGACY || CONFIG_IEEE802154_CC2520 ||
|
||||
* CONFIG_IEEE802154_CC2520_RAW
|
||||
*/
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
#define LED0_GPIO_PORT CONFIG_GPIO_QMSI_0_NAME
|
||||
#define LED0_GPIO_PIN 25
|
||||
|
||||
#if defined(CONFIG_TI_CC2520_LEGACY) || \
|
||||
defined(CONFIG_TI_CC2520) || \
|
||||
defined(CONFIG_TI_CC2520_RAW)
|
||||
#if defined(CONFIG_IEEE802154_CC2520_LEGACY) || \
|
||||
defined(CONFIG_IEEE802154_CC2520) || \
|
||||
defined(CONFIG_IEEE802154_CC2520_RAW)
|
||||
|
||||
/* GPIO numbers where the TI cc2520 chip is connected to */
|
||||
#define CC2520_GPIO_VREG_EN 0 /* PIN ?, ATP_AON_INT0 (out) */
|
||||
|
@ -33,7 +33,9 @@
|
|||
#define CC2520_GPIO_CCA 6 /* PIN 6, GPIO6 (in) */
|
||||
#define CC2520_GPIO_SFD 29 /* PIN 33, GPIO29 (in) */
|
||||
|
||||
#endif /* CONFIG_TI_CC2520_LEGACY || CONFIG_TI_CC2520 || CONFIG_TI_CC2520_RAW */
|
||||
#endif /* CONFIG_IEEE802154_CC2520_LEGACY || CONFIG_IEEE802154_CC2520 ||
|
||||
* CONFIG_IEEE802154_CC2520_RAW
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_USB)
|
||||
/* GPIO driver name */
|
||||
|
|
|
@ -95,7 +95,7 @@ static struct net_buf *udp_recv(const char *name,
|
|||
NET_INFO("%s received %u bytes", name,
|
||||
net_nbuf_appdatalen(buf));
|
||||
|
||||
reply_buf = net_nbuf_get_tx(context);
|
||||
reply_buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
|
||||
NET_ASSERT(reply_buf);
|
||||
|
||||
|
@ -113,7 +113,7 @@ static struct net_buf *udp_recv(const char *name,
|
|||
net_buf_pull(tmp, header_len);
|
||||
|
||||
while (tmp) {
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
|
||||
memcpy(net_buf_add(frag, tmp->len), tmp->data, tmp->len);
|
||||
|
||||
|
|
154
doc/subsystems/networking/l2-and-drivers.rst
Normal file
154
doc/subsystems/networking/l2-and-drivers.rst
Normal file
|
@ -0,0 +1,154 @@
|
|||
.. _l2_and_drivers:
|
||||
|
||||
L2 Stack and Drivers
|
||||
####################
|
||||
|
||||
The L2 stack is designed to hide the whole networking link-layer part
|
||||
and the related device drivers from the higher IP stack. This is made
|
||||
through a unique object known as the "network interface object":
|
||||
:c:type:`struct net_if` declared in `include/net/net_if.h`.
|
||||
|
||||
The IP layer is unaware of implementation details beyond the net_if
|
||||
object and the generic API provided by the L2 layer in
|
||||
`include/net/net_l2.h` as :c:type:`struct net_l2`.
|
||||
|
||||
Only the L2 layer can talk to the device driver, linked to the net_if
|
||||
object. The L2 layer dictates the API provided by the device driver,
|
||||
specific for that device, and optimized for working together.
|
||||
|
||||
Currently, there are L2 layers for Ethernet, IEEE 802.15.4 Soft-MAC,
|
||||
Bluetooth IPSP, and a dummy one, which is a generic layer example that
|
||||
can be used as a template for writing a new one.
|
||||
|
||||
L2 layer API
|
||||
************
|
||||
|
||||
In order to create an L2 layer, or even a driver for a specific L2
|
||||
layer, one needs to understand how the IP layer interacts with it and
|
||||
how the L2 layer is supposed to behave. The generic L2 API has 3
|
||||
functions:
|
||||
|
||||
- recv: All device drivers, once they receive a packet which they put
|
||||
into a :c:type:`struct net_nbuf`, will push this buffer to the IP
|
||||
core stack via :c:func:`net_recv_data()`. At this point, the IP core
|
||||
stack does not know what to do with it. Instead, it passes the
|
||||
buffer along to the L2 stack's recv() function for handling. The L2
|
||||
stack does what it needs to do with the packet, for example, parsing
|
||||
the link layer header, or handling link-layer only packets. The
|
||||
recv() function will return NET_DROP in case of an erroneous packet,
|
||||
NET_OK if the packet was fully consumed by the L2, or NET_CONTINUE
|
||||
if the IP stack should then handle it as an IP packet.
|
||||
|
||||
- reserve: Prior to creating any network buffer content, the Zephyr
|
||||
core stack needs to know how much dedicated buffer space is needed
|
||||
for the L2 layer (for example, space for the link layer header). This
|
||||
reserve function returns the number of bytes needed.
|
||||
|
||||
- send: Similar to recv, the IP core stack will call this function to
|
||||
actually send a packet. All relevant link-layer content will be
|
||||
generated and added by this function. As for recv, send returns a
|
||||
verdict and can decide to drop the packet via NET_DROP if something
|
||||
wrong happened, or will return NET_OK.
|
||||
|
||||
Network Device drivers
|
||||
**********************
|
||||
|
||||
Network device drivers fully follows Zephyr device driver model as a
|
||||
basis. Please refer to :ref:`device_drivers`.
|
||||
|
||||
There are, however, two differences:
|
||||
|
||||
- the driver_api pointer must point to a valid :c:type:`struct
|
||||
net_if_api` pointer.
|
||||
|
||||
- The network device driver must use NET_DEVICE_INIT_INSTANCE(). This
|
||||
macro will call the DEVICE_AND_API_INIT() macro, and also
|
||||
instantiate a unique :c:type:`struct net_if` related to the created
|
||||
device driver instance.
|
||||
|
||||
Implementing a network device driver depends on the L2 stack it
|
||||
belongs to: Ethernet, IEEE 802.15.4, etc. In the next section, we will
|
||||
describe how a device driver should behave when receiving or sending a
|
||||
packet. The rest is really hardware dependent and thus does not need
|
||||
to be detailed here.
|
||||
|
||||
Ethernet device driver
|
||||
======================
|
||||
|
||||
On reception, it is up to the device driver to fill-in the buffer with
|
||||
as many data fragments as required. The buffer itself is a
|
||||
:c:type:`struct net_nbuf` and should be allocated through
|
||||
:c:func:`net_nbuf_get_reserve_rx(0)`. Then all fragments will be
|
||||
allocated through :c:func:`net_nbuf_get_reserve_data(0)`. Of course
|
||||
the amount of required fragments depends on the size of the received
|
||||
packet and on the size of a fragment, which is given by
|
||||
`CONFIG_NET_NBUF_DATA_SIZE`.
|
||||
|
||||
Note that it is not up to the device driver to decide on the
|
||||
link-layer space to be reserved in the buffer. Hence the 0 given as
|
||||
parameter here. The Ethernet L2 layer will update such information
|
||||
once the packet's Ethernet header has been successfully parsed.
|
||||
|
||||
In case :c:func:`net_recv_data()` call fails, it will be up to the
|
||||
device driver to un-reference the buffer via
|
||||
:c:func:`net_nbuf_unref()`.
|
||||
|
||||
On sending, it is up to the device driver to send the buffer all at
|
||||
once, with all the fragments.
|
||||
|
||||
In case of a fully successful packet transmission only, the device
|
||||
driver must un-reference the buffer via `net_nbuf_unref()`.
|
||||
|
||||
Each Ethernet device driver will need, in the end, to call
|
||||
`NET_DEVICE_INIT_INSTANCE()` like this:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
NET_DEVICE_INIT_INSTANCE(...,
|
||||
CONFIG_ETH_INIT_PRIORITY
|
||||
&the_valid_net_if_api_instance,
|
||||
ETHERNET_L2,
|
||||
NET_L2_GET_CTX_TYPE(ETHERNET_L2), 1500);
|
||||
|
||||
IEEE 802.15.4 device driver
|
||||
===========================
|
||||
|
||||
Device drivers for IEEE 802.15.4 L2 work basically the same as for
|
||||
Ethernet. What has been described above, especially for recv, applies
|
||||
here as well. There are two specific differences however:
|
||||
|
||||
- It requires a dedicated device driver API: :c:type:`struct
|
||||
ieee802154_radio_api`, which overloads :c:type:`struct
|
||||
net_if_api`. This is because 802.15.4 L2 needs more from the device
|
||||
driver than just send and recv functions. This dedicated API is
|
||||
declared in `include/net/ieee802154_radio.h`. Each and every IEEE
|
||||
802.15.4 device driver must provide a valid pointer on such
|
||||
relevantly filled-in API structure.
|
||||
|
||||
- Sending a packet is slightly particular. IEEE 802.15.4 sends
|
||||
relatively small frames, 127 bytes all inclusive: frame header,
|
||||
payload and frame checksum. Buffer fragments are meant to fit such
|
||||
frame size limitation. But a buffer containing an IPv6/UDP packet
|
||||
might have more than one fragment. In the Ethernet device driver, it
|
||||
is up to the driver to handle all fragments. IEEE 802.15.4 drivers
|
||||
handle only one fragment at a time. This is why the :c:type:`struct
|
||||
ieee802154_radio_api` requires a tx function pointer which differs
|
||||
from the :c:type:`struct net_if_api` send function pointer.
|
||||
Instead, the IEEE 802.15.4 L2, provides a generic
|
||||
:c:func:`ieee802154_radio_send()` meant to be given as
|
||||
:c:type:`struct net_if` send function. It turn, the implementation
|
||||
of :c:func:`ieee802154_radio_send()` will ensure the same behavior:
|
||||
sending one fragment at a time through :c:type:`struct
|
||||
ieee802154_radio_api` tx function, and un-referencing the buffer
|
||||
only when all the transmission were successful.
|
||||
|
||||
Each IEEE 802.15.4 device driver, in the end, will need to call
|
||||
`NET_DEVICE_INIT_INSTANCE()` that way:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
NET_DEVICE_INIT_INSTANCE(...,
|
||||
the_device_init_prio,
|
||||
&the_valid_ieee802154_radio_api_instance,
|
||||
IEEE802154_L2,
|
||||
NET_L2_GET_CTX_TYPE(IEEE802154_L2), 125);
|
|
@ -14,7 +14,7 @@ operation of the stacks and how they were implemented.
|
|||
ip-stack-migrate.rst
|
||||
ip-stack-architecture.rst
|
||||
networking-api-usage.rst
|
||||
l2-and-drivers.rst
|
||||
network-management-api.rst
|
||||
buffers.rst
|
||||
qemu_setup.rst
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ static void telnet_end_client_connection(void)
|
|||
|
||||
static int telnet_setup_out_buf(struct net_context *client)
|
||||
{
|
||||
out_buf = net_nbuf_get_tx(client);
|
||||
out_buf = net_nbuf_get_tx(client, K_FOREVER);
|
||||
if (!out_buf) {
|
||||
/* Cannot happen atm, nbuf waits indefinitely */
|
||||
return -ENOBUFS;
|
||||
|
@ -234,7 +234,7 @@ static inline bool telnet_send(void)
|
|||
struct line_buf *lb = telnet_rb_get_line_out();
|
||||
|
||||
if (lb) {
|
||||
net_nbuf_append(out_buf, lb->len, lb->buf);
|
||||
net_nbuf_append(out_buf, lb->len, lb->buf, K_FOREVER);
|
||||
|
||||
/* We reinitialize the line buffer */
|
||||
lb->len = 0;
|
||||
|
@ -258,7 +258,7 @@ static int telnet_console_out_nothing(int c)
|
|||
|
||||
static inline void telnet_command_send_reply(uint8_t *msg, uint16_t len)
|
||||
{
|
||||
net_nbuf_append(out_buf, len, msg);
|
||||
net_nbuf_append(out_buf, len, msg, K_FOREVER);
|
||||
|
||||
net_context_send(out_buf, telnet_sent_cb,
|
||||
K_NO_WAIT, NULL, NULL);
|
||||
|
|
|
@ -551,7 +551,7 @@ static int eth_enc28j60_rx(struct device *dev)
|
|||
lengthfr = frm_len;
|
||||
|
||||
/* Get the frame from the buffer */
|
||||
buf = net_nbuf_get_reserve_rx(0);
|
||||
buf = net_nbuf_get_reserve_rx(0, K_NO_WAIT);
|
||||
if (!buf) {
|
||||
SYS_LOG_ERR("Could not allocate rx buffer");
|
||||
goto done;
|
||||
|
@ -565,7 +565,7 @@ static int eth_enc28j60_rx(struct device *dev)
|
|||
size_t spi_frame_len;
|
||||
|
||||
/* Reserve a data frag to receive the frame */
|
||||
pkt_buf = net_nbuf_get_reserve_data(0);
|
||||
pkt_buf = net_nbuf_get_reserve_data(0, K_NO_WAIT);
|
||||
if (!pkt_buf) {
|
||||
SYS_LOG_ERR("Could not allocate data buffer");
|
||||
net_buf_unref(buf);
|
||||
|
|
|
@ -170,10 +170,11 @@
|
|||
|
||||
/* Receive filters enabled:
|
||||
* - Unicast
|
||||
* - Multicast
|
||||
* - Broadcast
|
||||
* - CRC Check
|
||||
*/
|
||||
#define ENC28J60_RECEIVE_FILTERS 0xA1
|
||||
#define ENC28J60_RECEIVE_FILTERS 0xA3
|
||||
|
||||
/* MAC configuration:
|
||||
* - Automatic Padding
|
||||
|
|
|
@ -145,7 +145,7 @@ static void eth_rx(struct device *iface)
|
|||
return;
|
||||
}
|
||||
|
||||
buf = net_nbuf_get_reserve_rx(0);
|
||||
buf = net_nbuf_get_reserve_rx(0, K_NO_WAIT);
|
||||
if (!buf) {
|
||||
/* We failed to get a receive buffer. We don't add
|
||||
* any further logging here because the allocator
|
||||
|
@ -162,7 +162,7 @@ static void eth_rx(struct device *iface)
|
|||
|
||||
if (sizeof(context->frame_buf) < frame_length) {
|
||||
SYS_LOG_ERR("frame too large (%d)\n", frame_length);
|
||||
net_buf_unref(buf);
|
||||
net_nbuf_unref(buf);
|
||||
status = ENET_ReadFrame(ENET, &context->enet_handle, NULL, 0);
|
||||
assert(status == kStatus_Success);
|
||||
return;
|
||||
|
@ -178,7 +178,7 @@ static void eth_rx(struct device *iface)
|
|||
if (status) {
|
||||
irq_unlock(imask);
|
||||
SYS_LOG_ERR("ENET_ReadFrame failed: %d\n", status);
|
||||
net_buf_unref(buf);
|
||||
net_nbuf_unref(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -188,11 +188,11 @@ static void eth_rx(struct device *iface)
|
|||
struct net_buf *pkt_buf;
|
||||
size_t frag_len;
|
||||
|
||||
pkt_buf = net_nbuf_get_reserve_data(0);
|
||||
pkt_buf = net_nbuf_get_reserve_data(0, K_NO_WAIT);
|
||||
if (!pkt_buf) {
|
||||
irq_unlock(imask);
|
||||
SYS_LOG_ERR("Failed to get fragment buf\n");
|
||||
net_buf_unref(buf);
|
||||
net_nbuf_unref(buf);
|
||||
assert(status == kStatus_Success);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ static int rx_descriptors_init(Gmac *gmac, struct gmac_queue *queue)
|
|||
rx_nbuf_list->tail = 0;
|
||||
|
||||
for (int i = 0; i < rx_desc_list->len; i++) {
|
||||
rx_buf = net_nbuf_get_reserve_data(0);
|
||||
rx_buf = net_nbuf_get_reserve_data(0, K_NO_WAIT);
|
||||
if (rx_buf == NULL) {
|
||||
free_rx_bufs(rx_nbuf_list);
|
||||
SYS_LOG_ERR("Failed to reserve data net buffers");
|
||||
|
@ -470,7 +470,7 @@ static struct net_buf *frame_get(struct gmac_queue *queue)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
rx_frame = net_nbuf_get_reserve_rx(0);
|
||||
rx_frame = net_nbuf_get_reserve_rx(0, K_NO_WAIT);
|
||||
|
||||
/* Process a frame */
|
||||
prev_frag = rx_frame;
|
||||
|
@ -509,7 +509,7 @@ static struct net_buf *frame_get(struct gmac_queue *queue)
|
|||
DCACHE_INVALIDATE(frag_data, frag_len);
|
||||
|
||||
/* Get a new data net buffer from the buffer pool */
|
||||
new_frag = net_nbuf_get_reserve_data(0);
|
||||
new_frag = net_nbuf_get_reserve_data(0, K_NO_WAIT);
|
||||
if (new_frag == NULL) {
|
||||
queue->err_rx_frames_dropped++;
|
||||
net_buf_unref(rx_frame);
|
||||
|
|
|
@ -54,198 +54,20 @@ config SYS_LOG_IEEE802154_DRIVER_LEVEL
|
|||
|
||||
- 4 DEBUG, write SYS_LOG_DBG in adition to previous levels
|
||||
|
||||
config TI_CC2520
|
||||
bool "TI CC2520 Driver support"
|
||||
depends on NETWORKING
|
||||
select NET_L2_IEEE802154
|
||||
default n
|
||||
source "drivers/ieee802154/Kconfig.cc2520"
|
||||
|
||||
config TI_CC2520_RAW
|
||||
bool "TI CC2520 Driver RAW channel"
|
||||
select NET_L2_RAW_CHANNEL
|
||||
default n
|
||||
help
|
||||
Enable TI_CC2520 driver with RAW channel
|
||||
source "drivers/ieee802154/Kconfig.mcr20a"
|
||||
|
||||
The CC2520 driver with RAW channel allows to export radio interface
|
||||
over USB making an USB 802.15.4 dongle.
|
||||
|
||||
if TI_CC2520 || TI_CC2520_RAW
|
||||
|
||||
config TI_CC2520_DRV_NAME
|
||||
string "TI CC2520 Driver's name"
|
||||
default "cc2520"
|
||||
help
|
||||
This option sets the driver name
|
||||
|
||||
config TI_CC2520_SPI_DRV_NAME
|
||||
string "SPI driver's name to use to access CC2520"
|
||||
default ""
|
||||
help
|
||||
This option is mandatory to set which SPI controller to use in order
|
||||
to actually control the CC2520 chip.
|
||||
|
||||
config TI_CC2520_SPI_FREQ
|
||||
int "SPI system frequency"
|
||||
default 0
|
||||
help
|
||||
This option sets the SPI controller's frequency. Beware this value
|
||||
depends on the SPI controller being used and also on the system
|
||||
clock.
|
||||
|
||||
config TI_CC2520_SPI_SLAVE
|
||||
int "SPI slave linked to CC2520"
|
||||
default 0
|
||||
help
|
||||
This option sets the SPI slave number SPI controller has to switch
|
||||
to when dealing with CC2520 chip.
|
||||
|
||||
config TI_CC2520_RX_STACK_SIZE
|
||||
int "Driver's internal rx thread stack size"
|
||||
default 800
|
||||
help
|
||||
This option sets the driver's stack size for its internal rx thread.
|
||||
The default value should be sufficient, but in case it prooves to be
|
||||
a too little one, this option makes it easy to play with the size.
|
||||
|
||||
config TI_CC2520_INIT_PRIO
|
||||
int "CC2520 intialization priority"
|
||||
default 80
|
||||
help
|
||||
Set the initialization priority number. Do not mess with it unless
|
||||
you know what you are doing. Beware cc2520 requires gpio and spi to
|
||||
be ready first (and sometime gpio should be the very first as spi
|
||||
might need it too). And of course it has to start before the net stack.
|
||||
|
||||
endif
|
||||
|
||||
config UPIPE_15_4
|
||||
menuconfig IEEE802154_UPIPE
|
||||
bool "UART PIPE fake radio driver support for QEMU"
|
||||
depends on BOARD_QEMU_X86
|
||||
select NETWORKING
|
||||
select UART_PIPE
|
||||
default n
|
||||
|
||||
config UPIPE_15_4_DRV_NAME
|
||||
config IEEE802154_UPIPE_DRV_NAME
|
||||
string "UART PIPE Driver name"
|
||||
default "upipe_15_4"
|
||||
depends on UPIPE_15_4
|
||||
|
||||
config NXP_MCR20A
|
||||
bool "NXP MCR20A Driver support"
|
||||
depends on NETWORKING && SPI
|
||||
select NET_L2_IEEE802154
|
||||
default n
|
||||
|
||||
config NXP_MCR20A_RAW
|
||||
bool "NXP MCR20A Driver RAW channel"
|
||||
depends on SPI
|
||||
select NET_L2_RAW_CHANNEL
|
||||
default n
|
||||
help
|
||||
Enable NXP_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 NXP_MCR20A || NXP_MCR20A_RAW
|
||||
|
||||
config NXP_MCR20A_DRV_NAME
|
||||
string "NXP MCR20A Driver's name"
|
||||
default "mcr20a"
|
||||
help
|
||||
This option sets the driver name
|
||||
|
||||
config NXP_MCR20A_SPI_DRV_NAME
|
||||
string "SPI driver's name to use to access MCR20A"
|
||||
default SPI_0_NAME
|
||||
help
|
||||
This option is mandatory to set which SPI controller to use in order
|
||||
to actually control the MCR20A chip.
|
||||
|
||||
config NXP_MCR20A_SPI_FREQ
|
||||
int "SPI system frequency"
|
||||
default 4000000
|
||||
help
|
||||
This option sets the SPI controller's frequency. Beware this value
|
||||
depends on the SPI controller being used and also on the system
|
||||
clock.
|
||||
|
||||
config NXP_MCR20A_SPI_SLAVE
|
||||
int "SPI slave linked to MCR20A"
|
||||
default 0
|
||||
help
|
||||
This option sets the SPI slave number SPI controller has to switch
|
||||
to when dealing with MCR20A chip.
|
||||
|
||||
config MCR20A_GPIO_IRQ_B_NAME
|
||||
string "GPIO device used for IRQ_B output of MCR20A"
|
||||
default GPIO_MCUX_PORTB_NAME
|
||||
|
||||
config MCR20A_GPIO_IRQ_B_PIN
|
||||
int "GPIO pin connected to IRQ_B output of MCR20A"
|
||||
default 9
|
||||
|
||||
config MCR20A_GPIO_RESET_NAME
|
||||
string "GPIO device used for RESET input of MCR20A"
|
||||
default GPIO_MCUX_PORTA_NAME
|
||||
|
||||
config MCR20A_GPIO_RESET_PIN
|
||||
int "GPIO pin connected to RESET input of MCR20A"
|
||||
default 2
|
||||
|
||||
choice
|
||||
prompt "CLK_OUT frequency"
|
||||
default MCR20A_CLK_OUT_DISABLED
|
||||
help
|
||||
Configuration of the MCR20A clock output pin.
|
||||
|
||||
config MCR20A_CLK_OUT_DISABLED
|
||||
bool "Disabled"
|
||||
|
||||
config MCR20A_CLK_OUT_32MHZ
|
||||
bool "32 MHz"
|
||||
|
||||
config MCR20A_CLK_OUT_16MHZ
|
||||
bool "16 MHz"
|
||||
|
||||
config MCR20A_CLK_OUT_8MHZ
|
||||
bool "8 MHz"
|
||||
|
||||
config MCR20A_CLK_OUT_4MHZ
|
||||
bool "4 MHz"
|
||||
|
||||
config MCR20A_CLK_OUT_1MHZ
|
||||
bool "1 MHz"
|
||||
|
||||
config MCR20A_CLK_OUT_250KHZ
|
||||
bool "250 kHz"
|
||||
|
||||
config MCR20A_CLK_OUT_62500HZ
|
||||
bool "62500 Hz"
|
||||
|
||||
config MCR20A_CLK_OUT_32768HZ
|
||||
bool "32768 Hz"
|
||||
|
||||
endchoice
|
||||
|
||||
config NXP_MCR20A_RX_STACK_SIZE
|
||||
int "Driver's internal rx thread stack size"
|
||||
default 800
|
||||
help
|
||||
This option sets the driver's stack size for its internal rx thread.
|
||||
The default value should be sufficient, but in case it proves to be
|
||||
a too little one, this option makes it easy to play with the size.
|
||||
|
||||
config NXP_MCR20A_INIT_PRIO
|
||||
int "MCR20A intialization priority"
|
||||
default 80
|
||||
help
|
||||
Set the initialization priority number. Do not mess with it unless
|
||||
you know what you are doing. Beware mcr20a requires gpio and spi to
|
||||
be ready first (and sometime gpio should be the very first as spi
|
||||
might need it too). And of course it has to start before the net stack.
|
||||
|
||||
endif
|
||||
default "IEEE802154_UPIPE"
|
||||
depends on IEEE802154_UPIPE
|
||||
|
||||
endmenu
|
||||
|
|
67
drivers/ieee802154/Kconfig.cc2520
Normal file
67
drivers/ieee802154/Kconfig.cc2520
Normal file
|
@ -0,0 +1,67 @@
|
|||
# Kconfig.cc2520 - TI CC2520 configuration options
|
||||
#
|
||||
|
||||
menuconfig IEEE802154_CC2520
|
||||
bool "TI CC2520 Driver support"
|
||||
depends on NETWORKING
|
||||
select NET_L2_IEEE802154
|
||||
default n
|
||||
|
||||
menuconfig 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.
|
||||
|
||||
if IEEE802154_CC2520 || IEEE802154_CC2520_RAW
|
||||
|
||||
config IEEE802154_CC2520_DRV_NAME
|
||||
string "TI CC2520 Driver's name"
|
||||
default "cc2520"
|
||||
help
|
||||
This option sets the driver name
|
||||
|
||||
config IEEE802154_CC2520_SPI_DRV_NAME
|
||||
string "SPI driver's name to use to access CC2520"
|
||||
default ""
|
||||
help
|
||||
This option is mandatory to set which SPI controller to use in order
|
||||
to actually control the CC2520 chip.
|
||||
|
||||
config IEEE802154_CC2520_SPI_FREQ
|
||||
int "SPI system frequency"
|
||||
default 0
|
||||
help
|
||||
This option sets the SPI controller's frequency. Beware this value
|
||||
depends on the SPI controller being used and also on the system
|
||||
clock.
|
||||
|
||||
config IEEE802154_CC2520_SPI_SLAVE
|
||||
int "SPI slave linked to CC2520"
|
||||
default 0
|
||||
help
|
||||
This option sets the SPI slave number SPI controller has to switch
|
||||
to when dealing with CC2520 chip.
|
||||
|
||||
config IEEE802154_CC2520_RX_STACK_SIZE
|
||||
int "Driver's internal rx thread stack size"
|
||||
default 800
|
||||
help
|
||||
This option sets the driver's stack size for its internal rx thread.
|
||||
The default value should be sufficient, but in case it prooves to be
|
||||
a too little one, this option makes it easy to play with the size.
|
||||
|
||||
config IEEE802154_CC2520_INIT_PRIO
|
||||
int "CC2520 intialization priority"
|
||||
default 80
|
||||
help
|
||||
Set the initialization priority number. Do not mess with it unless
|
||||
you know what you are doing. Beware cc2520 requires gpio and spi to
|
||||
be ready first (and sometime gpio should be the very first as spi
|
||||
might need it too). And of course it has to start before the net stack.
|
||||
|
||||
endif
|
120
drivers/ieee802154/Kconfig.mcr20a
Normal file
120
drivers/ieee802154/Kconfig.mcr20a
Normal file
|
@ -0,0 +1,120 @@
|
|||
# Kconfig.mcr20a - NXP MCR20A configuration options
|
||||
#
|
||||
|
||||
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
|
||||
|
||||
config IEEE802154_MCR20A_DRV_NAME
|
||||
string "NXP MCR20A Driver's name"
|
||||
default "mcr20a"
|
||||
help
|
||||
This option sets the driver name
|
||||
|
||||
config IEEE802154_MCR20A_SPI_DRV_NAME
|
||||
string "SPI driver's name to use to access MCR20A"
|
||||
default SPI_0_NAME
|
||||
help
|
||||
This option is mandatory to set which SPI controller to use in order
|
||||
to actually control the MCR20A chip.
|
||||
|
||||
config IEEE802154_MCR20A_SPI_FREQ
|
||||
int "SPI system frequency"
|
||||
default 4000000
|
||||
help
|
||||
This option sets the SPI controller's frequency. Beware this value
|
||||
depends on the SPI controller being used and also on the system
|
||||
clock.
|
||||
|
||||
config IEEE802154_MCR20A_SPI_SLAVE
|
||||
int "SPI slave linked to MCR20A"
|
||||
default 0
|
||||
help
|
||||
This option sets the SPI slave number SPI controller has to switch
|
||||
to when dealing with MCR20A chip.
|
||||
|
||||
config MCR20A_GPIO_IRQ_B_NAME
|
||||
string "GPIO device used for IRQ_B output of MCR20A"
|
||||
default GPIO_MCUX_PORTB_NAME
|
||||
|
||||
config MCR20A_GPIO_IRQ_B_PIN
|
||||
int "GPIO pin connected to IRQ_B output of MCR20A"
|
||||
default 9
|
||||
|
||||
config MCR20A_GPIO_RESET_NAME
|
||||
string "GPIO device used for RESET input of MCR20A"
|
||||
default GPIO_MCUX_PORTA_NAME
|
||||
|
||||
config MCR20A_GPIO_RESET_PIN
|
||||
int "GPIO pin connected to RESET input of MCR20A"
|
||||
default 2
|
||||
|
||||
choice
|
||||
prompt "CLK_OUT frequency"
|
||||
default MCR20A_CLK_OUT_DISABLED
|
||||
help
|
||||
Configuration of the MCR20A clock output pin.
|
||||
|
||||
config MCR20A_CLK_OUT_DISABLED
|
||||
bool "Disabled"
|
||||
|
||||
config MCR20A_CLK_OUT_32MHZ
|
||||
bool "32 MHz"
|
||||
|
||||
config MCR20A_CLK_OUT_16MHZ
|
||||
bool "16 MHz"
|
||||
|
||||
config MCR20A_CLK_OUT_8MHZ
|
||||
bool "8 MHz"
|
||||
|
||||
config MCR20A_CLK_OUT_4MHZ
|
||||
bool "4 MHz"
|
||||
|
||||
config MCR20A_CLK_OUT_1MHZ
|
||||
bool "1 MHz"
|
||||
|
||||
config MCR20A_CLK_OUT_250KHZ
|
||||
bool "250 kHz"
|
||||
|
||||
config MCR20A_CLK_OUT_62500HZ
|
||||
bool "62500 Hz"
|
||||
|
||||
config MCR20A_CLK_OUT_32768HZ
|
||||
bool "32768 Hz"
|
||||
|
||||
endchoice
|
||||
|
||||
config IEEE802154_MCR20A_RX_STACK_SIZE
|
||||
int "Driver's internal rx thread stack size"
|
||||
default 800
|
||||
help
|
||||
This option sets the driver's stack size for its internal rx thread.
|
||||
The default value should be sufficient, but in case it proves to be
|
||||
a too little one, this option makes it easy to play with the size.
|
||||
|
||||
config IEEE802154_MCR20A_INIT_PRIO
|
||||
int "MCR20A intialization priority"
|
||||
default 80
|
||||
help
|
||||
Set the initialization priority number. Do not mess with it unless
|
||||
you know what you are doing. Beware mcr20a requires gpio and spi to
|
||||
be ready first (and sometime gpio should be the very first as spi
|
||||
might need it too). And of course it has to start before the net stack.
|
||||
|
||||
|
||||
endif
|
|
@ -1,5 +1,5 @@
|
|||
obj-$(CONFIG_TI_CC2520) += ieee802154_cc2520.o
|
||||
obj-$(CONFIG_TI_CC2520_RAW) += ieee802154_cc2520.o
|
||||
obj-$(CONFIG_UPIPE_15_4) += ieee802154_uart_pipe.o
|
||||
obj-$(CONFIG_NXP_MCR20A) += ieee802154_mcr20a.o
|
||||
obj-$(CONFIG_NXP_MCR20A_RAW) += ieee802154_mcr20a.o
|
||||
obj-$(CONFIG_IEEE802154_CC2520) += ieee802154_cc2520.o
|
||||
obj-$(CONFIG_IEEE802154_CC2520_RAW) += ieee802154_cc2520.o
|
||||
obj-$(CONFIG_IEEE802154_UPIPE) += ieee802154_uart_pipe.o
|
||||
obj-$(CONFIG_IEEE802154_MCR20A) += ieee802154_mcr20a.o
|
||||
obj-$(CONFIG_IEEE802154_MCR20A_RAW) += ieee802154_mcr20a.o
|
||||
|
|
|
@ -594,19 +594,19 @@ static void cc2520_rx(int arg)
|
|||
goto flush;
|
||||
}
|
||||
|
||||
buf = net_nbuf_get_reserve_rx(0);
|
||||
buf = net_nbuf_get_reserve_rx(0, K_NO_WAIT);
|
||||
if (!buf) {
|
||||
SYS_LOG_ERR("No buf available");
|
||||
goto flush;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_TI_CC2520_RAW)
|
||||
#if defined(CONFIG_IEEE802154_CC2520_RAW)
|
||||
/**
|
||||
* Reserve 1 byte for length
|
||||
*/
|
||||
pkt_buf = net_nbuf_get_reserve_data(1);
|
||||
pkt_buf = net_nbuf_get_reserve_data(1, K_NO_WAIT);
|
||||
#else
|
||||
pkt_buf = net_nbuf_get_reserve_data(0);
|
||||
pkt_buf = net_nbuf_get_reserve_data(0, K_NO_WAIT);
|
||||
#endif
|
||||
if (!pkt_buf) {
|
||||
SYS_LOG_ERR("No pkt_buf available");
|
||||
|
@ -615,7 +615,7 @@ static void cc2520_rx(int arg)
|
|||
|
||||
net_buf_frag_insert(buf, pkt_buf);
|
||||
|
||||
#if defined(CONFIG_TI_CC2520_RAW)
|
||||
#if defined(CONFIG_IEEE802154_CC2520_RAW)
|
||||
if (!read_rxfifo_content(&cc2520->spi, pkt_buf, pkt_len)) {
|
||||
SYS_LOG_ERR("No content read");
|
||||
goto flush;
|
||||
|
@ -651,7 +651,7 @@ static void cc2520_rx(int arg)
|
|||
goto out;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_TI_CC2520_RAW)
|
||||
#if defined(CONFIG_IEEE802154_CC2520_RAW)
|
||||
net_buf_add_u8(pkt_buf, cc2520->lqi);
|
||||
#endif
|
||||
|
||||
|
@ -665,7 +665,7 @@ static void cc2520_rx(int arg)
|
|||
|
||||
net_analyze_stack("CC2520 Rx Fiber stack",
|
||||
(unsigned char *)cc2520->cc2520_rx_stack,
|
||||
CONFIG_TI_CC2520_RX_STACK_SIZE);
|
||||
CONFIG_IEEE802154_CC2520_RX_STACK_SIZE);
|
||||
continue;
|
||||
flush:
|
||||
_cc2520_print_exceptions(cc2520);
|
||||
|
@ -990,16 +990,17 @@ static inline int configure_spi(struct device *dev)
|
|||
struct cc2520_context *cc2520 = dev->driver_data;
|
||||
struct spi_config spi_conf = {
|
||||
.config = SPI_WORD(8),
|
||||
.max_sys_freq = CONFIG_TI_CC2520_SPI_FREQ,
|
||||
.max_sys_freq = CONFIG_IEEE802154_CC2520_SPI_FREQ,
|
||||
};
|
||||
|
||||
cc2520->spi.dev = device_get_binding(CONFIG_TI_CC2520_SPI_DRV_NAME);
|
||||
cc2520->spi.dev = device_get_binding(
|
||||
CONFIG_IEEE802154_CC2520_SPI_DRV_NAME);
|
||||
if (!cc2520->spi.dev) {
|
||||
SYS_LOG_ERR("Unable to get SPI device");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
cc2520->spi.slave = CONFIG_TI_CC2520_SPI_SLAVE;
|
||||
cc2520->spi.slave = CONFIG_IEEE802154_CC2520_SPI_SLAVE;
|
||||
|
||||
if (spi_configure(cc2520->spi.dev, &spi_conf) != 0 ||
|
||||
spi_slave_select(cc2520->spi.dev,
|
||||
|
@ -1037,7 +1038,7 @@ static int cc2520_init(struct device *dev)
|
|||
}
|
||||
|
||||
k_thread_spawn(cc2520->cc2520_rx_stack,
|
||||
CONFIG_TI_CC2520_RX_STACK_SIZE,
|
||||
CONFIG_IEEE802154_CC2520_RX_STACK_SIZE,
|
||||
(k_thread_entry_t)cc2520_rx,
|
||||
dev, NULL, NULL,
|
||||
K_PRIO_COOP(2), 0, 0);
|
||||
|
@ -1080,21 +1081,21 @@ static struct ieee802154_radio_api cc2520_radio_api = {
|
|||
.get_lqi = cc2520_get_lqi,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_TI_CC2520_RAW)
|
||||
DEVICE_AND_API_INIT(cc2520, CONFIG_TI_CC2520_DRV_NAME,
|
||||
#if defined(CONFIG_IEEE802154_CC2520_RAW)
|
||||
DEVICE_AND_API_INIT(cc2520, CONFIG_IEEE802154_CC2520_DRV_NAME,
|
||||
cc2520_init, &cc2520_context_data, NULL,
|
||||
POST_KERNEL, CONFIG_TI_CC2520_INIT_PRIO,
|
||||
POST_KERNEL, CONFIG_IEEE802154_CC2520_INIT_PRIO,
|
||||
&cc2520_radio_api);
|
||||
#else
|
||||
NET_DEVICE_INIT(cc2520, CONFIG_TI_CC2520_DRV_NAME,
|
||||
NET_DEVICE_INIT(cc2520, CONFIG_IEEE802154_CC2520_DRV_NAME,
|
||||
cc2520_init, &cc2520_context_data, NULL,
|
||||
CONFIG_TI_CC2520_INIT_PRIO,
|
||||
CONFIG_IEEE802154_CC2520_INIT_PRIO,
|
||||
&cc2520_radio_api, IEEE802154_L2,
|
||||
NET_L2_GET_CTX_TYPE(IEEE802154_L2), 125);
|
||||
|
||||
NET_STACK_INFO_ADDR(RX, cc2520,
|
||||
CONFIG_TI_CC2520_RX_STACK_SIZE,
|
||||
CONFIG_TI_CC2520_RX_STACK_SIZE,
|
||||
CONFIG_IEEE802154_CC2520_RX_STACK_SIZE,
|
||||
CONFIG_IEEE802154_CC2520_RX_STACK_SIZE,
|
||||
((struct cc2520_context *)(&__device_cc2520))->
|
||||
cc2520_rx_stack,
|
||||
0);
|
||||
|
|
|
@ -40,7 +40,7 @@ struct cc2520_context {
|
|||
struct k_sem tx_sync;
|
||||
atomic_t tx;
|
||||
/************RX************/
|
||||
char __stack cc2520_rx_stack[CONFIG_TI_CC2520_RX_STACK_SIZE];
|
||||
char __stack cc2520_rx_stack[CONFIG_IEEE802154_CC2520_RX_STACK_SIZE];
|
||||
struct k_sem rx_lock;
|
||||
bool overflow;
|
||||
uint8_t lqi;
|
||||
|
|
|
@ -137,6 +137,8 @@ uint8_t _mcr20a_read_reg(struct mcr20a_spi *spi, bool dreg, uint8_t addr)
|
|||
{
|
||||
uint8_t len = dreg ? 2 : 3;
|
||||
|
||||
k_sem_take(&spi->spi_sem, K_FOREVER);
|
||||
|
||||
spi->cmd_buf[0] = dreg ? (MCR20A_REG_READ | addr) :
|
||||
(MCR20A_IAR_INDEX | MCR20A_REG_WRITE);
|
||||
spi->cmd_buf[1] = dreg ? 0 : (addr | MCR20A_REG_READ);
|
||||
|
@ -146,9 +148,12 @@ uint8_t _mcr20a_read_reg(struct mcr20a_spi *spi, bool dreg, uint8_t addr)
|
|||
|
||||
if (spi_transceive(spi->dev, spi->cmd_buf, len,
|
||||
spi->cmd_buf, len) == 0) {
|
||||
k_sem_give(&spi->spi_sem);
|
||||
return spi->cmd_buf[len - 1];
|
||||
}
|
||||
|
||||
k_sem_give(&spi->spi_sem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -157,6 +162,9 @@ bool _mcr20a_write_reg(struct mcr20a_spi *spi, bool dreg, uint8_t addr,
|
|||
uint8_t value)
|
||||
{
|
||||
uint8_t len = dreg ? 2 : 3;
|
||||
bool retval;
|
||||
|
||||
k_sem_take(&spi->spi_sem, K_FOREVER);
|
||||
|
||||
spi->cmd_buf[0] = dreg ? (MCR20A_REG_WRITE | addr) :
|
||||
(MCR20A_IAR_INDEX | MCR20A_REG_WRITE);
|
||||
|
@ -164,14 +172,21 @@ bool _mcr20a_write_reg(struct mcr20a_spi *spi, bool dreg, uint8_t addr,
|
|||
spi->cmd_buf[2] = dreg ? 0 : value;
|
||||
|
||||
spi_slave_select(spi->dev, spi->slave);
|
||||
retval = (spi_write(spi->dev, spi->cmd_buf, len) == 0);
|
||||
|
||||
return (spi_write(spi->dev, spi->cmd_buf, len) == 0);
|
||||
k_sem_give(&spi->spi_sem);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Write multiple bytes to direct or indirect register */
|
||||
bool _mcr20a_write_burst(struct mcr20a_spi *spi, bool dreg, uint16_t addr,
|
||||
uint8_t *data_buf, uint8_t len)
|
||||
{
|
||||
bool retval;
|
||||
|
||||
k_sem_take(&spi->spi_sem, K_FOREVER);
|
||||
|
||||
if ((len + 2) > sizeof(spi->cmd_buf)) {
|
||||
SYS_LOG_ERR("Buffer length too large");
|
||||
}
|
||||
|
@ -188,14 +203,19 @@ bool _mcr20a_write_burst(struct mcr20a_spi *spi, bool dreg, uint16_t addr,
|
|||
}
|
||||
|
||||
spi_slave_select(spi->dev, spi->slave);
|
||||
retval = (spi_write(spi->dev, spi->cmd_buf, len) == 0);
|
||||
|
||||
return (spi_write(spi->dev, spi->cmd_buf, len) == 0);
|
||||
k_sem_give(&spi->spi_sem);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Read multiple bytes from direct or indirect register */
|
||||
bool _mcr20a_read_burst(struct mcr20a_spi *spi, bool dreg, uint16_t addr,
|
||||
uint8_t *data_buf, uint8_t len)
|
||||
{
|
||||
k_sem_take(&spi->spi_sem, K_FOREVER);
|
||||
|
||||
if ((len + 2) > sizeof(spi->cmd_buf)) {
|
||||
SYS_LOG_ERR("Buffer length too large");
|
||||
}
|
||||
|
@ -213,6 +233,7 @@ bool _mcr20a_read_burst(struct mcr20a_spi *spi, bool dreg, uint16_t addr,
|
|||
|
||||
if (spi_transceive(spi->dev, spi->cmd_buf, len,
|
||||
spi->cmd_buf, len) != 0) {
|
||||
k_sem_give(&spi->spi_sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -222,6 +243,8 @@ bool _mcr20a_read_burst(struct mcr20a_spi *spi, bool dreg, uint16_t addr,
|
|||
memcpy(data_buf, &spi->cmd_buf[2], len - 2);
|
||||
}
|
||||
|
||||
k_sem_give(&spi->spi_sem);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -472,17 +495,21 @@ static inline bool read_rxfifo_content(struct mcr20a_spi *spi,
|
|||
return false;
|
||||
}
|
||||
|
||||
data[0] = MCR20A_BUF_READ;
|
||||
k_sem_take(&spi->spi_sem, K_FOREVER);
|
||||
|
||||
data[0] = MCR20A_BUF_READ;
|
||||
spi_slave_select(spi->dev, spi->slave);
|
||||
|
||||
if (spi_transceive(spi->dev, data, len+1, data, len+1) != 0) {
|
||||
k_sem_give(&spi->spi_sem);
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(buf->data, &data[1], len);
|
||||
net_buf_add(buf, len);
|
||||
|
||||
k_sem_give(&spi->spi_sem);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -497,20 +524,20 @@ static inline void mcr20a_rx(struct mcr20a_context *mcr20a)
|
|||
pkt_len = read_reg_rx_frm_len(&mcr20a->spi);
|
||||
pkt_len -= MCR20A_FCS_LENGTH;
|
||||
|
||||
buf = net_nbuf_get_reserve_rx(0);
|
||||
buf = net_nbuf_get_reserve_rx(0, K_NO_WAIT);
|
||||
if (!buf) {
|
||||
SYS_LOG_ERR("No buf available");
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NXP_MCR20A_RAW)
|
||||
#if defined(CONFIG_IEEE802154_MCR20A_RAW)
|
||||
/* TODO: Test raw mode */
|
||||
/**
|
||||
* Reserve 1 byte for length
|
||||
*/
|
||||
pkt_buf = net_nbuf_get_reserve_data(1);
|
||||
pkt_buf = net_nbuf_get_reserve_data(1, K_NO_WAIT);
|
||||
#else
|
||||
pkt_buf = net_nbuf_get_reserve_data(0);
|
||||
pkt_buf = net_nbuf_get_reserve_data(0, K_NO_WAIT);
|
||||
#endif
|
||||
if (!pkt_buf) {
|
||||
SYS_LOG_ERR("No pkt_buf available");
|
||||
|
@ -534,7 +561,7 @@ static inline void mcr20a_rx(struct mcr20a_context *mcr20a)
|
|||
pkt_len, mcr20a->lqi,
|
||||
mcr20a_get_rssi(mcr20a->lqi));
|
||||
|
||||
#if defined(CONFIG_NXP_MCR20A_RAW)
|
||||
#if defined(CONFIG_IEEE802154_MCR20A_RAW)
|
||||
net_buf_add_u8(pkt_buf, mcr20a->lqi);
|
||||
#endif
|
||||
|
||||
|
@ -545,7 +572,7 @@ static inline void mcr20a_rx(struct mcr20a_context *mcr20a)
|
|||
|
||||
net_analyze_stack("MCR20A Rx Fiber stack",
|
||||
mcr20a->mcr20a_rx_stack,
|
||||
CONFIG_NXP_MCR20A_RX_STACK_SIZE);
|
||||
CONFIG_IEEE802154_MCR20A_RX_STACK_SIZE);
|
||||
return;
|
||||
out:
|
||||
if (buf) {
|
||||
|
@ -1078,6 +1105,9 @@ static inline bool write_txfifo_content(struct mcr20a_spi *spi,
|
|||
uint8_t cmd[2 + MCR20A_PSDU_LENGTH];
|
||||
uint8_t payload_len = net_nbuf_ll_reserve(buf) + frag->len;
|
||||
uint8_t *payload = frag->data - net_nbuf_ll_reserve(buf);
|
||||
bool retval;
|
||||
|
||||
k_sem_take(&spi->spi_sem, K_FOREVER);
|
||||
|
||||
cmd[0] = MCR20A_BUF_WRITE;
|
||||
/**
|
||||
|
@ -1095,7 +1125,13 @@ static inline bool write_txfifo_content(struct mcr20a_spi *spi,
|
|||
|
||||
spi_slave_select(spi->dev, spi->slave);
|
||||
|
||||
return (spi_write(spi->dev, cmd, (2 + payload_len)) == 0);
|
||||
retval = (spi_transceive(spi->dev,
|
||||
cmd, (2 + payload_len),
|
||||
cmd, (2 + payload_len)) == 0);
|
||||
|
||||
k_sem_give(&spi->spi_sem);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int mcr20a_tx(struct device *dev,
|
||||
|
@ -1233,6 +1269,8 @@ static int mcr20a_update_overwrites(struct mcr20a_context *dev)
|
|||
goto error;
|
||||
}
|
||||
|
||||
k_sem_take(&spi->spi_sem, K_FOREVER);
|
||||
|
||||
for (uint8_t i = 0;
|
||||
i < sizeof(overwrites_indirect) / sizeof(overwrites_t);
|
||||
i++) {
|
||||
|
@ -1244,10 +1282,13 @@ static int mcr20a_update_overwrites(struct mcr20a_context *dev)
|
|||
spi_slave_select(spi->dev, spi->slave);
|
||||
|
||||
if (spi_write(spi->dev, spi->cmd_buf, 3)) {
|
||||
k_sem_give(&spi->spi_sem);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
k_sem_give(&spi->spi_sem);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
|
@ -1356,16 +1397,17 @@ static inline int configure_spi(struct device *dev)
|
|||
struct mcr20a_context *mcr20a = dev->driver_data;
|
||||
struct spi_config spi_conf = {
|
||||
.config = SPI_WORD(8),
|
||||
.max_sys_freq = CONFIG_NXP_MCR20A_SPI_FREQ,
|
||||
.max_sys_freq = CONFIG_IEEE802154_MCR20A_SPI_FREQ,
|
||||
};
|
||||
|
||||
mcr20a->spi.dev = device_get_binding(CONFIG_NXP_MCR20A_SPI_DRV_NAME);
|
||||
mcr20a->spi.dev = device_get_binding(
|
||||
CONFIG_IEEE802154_MCR20A_SPI_DRV_NAME);
|
||||
if (!mcr20a->spi.dev) {
|
||||
SYS_LOG_ERR("Unable to get SPI device");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mcr20a->spi.slave = CONFIG_NXP_MCR20A_SPI_SLAVE;
|
||||
mcr20a->spi.slave = CONFIG_IEEE802154_MCR20A_SPI_SLAVE;
|
||||
|
||||
if (spi_configure(mcr20a->spi.dev, &spi_conf) != 0 ||
|
||||
spi_slave_select(mcr20a->spi.dev,
|
||||
|
@ -1374,8 +1416,9 @@ static inline int configure_spi(struct device *dev)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
SYS_LOG_DBG("SPI configured %s, %d", CONFIG_NXP_MCR20A_SPI_DRV_NAME,
|
||||
CONFIG_NXP_MCR20A_SPI_SLAVE);
|
||||
SYS_LOG_DBG("SPI configured %s, %d",
|
||||
CONFIG_IEEE802154_MCR20A_SPI_DRV_NAME,
|
||||
CONFIG_IEEE802154_MCR20A_SPI_SLAVE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1384,6 +1427,9 @@ static int mcr20a_init(struct device *dev)
|
|||
{
|
||||
struct mcr20a_context *mcr20a = dev->driver_data;
|
||||
|
||||
k_sem_init(&mcr20a->spi.spi_sem, 0, UINT_MAX);
|
||||
k_sem_give(&mcr20a->spi.spi_sem);
|
||||
|
||||
atomic_set(&mcr20a->busy, 0);
|
||||
k_sem_init(&mcr20a->trig_sem, 0, UINT_MAX);
|
||||
|
||||
|
@ -1407,7 +1453,7 @@ static int mcr20a_init(struct device *dev)
|
|||
}
|
||||
|
||||
k_thread_spawn(mcr20a->mcr20a_rx_stack,
|
||||
CONFIG_NXP_MCR20A_RX_STACK_SIZE,
|
||||
CONFIG_IEEE802154_MCR20A_RX_STACK_SIZE,
|
||||
(k_thread_entry_t)mcr20a_thread_main,
|
||||
dev, NULL, NULL,
|
||||
K_PRIO_COOP(2), 0, 0);
|
||||
|
@ -1448,15 +1494,15 @@ static struct ieee802154_radio_api mcr20a_radio_api = {
|
|||
.get_lqi = mcr20a_get_lqi,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_NXP_MCR20A_RAW)
|
||||
DEVICE_AND_API_INIT(mcr20a, CONFIG_NXP_MCR20A_DRV_NAME,
|
||||
#if defined(CONFIG_IEEE802154_MCR20A_RAW)
|
||||
DEVICE_AND_API_INIT(mcr20a, CONFIG_IEEE802154_MCR20A_DRV_NAME,
|
||||
mcr20a_init, &mcr20a_context_data, NULL,
|
||||
POST_KERNEL, CONFIG_NXP_MCR20A_INIT_PRIO,
|
||||
POST_KERNEL, CONFIG_IEEE802154_MCR20A_INIT_PRIO,
|
||||
&mcr20a_radio_api);
|
||||
#else
|
||||
NET_DEVICE_INIT(mcr20a, CONFIG_NXP_MCR20A_DRV_NAME,
|
||||
NET_DEVICE_INIT(mcr20a, CONFIG_IEEE802154_MCR20A_DRV_NAME,
|
||||
mcr20a_init, &mcr20a_context_data, NULL,
|
||||
CONFIG_NXP_MCR20A_INIT_PRIO,
|
||||
CONFIG_IEEE802154_MCR20A_INIT_PRIO,
|
||||
&mcr20a_radio_api, IEEE802154_L2,
|
||||
NET_L2_GET_CTX_TYPE(IEEE802154_L2), 125);
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
struct mcr20a_spi {
|
||||
struct device *dev;
|
||||
uint32_t slave;
|
||||
struct k_sem spi_sem;
|
||||
/**
|
||||
* cmd_buf will use at most 9 bytes:
|
||||
* dummy bytes + 8 ieee address bytes
|
||||
|
@ -40,7 +41,7 @@ struct mcr20a_context {
|
|||
atomic_t busy;
|
||||
atomic_t seq_retval;
|
||||
/************RX************/
|
||||
char __stack mcr20a_rx_stack[CONFIG_NXP_MCR20A_RX_STACK_SIZE];
|
||||
char __stack mcr20a_rx_stack[CONFIG_IEEE802154_MCR20A_RX_STACK_SIZE];
|
||||
struct k_sem trig_sem;
|
||||
uint8_t lqi;
|
||||
};
|
||||
|
|
|
@ -54,13 +54,13 @@ static uint8_t *upipe_rx(uint8_t *buf, size_t *off)
|
|||
upipe->rx_buf[upipe->rx_off++] = *buf;
|
||||
|
||||
if (upipe->rx_len == upipe->rx_off) {
|
||||
nbuf = net_nbuf_get_reserve_rx(0);
|
||||
nbuf = net_nbuf_get_reserve_rx(0, K_NO_WAIT);
|
||||
if (!nbuf) {
|
||||
SYS_LOG_DBG("No buf available");
|
||||
goto flush;
|
||||
}
|
||||
|
||||
pkt_buf = net_nbuf_get_reserve_data(0);
|
||||
pkt_buf = net_nbuf_get_reserve_data(0, K_NO_WAIT);
|
||||
if (!pkt_buf) {
|
||||
SYS_LOG_DBG("No fragment available");
|
||||
goto out;
|
||||
|
@ -282,7 +282,7 @@ static struct ieee802154_radio_api upipe_radio_api = {
|
|||
.stop = upipe_stop,
|
||||
};
|
||||
|
||||
NET_DEVICE_INIT(upipe_15_4, CONFIG_UPIPE_15_4_DRV_NAME,
|
||||
NET_DEVICE_INIT(upipe_15_4, CONFIG_IEEE802154_UPIPE_DRV_NAME,
|
||||
upipe_init, &upipe_context_data, NULL,
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
||||
&upipe_radio_api, IEEE802154_L2,
|
||||
|
|
|
@ -267,12 +267,12 @@ static inline int slip_input_byte(struct slip_context *slip,
|
|||
}
|
||||
|
||||
if (!slip->rx) {
|
||||
slip->rx = net_nbuf_get_reserve_rx(0);
|
||||
slip->rx = net_nbuf_get_reserve_rx(0, K_NO_WAIT);
|
||||
if (!slip->rx) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
slip->last = net_nbuf_get_reserve_data(0);
|
||||
slip->last = net_nbuf_get_reserve_data(0, K_NO_WAIT);
|
||||
if (!slip->last) {
|
||||
net_nbuf_unref(slip->rx);
|
||||
slip->rx = NULL;
|
||||
|
@ -287,7 +287,7 @@ static inline int slip_input_byte(struct slip_context *slip,
|
|||
/* We need to allocate a new fragment */
|
||||
struct net_buf *frag;
|
||||
|
||||
frag = net_nbuf_get_reserve_data(0);
|
||||
frag = net_nbuf_get_reserve_data(0, K_NO_WAIT);
|
||||
if (!frag) {
|
||||
SYS_LOG_ERR("[%p] cannot allocate data fragment",
|
||||
slip);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
MCUX_DEVICE = $(shell echo $(CONFIG_SOC) | tr '[:lower:]' '[:upper:]')
|
||||
MCUX_CPU = CPU_$(subst $(DQUOTE),,$(CONFIG_SOC_PART_NUMBER))
|
||||
|
||||
ifdef CONFIG_NXP_MCR20A
|
||||
ifdef CONFIG_IEEE802154_MCR20A
|
||||
ZEPHYRINCLUDE += -I$(srctree)/ext/hal/nxp/mcux/components/mcr20a
|
||||
endif
|
||||
|
||||
|
|
|
@ -311,34 +311,40 @@ static inline void net_nbuf_set_src_ipv6_addr(struct net_buf *buf)
|
|||
*/
|
||||
|
||||
struct net_buf *net_nbuf_get_rx_debug(struct net_context *context,
|
||||
int32_t timeout,
|
||||
const char *caller, int line);
|
||||
#define net_nbuf_get_rx(context) \
|
||||
net_nbuf_get_rx_debug(context, __func__, __LINE__)
|
||||
#define net_nbuf_get_rx(context, timeout) \
|
||||
net_nbuf_get_rx_debug(context, timeout, __func__, __LINE__)
|
||||
|
||||
struct net_buf *net_nbuf_get_tx_debug(struct net_context *context,
|
||||
int32_t timeout,
|
||||
const char *caller, int line);
|
||||
#define net_nbuf_get_tx(context) \
|
||||
net_nbuf_get_tx_debug(context, __func__, __LINE__)
|
||||
#define net_nbuf_get_tx(context, timeout) \
|
||||
net_nbuf_get_tx_debug(context, timeout, __func__, __LINE__)
|
||||
|
||||
struct net_buf *net_nbuf_get_data_debug(struct net_context *context,
|
||||
int32_t timeout,
|
||||
const char *caller, int line);
|
||||
#define net_nbuf_get_data(context) \
|
||||
net_nbuf_get_data_debug(context, __func__, __LINE__)
|
||||
#define net_nbuf_get_data(context, timeout) \
|
||||
net_nbuf_get_data_debug(context, timeout, __func__, __LINE__)
|
||||
|
||||
struct net_buf *net_nbuf_get_reserve_rx_debug(uint16_t reserve_head,
|
||||
int32_t timeout,
|
||||
const char *caller, int line);
|
||||
#define net_nbuf_get_reserve_rx(res) \
|
||||
net_nbuf_get_reserve_rx_debug(res, __func__, __LINE__)
|
||||
#define net_nbuf_get_reserve_rx(res, timeout) \
|
||||
net_nbuf_get_reserve_rx_debug(res, timeout, __func__, __LINE__)
|
||||
|
||||
struct net_buf *net_nbuf_get_reserve_tx_debug(uint16_t reserve_head,
|
||||
int32_t timeout,
|
||||
const char *caller, int line);
|
||||
#define net_nbuf_get_reserve_tx(res) \
|
||||
net_nbuf_get_reserve_tx_debug(res, __func__, __LINE__)
|
||||
#define net_nbuf_get_reserve_tx(res, timeout) \
|
||||
net_nbuf_get_reserve_tx_debug(res, timeout, __func__, __LINE__)
|
||||
|
||||
struct net_buf *net_nbuf_get_reserve_data_debug(uint16_t reserve_head,
|
||||
int32_t timeout,
|
||||
const char *caller, int line);
|
||||
#define net_nbuf_get_reserve_data(res) \
|
||||
net_nbuf_get_reserve_data_debug(res, __func__, __LINE__)
|
||||
#define net_nbuf_get_reserve_data(res, timeout) \
|
||||
net_nbuf_get_reserve_data_debug(res, timeout, __func__, __LINE__)
|
||||
|
||||
void net_nbuf_unref_debug(struct net_buf *buf, const char *caller, int line);
|
||||
#define net_nbuf_unref(buf) net_nbuf_unref_debug(buf, __func__, __LINE__)
|
||||
|
@ -369,10 +375,15 @@ void net_nbuf_print_frags(struct net_buf *buf);
|
|||
*
|
||||
* @param context Network context that will be related to
|
||||
* this buffer.
|
||||
* @param timeout Affects the action taken should the net buf pool be empty.
|
||||
* If K_NO_WAIT, then return immediately. If K_FOREVER, then
|
||||
* wait as long as necessary. Otherwise, wait up to the specified
|
||||
* number of milliseconds before timing out.
|
||||
*
|
||||
* @return Network buffer if successful, NULL otherwise.
|
||||
*/
|
||||
struct net_buf *net_nbuf_get_rx(struct net_context *context);
|
||||
struct net_buf *net_nbuf_get_rx(struct net_context *context,
|
||||
int32_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Get buffer from the TX buffers pool.
|
||||
|
@ -382,10 +393,15 @@ struct net_buf *net_nbuf_get_rx(struct net_context *context);
|
|||
*
|
||||
* @param context Network context that will be related to
|
||||
* this buffer.
|
||||
* @param timeout Affects the action taken should the net buf pool be empty.
|
||||
* If K_NO_WAIT, then return immediately. If K_FOREVER, then
|
||||
* wait as long as necessary. Otherwise, wait up to the specified
|
||||
* number of milliseconds before timing out.
|
||||
*
|
||||
* @return Network buffer if successful, NULL otherwise.
|
||||
*/
|
||||
struct net_buf *net_nbuf_get_tx(struct net_context *context);
|
||||
struct net_buf *net_nbuf_get_tx(struct net_context *context,
|
||||
int32_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Get buffer from the DATA buffers pool.
|
||||
|
@ -395,10 +411,15 @@ struct net_buf *net_nbuf_get_tx(struct net_context *context);
|
|||
*
|
||||
* @param context Network context that will be related to
|
||||
* this buffer.
|
||||
* @param timeout Affects the action taken should the net buf pool be empty.
|
||||
* If K_NO_WAIT, then return immediately. If K_FOREVER, then
|
||||
* wait as long as necessary. Otherwise, wait up to the specified
|
||||
* number of milliseconds before timing out.
|
||||
*
|
||||
* @return Network buffer if successful, NULL otherwise.
|
||||
*/
|
||||
struct net_buf *net_nbuf_get_data(struct net_context *context);
|
||||
struct net_buf *net_nbuf_get_data(struct net_context *context,
|
||||
int32_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Get RX buffer from pool but also reserve headroom for
|
||||
|
@ -408,10 +429,15 @@ struct net_buf *net_nbuf_get_data(struct net_context *context);
|
|||
* but is mainly used by network fragmentation code.
|
||||
*
|
||||
* @param reserve_head How many bytes to reserve for headroom.
|
||||
* @param timeout Affects the action taken should the net buf pool be empty.
|
||||
* If K_NO_WAIT, then return immediately. If K_FOREVER, then
|
||||
* wait as long as necessary. Otherwise, wait up to the specified
|
||||
* number of milliseconds before timing out.
|
||||
*
|
||||
* @return Network buffer if successful, NULL otherwise.
|
||||
*/
|
||||
struct net_buf *net_nbuf_get_reserve_rx(uint16_t reserve_head);
|
||||
struct net_buf *net_nbuf_get_reserve_rx(uint16_t reserve_head,
|
||||
int32_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Get TX buffer from pool but also reserve headroom for
|
||||
|
@ -421,10 +447,15 @@ struct net_buf *net_nbuf_get_reserve_rx(uint16_t reserve_head);
|
|||
* but is mainly used by network fragmentation code.
|
||||
*
|
||||
* @param reserve_head How many bytes to reserve for headroom.
|
||||
* @param timeout Affects the action taken should the net buf pool be empty.
|
||||
* If K_NO_WAIT, then return immediately. If K_FOREVER, then
|
||||
* wait as long as necessary. Otherwise, wait up to the specified
|
||||
* number of milliseconds before timing out.
|
||||
*
|
||||
* @return Network buffer if successful, NULL otherwise.
|
||||
*/
|
||||
struct net_buf *net_nbuf_get_reserve_tx(uint16_t reserve_head);
|
||||
struct net_buf *net_nbuf_get_reserve_tx(uint16_t reserve_head,
|
||||
int32_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Get DATA buffer from pool but also reserve headroom for
|
||||
|
@ -434,10 +465,15 @@ struct net_buf *net_nbuf_get_reserve_tx(uint16_t reserve_head);
|
|||
* but is mainly used by network fragmentation code.
|
||||
*
|
||||
* @param reserve_head How many bytes to reserve for headroom.
|
||||
* @param timeout Affects the action taken should the net buf pool be empty.
|
||||
* If K_NO_WAIT, then return immediately. If K_FOREVER, then
|
||||
* wait as long as necessary. Otherwise, wait up to the specified
|
||||
* number of milliseconds before timing out.
|
||||
*
|
||||
* @return Network buffer if successful, NULL otherwise.
|
||||
*/
|
||||
struct net_buf *net_nbuf_get_reserve_data(uint16_t reserve_head);
|
||||
struct net_buf *net_nbuf_get_reserve_data(uint16_t reserve_head,
|
||||
int32_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Place buffer back into the available buffers pool.
|
||||
|
@ -477,11 +513,15 @@ struct net_buf *net_nbuf_ref(struct net_buf *buf);
|
|||
* @param reserve Amount of extra data (this is not link layer header) in the
|
||||
* first data fragment that is returned. The function will copy the original
|
||||
* buffer right after the reserved bytes in the first destination fragment.
|
||||
* @param timeout Affects the action taken should the net buf pool be empty.
|
||||
* If K_NO_WAIT, then return immediately. If K_FOREVER, then
|
||||
* wait as long as necessary. Otherwise, wait up to the specified
|
||||
* number of milliseconds before timing out.
|
||||
*
|
||||
* @return New fragment list if successful, NULL otherwise.
|
||||
*/
|
||||
struct net_buf *net_nbuf_copy(struct net_buf *buf, size_t amount,
|
||||
size_t reserve);
|
||||
size_t reserve, int32_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Copy a buffer with fragments while reserving some extra space
|
||||
|
@ -492,27 +532,32 @@ struct net_buf *net_nbuf_copy(struct net_buf *buf, size_t amount,
|
|||
* @param reserve Amount of extra data (this is not link layer header) in the
|
||||
* first data fragment that is returned. The function will copy the original
|
||||
* buffer right after the reserved bytes in the first destination fragment.
|
||||
* @param timeout Affects the action taken should the net buf pool be empty.
|
||||
* If K_NO_WAIT, then return immediately. If K_FOREVER, then
|
||||
* wait as long as necessary. Otherwise, wait up to the specified
|
||||
* number of milliseconds before timing out.
|
||||
*
|
||||
* @return New fragment list if successful, NULL otherwise.
|
||||
*/
|
||||
static inline struct net_buf *net_nbuf_copy_all(struct net_buf *buf,
|
||||
size_t reserve)
|
||||
size_t reserve,
|
||||
int32_t timeout)
|
||||
{
|
||||
return net_nbuf_copy(buf, net_buf_frags_len(buf), reserve);
|
||||
return net_nbuf_copy(buf, net_buf_frags_len(buf), reserve, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief net_nbuf_linear_copy Copy len bytes from src starting from
|
||||
* offset to dst
|
||||
* @details This routine assumes that dst is conformed by
|
||||
* one fragment with enough space to store len
|
||||
* bytes starting from offset at src.
|
||||
* @param dst Destination buffer
|
||||
* @param src Source buffer that may be fragmented
|
||||
* @param offset Starting point to copy from
|
||||
* @param len Number of bytes to copy
|
||||
* @return 0 on success
|
||||
* @return -ENOMEM on error
|
||||
* @brief Copy len bytes from src starting from offset to dst
|
||||
*
|
||||
* This routine assumes that dst is conformed by one fragment with enough space
|
||||
* to store @a len bytes starting from offset at src.
|
||||
*
|
||||
* @param dst Destination buffer
|
||||
* @param src Source buffer that may be fragmented
|
||||
* @param offset Starting point to copy from
|
||||
* @param len Number of bytes to copy
|
||||
* @return 0 on success
|
||||
* @return -ENOMEM on error
|
||||
*/
|
||||
int net_nbuf_linear_copy(struct net_buf *dst, struct net_buf *src,
|
||||
uint16_t offset, uint16_t len);
|
||||
|
@ -521,12 +566,13 @@ int net_nbuf_linear_copy(struct net_buf *dst, struct net_buf *src,
|
|||
* @brief Compact the fragment list.
|
||||
*
|
||||
* @details After this there is no more any free space in individual fragments.
|
||||
* @param buf Network buffer fragment. This should be the first fragment (data)
|
||||
* in the fragment list.
|
||||
* @param buf Network buffer fragment. This should be the Tx/Rx buffer.
|
||||
*
|
||||
* @return True if compact success, False otherwise. (Note that it fails only
|
||||
* when input is data fragment)
|
||||
*
|
||||
* @return Pointer to the start of the fragment list if ok, NULL otherwise.
|
||||
*/
|
||||
struct net_buf *net_nbuf_compact(struct net_buf *buf);
|
||||
bool net_nbuf_compact(struct net_buf *buf);
|
||||
|
||||
/**
|
||||
* @brief Check if the buffer chain is compact or not.
|
||||
|
@ -542,24 +588,6 @@ struct net_buf *net_nbuf_compact(struct net_buf *buf);
|
|||
*/
|
||||
bool net_nbuf_is_compact(struct net_buf *buf);
|
||||
|
||||
/**
|
||||
* @brief Create some more space in front of the fragment list.
|
||||
*
|
||||
* @details After this there is more space available before the first
|
||||
* fragment. The existing data needs to be moved "down" which will
|
||||
* cause a cascading effect on fragment list because fragments are fixed
|
||||
* size.
|
||||
*
|
||||
* @param parent Pointer to parent of the network buffer. If there is
|
||||
* no parent, then set this parameter NULL.
|
||||
* @param buf Network buffer
|
||||
* @param amount Amount of data that is needed in front of the fragment list.
|
||||
*
|
||||
* @return Pointer to the start of the fragment list if ok, NULL otherwise.
|
||||
*/
|
||||
struct net_buf *net_nbuf_push(struct net_buf *parent, struct net_buf *buf,
|
||||
size_t amount);
|
||||
|
||||
/**
|
||||
* @brief Remove given amount of data from the beginning of fragment list.
|
||||
* This is similar thing to do as in net_buf_pull() but this function changes
|
||||
|
@ -583,12 +611,17 @@ struct net_buf *net_nbuf_pull(struct net_buf *buf, size_t amount);
|
|||
* @param buf Network buffer fragment list.
|
||||
* @param len Total length of input data
|
||||
* @param data Data to be added
|
||||
* @param timeout Affects the action taken should the net buf pool be empty.
|
||||
* If K_NO_WAIT, then return immediately. If K_FOREVER, then
|
||||
* wait as long as necessary. Otherwise, wait up to the specified
|
||||
* number of milliseconds before timing out.
|
||||
*
|
||||
* @return True if all the data is placed at end of fragment list,
|
||||
* False otherwise (In-case of false buf might contain input
|
||||
* data in the process of placing into fragments).
|
||||
*/
|
||||
bool net_nbuf_append(struct net_buf *buf, uint16_t len, uint8_t *data);
|
||||
bool net_nbuf_append(struct net_buf *buf, uint16_t len, uint8_t *data,
|
||||
int32_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Append uint8_t data to last fragment in fragment list
|
||||
|
@ -606,7 +639,7 @@ bool net_nbuf_append(struct net_buf *buf, uint16_t len, uint8_t *data);
|
|||
*/
|
||||
static inline bool net_nbuf_append_u8(struct net_buf *buf, uint8_t data)
|
||||
{
|
||||
return net_nbuf_append(buf, 1, &data);
|
||||
return net_nbuf_append(buf, 1, &data, K_FOREVER);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -627,7 +660,8 @@ static inline bool net_nbuf_append_be16(struct net_buf *buf, uint16_t data)
|
|||
{
|
||||
uint16_t value = sys_cpu_to_be16(data);
|
||||
|
||||
return net_nbuf_append(buf, sizeof(uint16_t), (uint8_t *)&value);
|
||||
return net_nbuf_append(buf, sizeof(uint16_t), (uint8_t *)&value,
|
||||
K_FOREVER);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -648,7 +682,8 @@ static inline bool net_nbuf_append_be32(struct net_buf *buf, uint32_t data)
|
|||
{
|
||||
uint32_t value = sys_cpu_to_be32(data);
|
||||
|
||||
return net_nbuf_append(buf, sizeof(uint32_t), (uint8_t *)&value);
|
||||
return net_nbuf_append(buf, sizeof(uint32_t), (uint8_t *)&value,
|
||||
K_FOREVER);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -770,23 +805,23 @@ struct net_buf *net_nbuf_read_be32(struct net_buf *buf, uint16_t offset,
|
|||
* e.g. Buf(Tx/Rx) - Frag1 - Frag2 - Frag3 - Frag4
|
||||
* (Assume FRAG DATA SIZE is 100 bytes after link layer header)
|
||||
*
|
||||
* 1) net_nbuf_write(buf, frag2, 20, &pos, 20, data)
|
||||
* 1) net_nbuf_write(buf, frag2, 20, &pos, 20, data, K_FOREVER)
|
||||
* In this case write starts from "frag2->data + 20",
|
||||
* returns frag2, pos = 40
|
||||
*
|
||||
* 2) net_nbuf_write(buf, frag1, 150, &pos, 60, data)
|
||||
* 2) net_nbuf_write(buf, frag1, 150, &pos, 60, data, K_FOREVER)
|
||||
* In this case write starts from "frag2->data + 50"
|
||||
* returns frag3, pos = 10
|
||||
*
|
||||
* 3) net_nbuf_write(buf, frag1, 350, &pos, 30, data)
|
||||
* 3) net_nbuf_write(buf, frag1, 350, &pos, 30, data, K_FOREVER)
|
||||
* In this case write starts from "frag4->data + 50"
|
||||
* returns frag4, pos = 80
|
||||
*
|
||||
* 4) net_nbuf_write(buf, frag2, 110, &pos, 90, data)
|
||||
* 4) net_nbuf_write(buf, frag2, 110, &pos, 90, data, K_FOREVER)
|
||||
* In this case write starts from "frag3->data + 10"
|
||||
* returns frag4, pos = 0
|
||||
*
|
||||
* 5) net_nbuf_write(buf, frag4, 110, &pos, 20, data)
|
||||
* 5) net_nbuf_write(buf, frag4, 110, &pos, 20, data, K_FOREVER)
|
||||
* In this case write creates new data fragment and starts from
|
||||
* "frag5->data + 10"
|
||||
* returns frag5, pos = 30
|
||||
|
@ -801,13 +836,17 @@ struct net_buf *net_nbuf_read_be32(struct net_buf *buf, uint16_t offset,
|
|||
* relative to return fragment)
|
||||
* @param len Length of the data to be written.
|
||||
* @param data Data to be written
|
||||
* @param timeout Affects the action taken should the net buf pool be empty.
|
||||
* If K_NO_WAIT, then return immediately. If K_FOREVER, then
|
||||
* wait as long as necessary. Otherwise, wait up to the specified
|
||||
* number of milliseconds before timing out.
|
||||
*
|
||||
* @return Pointer to the fragment and position (*pos) where write ended,
|
||||
* NULL and pos is 0xffff otherwise.
|
||||
*/
|
||||
struct net_buf *net_nbuf_write(struct net_buf *buf, struct net_buf *frag,
|
||||
uint16_t offset, uint16_t *pos, uint16_t len,
|
||||
uint8_t *data);
|
||||
uint8_t *data, int32_t timeout);
|
||||
|
||||
/* Write uint8_t data to an arbitrary offset in fragment. */
|
||||
static inline struct net_buf *net_nbuf_write_u8(struct net_buf *buf,
|
||||
|
@ -816,7 +855,8 @@ static inline struct net_buf *net_nbuf_write_u8(struct net_buf *buf,
|
|||
uint16_t *pos,
|
||||
uint8_t data)
|
||||
{
|
||||
return net_nbuf_write(buf, frag, offset, pos, sizeof(uint8_t), &data);
|
||||
return net_nbuf_write(buf, frag, offset, pos, sizeof(uint8_t),
|
||||
&data, K_FOREVER);
|
||||
}
|
||||
|
||||
/* Write uint16_t big endian value to an arbitrary offset in fragment. */
|
||||
|
@ -829,7 +869,7 @@ static inline struct net_buf *net_nbuf_write_be16(struct net_buf *buf,
|
|||
uint16_t value = htons(data);
|
||||
|
||||
return net_nbuf_write(buf, frag, offset, pos, sizeof(uint16_t),
|
||||
(uint8_t *)&value);
|
||||
(uint8_t *)&value, K_FOREVER);
|
||||
}
|
||||
|
||||
/* Write uint32_t big endian value to an arbitrary offset in fragment. */
|
||||
|
@ -842,7 +882,7 @@ static inline struct net_buf *net_nbuf_write_be32(struct net_buf *buf,
|
|||
uint32_t value = htonl(data);
|
||||
|
||||
return net_nbuf_write(buf, frag, offset, pos, sizeof(uint32_t),
|
||||
(uint8_t *)&value);
|
||||
(uint8_t *)&value, K_FOREVER);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -862,18 +902,26 @@ static inline struct net_buf *net_nbuf_write_be32(struct net_buf *buf,
|
|||
* @param offset Offset of fragment where insertion will start.
|
||||
* @param len Length of the data to be inserted.
|
||||
* @param data Data to be inserted
|
||||
* @param timeout Affects the action taken should the net buf pool be empty.
|
||||
* If K_NO_WAIT, then return immediately. If K_FOREVER, then
|
||||
* wait as long as necessary. Otherwise, wait up to the specified
|
||||
* number of milliseconds before timing out.
|
||||
*
|
||||
* @return True on success,
|
||||
* False otherwise.
|
||||
*/
|
||||
bool net_nbuf_insert(struct net_buf *buf, struct net_buf *frag,
|
||||
uint16_t offset, uint16_t len, uint8_t *data);
|
||||
uint16_t offset, uint16_t len, uint8_t *data,
|
||||
int32_t timeout);
|
||||
|
||||
/* Insert uint8_t data at an arbitrary offset in a series of fragments. */
|
||||
static inline bool net_nbuf_insert_u8(struct net_buf *buf, struct net_buf *frag,
|
||||
uint16_t offset, uint8_t data)
|
||||
static inline bool net_nbuf_insert_u8(struct net_buf *buf,
|
||||
struct net_buf *frag,
|
||||
uint16_t offset,
|
||||
uint8_t data)
|
||||
{
|
||||
return net_nbuf_insert(buf, frag, offset, sizeof(uint8_t), &data);
|
||||
return net_nbuf_insert(buf, frag, offset, sizeof(uint8_t), &data,
|
||||
K_FOREVER);
|
||||
}
|
||||
|
||||
/* Insert uint16_t big endian value at an arbitrary offset in a series of
|
||||
|
@ -881,12 +929,13 @@ static inline bool net_nbuf_insert_u8(struct net_buf *buf, struct net_buf *frag,
|
|||
*/
|
||||
static inline bool net_nbuf_insert_be16(struct net_buf *buf,
|
||||
struct net_buf *frag,
|
||||
uint16_t offset, uint16_t data)
|
||||
uint16_t offset,
|
||||
uint16_t data)
|
||||
{
|
||||
uint16_t value = htons(data);
|
||||
|
||||
return net_nbuf_insert(buf, frag, offset, sizeof(uint16_t),
|
||||
(uint8_t *)&value);
|
||||
(uint8_t *)&value, K_FOREVER);
|
||||
}
|
||||
|
||||
/* Insert uint32_t big endian value at an arbitrary offset in a series of
|
||||
|
@ -894,12 +943,13 @@ static inline bool net_nbuf_insert_be16(struct net_buf *buf,
|
|||
*/
|
||||
static inline bool net_nbuf_insert_be32(struct net_buf *buf,
|
||||
struct net_buf *frag,
|
||||
uint16_t offset, uint32_t data)
|
||||
uint16_t offset,
|
||||
uint32_t data)
|
||||
{
|
||||
uint32_t value = htonl(data);
|
||||
|
||||
return net_nbuf_insert(buf, frag, offset, sizeof(uint32_t),
|
||||
(uint8_t *)&value);
|
||||
(uint8_t *)&value, K_FOREVER);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -145,7 +145,7 @@ static struct net_buf *build_reply_buf(const char *name,
|
|||
printk("%s received %d bytes", name,
|
||||
net_nbuf_appdatalen(buf));
|
||||
|
||||
reply_buf = net_nbuf_get_tx(context);
|
||||
reply_buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
|
||||
recv_len = net_buf_frags_len(buf->frags);
|
||||
|
||||
|
|
|
@ -58,12 +58,12 @@ int udp_tx(void *context, const unsigned char *buf, size_t size)
|
|||
|
||||
udp_ctx = ctx->net_ctx;
|
||||
|
||||
send_buf = net_nbuf_get_tx(udp_ctx);
|
||||
send_buf = net_nbuf_get_tx(udp_ctx, K_FOREVER);
|
||||
if (!send_buf) {
|
||||
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
rc = net_nbuf_append(send_buf, size, (uint8_t *) buf);
|
||||
rc = net_nbuf_append(send_buf, size, (uint8_t *) buf, K_FOREVER);
|
||||
if (!rc) {
|
||||
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
}
|
||||
|
|
|
@ -47,13 +47,13 @@ int udp_tx(void *context, const unsigned char *buf, size_t size)
|
|||
|
||||
net_ctx = ctx->net_ctx;
|
||||
|
||||
send_buf = net_nbuf_get_tx(net_ctx);
|
||||
send_buf = net_nbuf_get_tx(net_ctx, K_FOREVER);
|
||||
if (!send_buf) {
|
||||
printk("cannot create buf\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rc = net_nbuf_append(send_buf, size, (uint8_t *) buf);
|
||||
rc = net_nbuf_append(send_buf, size, (uint8_t *) buf, K_FOREVER);
|
||||
if (!rc) {
|
||||
printk("cannot write buf\n");
|
||||
return -EIO;
|
||||
|
|
|
@ -36,8 +36,8 @@ CONFIG_NET_L2_IEEE802154_ORFD=y
|
|||
CONFIG_NET_L2_IEEE802154_FRAGMENT=y
|
||||
CONFIG_NET_DEBUG_L2_IEEE802154_FRAGMENT=y
|
||||
|
||||
CONFIG_TI_CC2520=y
|
||||
CONFIG_TI_CC2520_AUTO_ACK=y
|
||||
CONFIG_IEEE802154_CC2520=y
|
||||
CONFIG_IEEE802154_CC2520_AUTO_ACK=y
|
||||
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=1
|
||||
|
||||
CONFIG_GPIO=y
|
||||
|
@ -47,6 +47,6 @@ CONFIG_SPI_1=y
|
|||
CONFIG_SPI_CS_GPIO=y
|
||||
CONFIG_SPI_1_CS_GPIO_PORT="GPIO_0"
|
||||
CONFIG_SPI_1_CS_GPIO_PIN=0
|
||||
CONFIG_TI_CC2520_SPI_DRV_NAME="SPI_1"
|
||||
CONFIG_TI_CC2520_SPI_FREQ=4
|
||||
CONFIG_TI_CC2520_SPI_SLAVE=1
|
||||
CONFIG_IEEE802154_CC2520_SPI_DRV_NAME="SPI_1"
|
||||
CONFIG_IEEE802154_CC2520_SPI_FREQ=4
|
||||
CONFIG_IEEE802154_CC2520_SPI_SLAVE=1
|
|
@ -38,8 +38,8 @@ CONFIG_NET_L2_IEEE802154_ORFD=y
|
|||
CONFIG_NET_L2_IEEE802154_FRAGMENT=y
|
||||
CONFIG_NET_DEBUG_L2_IEEE802154_FRAGMENT=y
|
||||
|
||||
CONFIG_TI_CC2520=y
|
||||
CONFIG_TI_CC2520_AUTO_ACK=y
|
||||
CONFIG_IEEE802154_CC2520=y
|
||||
CONFIG_IEEE802154_CC2520_AUTO_ACK=y
|
||||
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=1
|
||||
|
||||
CONFIG_NET_SAMPLES_IP_ADDRESSES=y
|
||||
|
|
|
@ -42,12 +42,12 @@ CONFIG_SPI_0=y
|
|||
|
||||
CONFIG_SYS_LOG_SPI_LEVEL=1
|
||||
|
||||
CONFIG_TI_CC2520=y
|
||||
CONFIG_TI_CC2520_AUTO_ACK=y
|
||||
CONFIG_IEEE802154_CC2520=y
|
||||
CONFIG_IEEE802154_CC2520_AUTO_ACK=y
|
||||
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=1
|
||||
CONFIG_TI_CC2520_SPI_DRV_NAME="SPI_0"
|
||||
CONFIG_TI_CC2520_SPI_FREQ=4000000
|
||||
CONFIG_TI_CC2520_SPI_SLAVE=0
|
||||
CONFIG_IEEE802154_CC2520_SPI_DRV_NAME="SPI_0"
|
||||
CONFIG_IEEE802154_CC2520_SPI_FREQ=4000000
|
||||
CONFIG_IEEE802154_CC2520_SPI_SLAVE=0
|
||||
|
||||
CONFIG_NET_SAMPLES_IP_ADDRESSES=y
|
||||
CONFIG_NET_SAMPLES_MY_IPV6_ADDR="2001:db8::1"
|
||||
|
|
|
@ -40,7 +40,7 @@ CONFIG_GPIO=y
|
|||
CONFIG_SPI=y
|
||||
CONFIG_SPI_0=y
|
||||
|
||||
CONFIG_NXP_MCR20A=y
|
||||
CONFIG_IEEE802154_MCR20A=y
|
||||
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=1
|
||||
|
||||
CONFIG_NET_SAMPLES_IP_ADDRESSES=y
|
||||
|
|
|
@ -40,7 +40,7 @@ CONFIG_NET_L2_IEEE802154_ORFD=y
|
|||
CONFIG_NET_L2_IEEE802154_FRAGMENT=y
|
||||
CONFIG_NET_DEBUG_L2_IEEE802154_FRAGMENT=y
|
||||
|
||||
CONFIG_UPIPE_15_4=y
|
||||
CONFIG_IEEE802154_UPIPE=y
|
||||
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=1
|
||||
|
||||
CONFIG_NET_SAMPLES_IP_ADDRESSES=y
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
obj-y = echo-client.o
|
||||
|
||||
ifeq ($(CONFIG_TI_CC2520),y)
|
||||
ifeq ($(CONFIG_IEEE802154_CC2520),y)
|
||||
|
||||
ifeq ($(CONFIG_BOARD_ARDUINO_101),y)
|
||||
ccflags-y +=-I${ZEPHYR_BASE}/include/drivers/
|
||||
|
|
|
@ -364,11 +364,12 @@ static struct net_buf *prepare_send_buf(const char *name,
|
|||
struct net_buf *send_buf;
|
||||
bool status;
|
||||
|
||||
send_buf = net_nbuf_get_tx(context);
|
||||
send_buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
|
||||
NET_ASSERT(send_buf);
|
||||
|
||||
status = net_nbuf_append(send_buf, expecting_len, lorem_ipsum);
|
||||
status = net_nbuf_append(send_buf, expecting_len, lorem_ipsum,
|
||||
K_FOREVER);
|
||||
if (!status) {
|
||||
NET_ERR("%s: cannot create send buf", name);
|
||||
return NULL;
|
||||
|
|
|
@ -36,8 +36,8 @@ CONFIG_NET_L2_IEEE802154_ORFD=y
|
|||
CONFIG_NET_L2_IEEE802154_FRAGMENT=y
|
||||
CONFIG_NET_DEBUG_L2_IEEE802154_FRAGMENT=y
|
||||
|
||||
CONFIG_TI_CC2520=y
|
||||
CONFIG_TI_CC2520_AUTO_ACK=y
|
||||
CONFIG_IEEE802154_CC2520=y
|
||||
CONFIG_IEEE802154_CC2520_AUTO_ACK=y
|
||||
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=1
|
||||
|
||||
CONFIG_GPIO=y
|
||||
|
@ -47,6 +47,6 @@ CONFIG_SPI_1=y
|
|||
CONFIG_SPI_CS_GPIO=y
|
||||
CONFIG_SPI_1_CS_GPIO_PORT="GPIO_0"
|
||||
CONFIG_SPI_1_CS_GPIO_PIN=0
|
||||
CONFIG_TI_CC2520_SPI_DRV_NAME="SPI_1"
|
||||
CONFIG_TI_CC2520_SPI_FREQ=4
|
||||
CONFIG_TI_CC2520_SPI_SLAVE=1
|
||||
CONFIG_IEEE802154_CC2520_SPI_DRV_NAME="SPI_1"
|
||||
CONFIG_IEEE802154_CC2520_SPI_FREQ=4
|
||||
CONFIG_IEEE802154_CC2520_SPI_SLAVE=1
|
|
@ -38,8 +38,8 @@ CONFIG_NET_L2_IEEE802154_ORFD=y
|
|||
CONFIG_NET_L2_IEEE802154_FRAGMENT=y
|
||||
#CONFIG_NET_DEBUG_L2_IEEE802154_FRAGMENT=y
|
||||
|
||||
CONFIG_TI_CC2520=y
|
||||
CONFIG_TI_CC2520_AUTO_ACK=y
|
||||
CONFIG_IEEE802154_CC2520=y
|
||||
CONFIG_IEEE802154_CC2520_AUTO_ACK=y
|
||||
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=1
|
||||
|
||||
CONFIG_NET_SAMPLES_IP_ADDRESSES=y
|
||||
|
|
|
@ -42,12 +42,12 @@ CONFIG_SPI_0=y
|
|||
|
||||
CONFIG_SYS_LOG_SPI_LEVEL=1
|
||||
|
||||
CONFIG_TI_CC2520=y
|
||||
CONFIG_TI_CC2520_AUTO_ACK=y
|
||||
CONFIG_IEEE802154_CC2520=y
|
||||
CONFIG_IEEE802154_CC2520_AUTO_ACK=y
|
||||
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=1
|
||||
CONFIG_TI_CC2520_SPI_DRV_NAME="SPI_0"
|
||||
CONFIG_TI_CC2520_SPI_FREQ=4000000
|
||||
CONFIG_TI_CC2520_SPI_SLAVE=0
|
||||
CONFIG_IEEE802154_CC2520_SPI_DRV_NAME="SPI_0"
|
||||
CONFIG_IEEE802154_CC2520_SPI_FREQ=4000000
|
||||
CONFIG_IEEE802154_CC2520_SPI_SLAVE=0
|
||||
|
||||
CONFIG_NET_SAMPLES_IP_ADDRESSES=y
|
||||
CONFIG_NET_SAMPLES_MY_IPV6_ADDR="2001:db8::2"
|
||||
|
|
|
@ -39,7 +39,7 @@ CONFIG_GPIO=y
|
|||
CONFIG_SPI=y
|
||||
CONFIG_SPI_0=y
|
||||
|
||||
CONFIG_NXP_MCR20A=y
|
||||
CONFIG_IEEE802154_MCR20A=y
|
||||
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=1
|
||||
|
||||
CONFIG_NET_SAMPLES_IP_ADDRESSES=y
|
||||
|
|
|
@ -40,7 +40,7 @@ CONFIG_NET_L2_IEEE802154_ORFD=y
|
|||
CONFIG_NET_L2_IEEE802154_FRAGMENT=y
|
||||
CONFIG_NET_DEBUG_L2_IEEE802154_FRAGMENT=y
|
||||
|
||||
CONFIG_UPIPE_15_4=y
|
||||
CONFIG_IEEE802154_UPIPE=y
|
||||
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=1
|
||||
|
||||
CONFIG_NET_SAMPLES_IP_ADDRESSES=y
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
obj-y = echo-server.o
|
||||
|
||||
ifeq ($(CONFIG_TI_CC2520),y)
|
||||
ifeq ($(CONFIG_IEEE802154_CC2520),y)
|
||||
|
||||
ifeq ($(CONFIG_BOARD_ARDUINO_101),y)
|
||||
ccflags-y +=-I${ZEPHYR_BASE}/include/drivers/
|
||||
|
|
|
@ -271,7 +271,7 @@ static struct net_buf *build_reply_buf(const char *name,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
reply_buf = net_nbuf_get_tx(context);
|
||||
reply_buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
|
||||
NET_ASSERT(reply_buf);
|
||||
|
||||
|
@ -292,7 +292,7 @@ static struct net_buf *build_reply_buf(const char *name,
|
|||
net_buf_pull(tmp, header_len);
|
||||
|
||||
while (tmp) {
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
|
||||
if (!net_buf_headroom(tmp)) {
|
||||
/* If there is no link layer headers in the
|
||||
|
@ -429,8 +429,8 @@ static void tcp_received(struct net_context *context,
|
|||
void *user_data)
|
||||
{
|
||||
static char dbg[MAX_DBG_PRINT + 1];
|
||||
sa_family_t family = net_nbuf_family(buf);
|
||||
struct net_buf *reply_buf;
|
||||
sa_family_t family;
|
||||
int ret;
|
||||
|
||||
if (!buf) {
|
||||
|
@ -438,6 +438,8 @@ static void tcp_received(struct net_context *context,
|
|||
return;
|
||||
}
|
||||
|
||||
family = net_nbuf_family(buf);
|
||||
|
||||
snprintk(dbg, MAX_DBG_PRINT, "TCP IPv%c",
|
||||
family == AF_INET6 ? '6' : '4');
|
||||
|
||||
|
|
10
samples/net/http_client/Makefile
Normal file
10
samples/net/http_client/Makefile
Normal file
|
@ -0,0 +1,10 @@
|
|||
#
|
||||
# Copyright (c) 2017 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
BOARD ?= frdm_k64f
|
||||
CONF_FILE ?= prj_$(BOARD).conf
|
||||
|
||||
include $(ZEPHYR_BASE)/Makefile.inc
|
229
samples/net/http_client/README.rst
Normal file
229
samples/net/http_client/README.rst
Normal file
|
@ -0,0 +1,229 @@
|
|||
HTTP Client
|
||||
###########
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
This sample application shows how to create HTTP 1.1 requests to
|
||||
an HTTP server and how to parse the incoming responses.
|
||||
Supported HTTP 1.1 methods are: GET, HEAD, OPTIONS and POST.
|
||||
|
||||
The source code for this sample application can be found at:
|
||||
:file:`samples/net/http_client`.
|
||||
|
||||
Requirements
|
||||
************
|
||||
|
||||
- Freedom Board (FRDM-K64F)
|
||||
- LAN for testing purposes (Ethernet)
|
||||
- Terminal emulator software
|
||||
- HTTP Server
|
||||
|
||||
Building and Running
|
||||
********************
|
||||
|
||||
Open the project configuration file for your platform, for example:
|
||||
:file:`prj_frdm_k64f.conf` is the configuration file for the
|
||||
:ref:`frdm_k64f` board. For IPv4 networks, set the following variables:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
CONFIG_NET_IPV4=y
|
||||
CONFIG_NET_IPV6=n
|
||||
|
||||
IPv6 is the preferred routing technology for this sample application,
|
||||
if CONFIG_NET_IPV6=y is set, the value of CONFIG_NET_IPV4=y is ignored.
|
||||
|
||||
In this sample application, only static IP addresses are supported,
|
||||
those addresses are specified in the project configuration file,
|
||||
for example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
CONFIG_NET_SAMPLES_MY_IPV6_ADDR="2001:db8::1"
|
||||
CONFIG_NET_SAMPLES_PEER_IPV6_ADDR="2001:db8::2"
|
||||
|
||||
are the IPv6 addresses for the HTTP client running Zephyr and the
|
||||
HTTP server, respectively.
|
||||
|
||||
Alternatively, the IP addresses may be specified in the
|
||||
:file:`src/config.h` file.
|
||||
|
||||
Open the :file:`src/config.h` file and set the server port
|
||||
to match the HTTP server setup, for example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define SERVER_PORT 80
|
||||
|
||||
assumes that the HTTP server is listening at the TCP port 80.
|
||||
|
||||
HTTP Server
|
||||
===========
|
||||
|
||||
Setting up an HTTP server on your host computer is beyond the scope
|
||||
of this document.
|
||||
(We used `Apache 2 <http://httpd.apache.org/docs/2.4/getting-started.html>`_
|
||||
for testing this sample application.
|
||||
|
||||
However, this application assumes that there is a server's
|
||||
resource that can process an HTTP 1.1 POST request.
|
||||
|
||||
For example, assuming that the Apache 2 server with PHP support
|
||||
is used, and that the client sends a POST request with
|
||||
"Content-Type = application/x-www-form-urlencoded" the following
|
||||
PHP script will echo the POST payload back to the client:
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>HTTP Server POST test</title>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
echo '<p>POST key/values:</p>';
|
||||
foreach ($_POST as $key => $value) {
|
||||
echo "<p> {$key} : {$value} </p>";
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
In the machine hosting the HTTP server, this php script is at
|
||||
:file:`/var/www/html/post_test.php`. However, for your test machine
|
||||
this path can be different, but should be at your server's root folder.
|
||||
|
||||
HTTP Responses
|
||||
==============
|
||||
|
||||
Server's responses are processed by the http_receive_cb routine
|
||||
defined inside the :file:`src/http_client_rcv.c` file.
|
||||
|
||||
This sample application only prints the HTTP header fields via
|
||||
the HTTP Parser Library, see :file:`include/net/http_parser.h`.
|
||||
To process the HTTP response's body, use the HTTP Parser's callbacks
|
||||
to determine where the body begins. Depending on the payload's size,
|
||||
it may be necessary to traverse the network buffer's fragment chain.
|
||||
See the :file:`src/http_client_rcv.c` file at line 70 for sample code
|
||||
that shows how to walk the fragment chain.
|
||||
|
||||
FRDM K64F
|
||||
=========
|
||||
|
||||
Open a terminal window and type:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ make BOARD=frdm_k64f
|
||||
|
||||
The FRDM K64F board is detected as a USB storage device. The board
|
||||
must be mounted (i.e. to /mnt) to 'flash' the binary:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cp outdir/frdm_k64f/zephyr.bin /mnt
|
||||
|
||||
On Linux, use the 'dmesg' program to find the right USB device for the
|
||||
FRDM serial console. Assuming that this device is ttyACM0, open a
|
||||
terminal window and type:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ screen /dev/ttyACM0 115200
|
||||
|
||||
Once the binary is loaded into the FRDM board, press the RESET button.
|
||||
|
||||
Refer to the board documentation in Zephyr, :ref:`frdm_k64f`,
|
||||
for more information about this board and how to access the FRDM
|
||||
serial console under other operating systems.
|
||||
|
||||
Sample Output
|
||||
=============
|
||||
|
||||
This sample application loops a specified number of times doing four
|
||||
HTTP 1.1 requests and displays the header fields that were extracted
|
||||
from the server's response. The four requests are:
|
||||
|
||||
- GET "/index.html"
|
||||
- HEAD "/"
|
||||
- OPTIONS "/"
|
||||
- POST "/post_test.php"
|
||||
|
||||
The terminal window where screen is running will show something similar
|
||||
to the following:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
*******************************************
|
||||
HTTP Client: 2001:db8::1
|
||||
Connecting to: 2001:db8::2 port 80
|
||||
Hostname: 2001:db8::2
|
||||
HTTP Request: GET
|
||||
|
||||
--------- HTTP response (headers) ---------
|
||||
Date: Thu, 02 Feb 2017 00:51:31 GMT
|
||||
Server: Apache/2.4.10 (Debian)
|
||||
Last-Modified: Sat, 28 Jan 2017 02:55:09 GMT
|
||||
ETag: "3c-5471eb5db3c73"
|
||||
Accept-Ranges: bytes
|
||||
Content-Length: 60
|
||||
Connection: close
|
||||
Content-Type: text/html
|
||||
|
||||
HTTP server response status: OK
|
||||
HTTP parser status: success
|
||||
HTTP body: 60 bytes, expected: 60 bytes
|
||||
|
||||
*******************************************
|
||||
HTTP Client: 2001:db8::1
|
||||
Connecting to: 2001:db8::2 port 80
|
||||
Hostname: 2001:db8::2
|
||||
HTTP Request: HEAD
|
||||
|
||||
--------- HTTP response (headers) ---------
|
||||
Date: Thu, 02 Feb 2017 00:51:37 GMT
|
||||
Server: Apache/2.4.10 (Debian)
|
||||
Last-Modified: Sat, 28 Jan 2017 02:55:09 GMT
|
||||
ETag: "3c-5471eb5db3c73"
|
||||
Accept-Ranges: bytes
|
||||
Content-Length: 60
|
||||
Connection: close
|
||||
Content-Type: text/html
|
||||
|
||||
HTTP server response status: OK
|
||||
HTTP parser status: success
|
||||
|
||||
*******************************************
|
||||
HTTP Client: 2001:db8::1
|
||||
Connecting to: 2001:db8::2 port 80
|
||||
Hostname: 2001:db8::2
|
||||
HTTP Request: OPTIONS
|
||||
|
||||
--------- HTTP response (headers) ---------
|
||||
Date: Thu, 02 Feb 2017 00:51:43 GMT
|
||||
Server: Apache/2.4.10 (Debian)
|
||||
Allow: GET,HEAD,POST,OPTIONS
|
||||
Content-Length: 0
|
||||
Connection: close
|
||||
Content-Type: text/html
|
||||
|
||||
HTTP server response status: OK
|
||||
HTTP parser status: success
|
||||
|
||||
*******************************************
|
||||
HTTP Client: 2001:db8::1
|
||||
Connecting to: 2001:db8::2 port 80
|
||||
Hostname: 2001:db8::2
|
||||
HTTP Request: POST
|
||||
|
||||
--------- HTTP response (headers) ---------
|
||||
Date: Thu, 02 Feb 2017 00:51:49 GMT
|
||||
Server: Apache/2.4.10 (Debian)
|
||||
Vary: Accept-Encoding
|
||||
Content-Length: 231
|
||||
Connection: close
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
|
||||
HTTP server response status: OK
|
||||
HTTP parser status: success
|
34
samples/net/http_client/prj_frdm_k64f.conf
Normal file
34
samples/net/http_client/prj_frdm_k64f.conf
Normal file
|
@ -0,0 +1,34 @@
|
|||
CONFIG_RANDOM_GENERATOR=y
|
||||
|
||||
CONFIG_NETWORKING=y
|
||||
CONFIG_NET_TCP=y
|
||||
CONFIG_NET_ARP=y
|
||||
CONFIG_NET_L2_ETHERNET=y
|
||||
|
||||
CONFIG_NET_IPV6_RA_RDNSS=y
|
||||
CONFIG_NET_IFACE_UNICAST_IPV4_ADDR_COUNT=3
|
||||
|
||||
CONFIG_NET_NBUF_RX_COUNT=64
|
||||
CONFIG_NET_NBUF_TX_COUNT=64
|
||||
CONFIG_NET_NBUF_DATA_COUNT=16
|
||||
|
||||
CONFIG_NET_IPV4=n
|
||||
CONFIG_NET_IPV6=y
|
||||
|
||||
CONFIG_HTTP_PARSER=y
|
||||
CONFIG_STDOUT_CONSOLE=y
|
||||
|
||||
# Set the IP addresses here or in the
|
||||
# src/config.h file
|
||||
#
|
||||
CONFIG_NET_SAMPLES_IP_ADDRESSES=y
|
||||
CONFIG_NET_SAMPLES_MY_IPV6_ADDR="2001:db8::1"
|
||||
CONFIG_NET_SAMPLES_PEER_IPV6_ADDR="2001:db8::2"
|
||||
CONFIG_NET_SAMPLES_MY_IPV4_ADDR="192.168.1.101"
|
||||
CONFIG_NET_SAMPLES_PEER_IPV4_ADDR="192.168.1.10"
|
||||
|
||||
#CONFIG_MAIN_STACK_SIZE=8192
|
||||
|
||||
# See the config.h file and the LINEARIZE_BUFFER define
|
||||
#
|
||||
#CONFIG_NET_NBUF_DATA_SIZE=512
|
11
samples/net/http_client/src/Makefile
Normal file
11
samples/net/http_client/src/Makefile
Normal file
|
@ -0,0 +1,11 @@
|
|||
#
|
||||
# Copyright (c) 2017 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
obj-y += main.o
|
||||
obj-y += tcp_client.o
|
||||
obj-y += http_client.o
|
||||
obj-y += http_client_rcv.o
|
||||
obj-y += http_client_cb.o
|
74
samples/net/http_client/src/config.h
Normal file
74
samples/net/http_client/src/config.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <net/net_ip.h>
|
||||
|
||||
#define APP_NAP_TIME 3000
|
||||
|
||||
#define HTTP_POOL_BUF_CTR 4
|
||||
#define HTTP_POOL_BUF_SIZE 1024
|
||||
#define HTTP_STATUS_STR_SIZE 32
|
||||
|
||||
/* server port */
|
||||
#define SERVER_PORT 80
|
||||
/* rx tx timeout */
|
||||
#define HTTP_NETWORK_TIMEOUT 300
|
||||
|
||||
#ifdef CONFIG_NET_SAMPLES_IP_ADDRESSES
|
||||
#ifdef CONFIG_NET_IPV6
|
||||
#define LOCAL_ADDR CONFIG_NET_SAMPLES_MY_IPV6_ADDR
|
||||
#define SERVER_ADDR CONFIG_NET_SAMPLES_PEER_IPV6_ADDR
|
||||
#else
|
||||
#define LOCAL_ADDR CONFIG_NET_SAMPLES_MY_IPV4_ADDR
|
||||
#define SERVER_ADDR CONFIG_NET_SAMPLES_PEER_IPV4_ADDR
|
||||
#endif
|
||||
#else
|
||||
#ifdef CONFIG_NET_IPV6
|
||||
#define LOCAL_ADDR "2001:db8::1"
|
||||
#define SERVER_ADDR "2001:db8::2"
|
||||
#else
|
||||
#define LOCAL_ADDR "192.168.1.101"
|
||||
#define SERVER_ADDR "192.168.1.10"
|
||||
#endif
|
||||
#endif /* CONFIG */
|
||||
|
||||
/* It seems enough to hold 'Content-Length' and its value */
|
||||
#define CON_LEN_SIZE 48
|
||||
|
||||
/* Default HTTP Header Field values for HTTP Requests */
|
||||
#define ACCEPT "text/plain"
|
||||
#define ACCEPT_ENC "identity"
|
||||
#define ACCEPT_LANG "en-US"
|
||||
#define CONNECTION "Close"
|
||||
#define USER_AGENT "ZephyrHTTPClient/1.7"
|
||||
#define HOST_NAME SERVER_ADDR /* or example.com, www.example.com */
|
||||
|
||||
#define HEADER_FIELDS "Accept: "ACCEPT"\r\n" \
|
||||
"Accept-Encoding: "ACCEPT_ENC"\r\n" \
|
||||
"Accept-Language: "ACCEPT_LANG"\r\n" \
|
||||
"User-Agent: "USER_AGENT"\r\n" \
|
||||
"Host: "HOST_NAME"\r\n" \
|
||||
"Connection: "CONNECTION"\r\n"
|
||||
|
||||
/* Parsing and token tracking becomes a bit complicated if the
|
||||
* RX buffer is fragmented. for example: an HTTP response with
|
||||
* header fields that lie in two fragments. So, here we have
|
||||
* two options:
|
||||
*
|
||||
* - Use the fragmented buffer, but increasing the fragment size
|
||||
* - Linearize the buffer, it works better but consumes more memory
|
||||
*
|
||||
* Comment the following define to test the first case, set the
|
||||
* CONFIG_NET_NBUF_DATA_SIZE variable to 384 or 512. See the
|
||||
* prj_frdm_k64f.conf file.
|
||||
*/
|
||||
#define LINEARIZE_BUFFER
|
||||
|
||||
#ifndef LINEARIZE_BUFFER
|
||||
#if CONFIG_NET_NBUF_DATA_SIZE <= 256
|
||||
#error set CONFIG_NET_NBUF_DATA_SIZE to 384 or 512
|
||||
#endif
|
||||
#endif
|
158
samples/net/http_client/src/http_client.c
Normal file
158
samples/net/http_client/src/http_client.c
Normal file
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "http_client.h"
|
||||
#include "http_client_rcv.h"
|
||||
#include "http_client_cb.h"
|
||||
#include "config.h"
|
||||
|
||||
#include <misc/printk.h>
|
||||
#include <net/nbuf.h>
|
||||
|
||||
int http_init(struct http_client_ctx *http_ctx)
|
||||
{
|
||||
memset(http_ctx, 0, sizeof(struct http_client_ctx));
|
||||
|
||||
http_ctx->settings.on_body = on_body;
|
||||
http_ctx->settings.on_chunk_complete = on_chunk_complete;
|
||||
http_ctx->settings.on_chunk_header = on_chunk_header;
|
||||
http_ctx->settings.on_headers_complete = on_headers_complete;
|
||||
http_ctx->settings.on_header_field = on_header_field;
|
||||
http_ctx->settings.on_header_value = on_header_value;
|
||||
http_ctx->settings.on_message_begin = on_message_begin;
|
||||
http_ctx->settings.on_message_complete = on_message_complete;
|
||||
http_ctx->settings.on_status = on_status;
|
||||
http_ctx->settings.on_url = on_url;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int http_reset_ctx(struct http_client_ctx *http_ctx)
|
||||
{
|
||||
http_parser_init(&http_ctx->parser, HTTP_RESPONSE);
|
||||
|
||||
memset(http_ctx->http_status, 0, sizeof(http_ctx->http_status));
|
||||
|
||||
http_ctx->cl_present = 0;
|
||||
http_ctx->content_length = 0;
|
||||
http_ctx->processed = 0;
|
||||
http_ctx->body_found = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int http_send_request(struct http_client_ctx *http_ctx, const char *method,
|
||||
const char *url, const char *protocol,
|
||||
const char *content_type_value, const char *payload)
|
||||
{
|
||||
const char *content_type = "Content-Type: ";
|
||||
const char *sep = "\r\n\r\n";
|
||||
struct net_buf *tx;
|
||||
int rc;
|
||||
|
||||
tx = net_nbuf_get_tx(http_ctx->tcp_ctx.net_ctx, K_FOREVER);
|
||||
if (tx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!net_nbuf_append(tx, strlen(method), (uint8_t *)method,
|
||||
K_FOREVER)) {
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
if (!net_nbuf_append(tx, strlen(url), (uint8_t *)url, K_FOREVER)) {
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
if (!net_nbuf_append(tx, strlen(protocol), (uint8_t *)protocol,
|
||||
K_FOREVER)) {
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
if (!net_nbuf_append(tx, strlen(HEADER_FIELDS),
|
||||
(uint8_t *)HEADER_FIELDS, K_FOREVER)) {
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
if (content_type_value && payload) {
|
||||
char content_len_str[CON_LEN_SIZE];
|
||||
|
||||
if (!net_nbuf_append(tx, strlen(content_type),
|
||||
(uint8_t *)content_type, K_FOREVER)) {
|
||||
rc = -ENOMEM;
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
if (!net_nbuf_append(tx, strlen(content_type_value),
|
||||
(uint8_t *)content_type_value,
|
||||
K_FOREVER)) {
|
||||
rc = -ENOMEM;
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
rc = snprintk(content_len_str, sizeof(content_len_str),
|
||||
"\r\nContent-Length: %u\r\n\r\n",
|
||||
strlen(payload));
|
||||
if (rc <= 0 || rc >= sizeof(content_len_str)) {
|
||||
rc = -ENOMEM;
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
if (!net_nbuf_append(tx, strlen(content_len_str),
|
||||
(uint8_t *)content_len_str, K_FOREVER)) {
|
||||
rc = -ENOMEM;
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
if (!net_nbuf_append(tx, strlen(payload), (uint8_t *)payload,
|
||||
K_FOREVER)) {
|
||||
rc = -ENOMEM;
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!net_nbuf_append(tx, strlen(sep), (uint8_t *)sep,
|
||||
K_FOREVER)) {
|
||||
rc = -ENOMEM;
|
||||
goto lb_exit;
|
||||
}
|
||||
}
|
||||
|
||||
return net_context_send(tx, NULL, http_ctx->tcp_ctx.timeout,
|
||||
NULL, NULL);
|
||||
|
||||
lb_exit:
|
||||
net_buf_unref(tx);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int http_send_get(struct http_client_ctx *http_ctx, const char *url)
|
||||
{
|
||||
return http_send_request(http_ctx, "GET ", url, " HTTP/1.1\r\n",
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
int http_send_head(struct http_client_ctx *http_ctx, const char *url)
|
||||
{
|
||||
return http_send_request(http_ctx, "HEAD ", url, " HTTP/1.1\r\n",
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
int http_send_options(struct http_client_ctx *http_ctx, const char *url,
|
||||
const char *content_type_value, const char *payload)
|
||||
{
|
||||
return http_send_request(http_ctx, "OPTIONS ", url, " HTTP/1.1\r\n",
|
||||
content_type_value, payload);
|
||||
}
|
||||
|
||||
int http_send_post(struct http_client_ctx *http_ctx, const char *url,
|
||||
const char *content_type_value, const char *payload)
|
||||
{
|
||||
return http_send_request(http_ctx, "POST ", url, " HTTP/1.1\r\n",
|
||||
content_type_value, payload);
|
||||
}
|
38
samples/net/http_client/src/http_client.h
Normal file
38
samples/net/http_client/src/http_client.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _HTTP_CLIENT_H_
|
||||
#define _HTTP_CLIENT_H_
|
||||
|
||||
#include "http_client_types.h"
|
||||
|
||||
int http_init(struct http_client_ctx *http_ctx);
|
||||
|
||||
int http_reset_ctx(struct http_client_ctx *http_ctx);
|
||||
|
||||
/* Reception callback executed by the IP stack */
|
||||
void http_receive_cb(struct tcp_client_ctx *tcp_ctx, struct net_buf *rx);
|
||||
|
||||
/* Sends an HTTP GET request for URL url */
|
||||
int http_send_get(struct http_client_ctx *ctx, const char *url);
|
||||
|
||||
/* Sends an HTTP HEAD request for URL url */
|
||||
int http_send_head(struct http_client_ctx *ctx, const char *url);
|
||||
|
||||
/* Sends an HTTP OPTIONS request for URL url. From RFC 2616:
|
||||
* If the OPTIONS request includes an entity-body (as indicated by the
|
||||
* presence of Content-Length or Transfer-Encoding), then the media type
|
||||
* MUST be indicated by a Content-Type field.
|
||||
* Note: Transfer-Encoding is not yet supported.
|
||||
*/
|
||||
int http_send_options(struct http_client_ctx *http_ctx, const char *url,
|
||||
const char *content_type_value, const char *payload);
|
||||
|
||||
/* Sends an HTTP POST request for URL url with payload as content */
|
||||
int http_send_post(struct http_client_ctx *http_ctx, const char *url,
|
||||
const char *content_type_value, const char *payload);
|
||||
|
||||
#endif
|
133
samples/net/http_client/src/http_client_cb.c
Normal file
133
samples/net/http_client/src/http_client_cb.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "http_client_cb.h"
|
||||
#include "http_client_types.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_NUM_DIGITS 16
|
||||
|
||||
int on_url(struct http_parser *parser, const char *at, size_t length)
|
||||
{
|
||||
ARG_UNUSED(parser);
|
||||
|
||||
printf("URL: %.*s\n", length, at);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_status(struct http_parser *parser, const char *at, size_t length)
|
||||
{
|
||||
struct http_client_ctx *ctx;
|
||||
uint16_t len;
|
||||
|
||||
ARG_UNUSED(parser);
|
||||
|
||||
ctx = CONTAINER_OF(parser, struct http_client_ctx, parser);
|
||||
len = min(length, sizeof(ctx->http_status) - 1);
|
||||
memcpy(ctx->http_status, at, len);
|
||||
ctx->http_status[len] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_header_field(struct http_parser *parser, const char *at, size_t length)
|
||||
{
|
||||
char *content_len = "Content-Length";
|
||||
struct http_client_ctx *ctx;
|
||||
uint16_t len;
|
||||
|
||||
ctx = CONTAINER_OF(parser, struct http_client_ctx, parser);
|
||||
|
||||
len = strlen(content_len);
|
||||
if (length >= len && memcmp(at, content_len, len) == 0) {
|
||||
ctx->cl_present = 1;
|
||||
}
|
||||
|
||||
printf("%.*s: ", length, at);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_header_value(struct http_parser *parser, const char *at, size_t length)
|
||||
{
|
||||
struct http_client_ctx *ctx;
|
||||
char str[MAX_NUM_DIGITS];
|
||||
|
||||
ctx = CONTAINER_OF(parser, struct http_client_ctx, parser);
|
||||
|
||||
if (ctx->cl_present) {
|
||||
if (length <= MAX_NUM_DIGITS - 1) {
|
||||
long int num;
|
||||
|
||||
memcpy(str, at, length);
|
||||
str[length] = 0;
|
||||
num = strtol(str, NULL, 10);
|
||||
if (num == LONG_MIN || num == LONG_MAX) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctx->content_length = num;
|
||||
}
|
||||
|
||||
ctx->cl_present = 0;
|
||||
}
|
||||
|
||||
printf("%.*s\n", length, at);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_body(struct http_parser *parser, const char *at, size_t length)
|
||||
{
|
||||
struct http_client_ctx *ctx;
|
||||
|
||||
ctx = CONTAINER_OF(parser, struct http_client_ctx, parser);
|
||||
|
||||
ctx->body_found = 1;
|
||||
ctx->processed += length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_headers_complete(struct http_parser *parser)
|
||||
{
|
||||
ARG_UNUSED(parser);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_message_begin(struct http_parser *parser)
|
||||
{
|
||||
ARG_UNUSED(parser);
|
||||
|
||||
printf("\n--------- HTTP response (headers) ---------\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_message_complete(struct http_parser *parser)
|
||||
{
|
||||
ARG_UNUSED(parser);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_chunk_header(struct http_parser *parser)
|
||||
{
|
||||
ARG_UNUSED(parser);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_chunk_complete(struct http_parser *parser)
|
||||
{
|
||||
ARG_UNUSED(parser);
|
||||
|
||||
return 0;
|
||||
}
|
38
samples/net/http_client/src/http_client_cb.h
Normal file
38
samples/net/http_client/src/http_client_cb.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _HTTP_CLIENT_CB_H_
|
||||
#define _HTTP_CLIENT_CB_H_
|
||||
|
||||
#include <net/http_parser.h>
|
||||
|
||||
/*
|
||||
* This are the callbacks executed by the parser. Some of them
|
||||
* are only useful when parsing requests (or responses).
|
||||
* Unused callbacks may be removed.
|
||||
*/
|
||||
|
||||
int on_url(struct http_parser *parser, const char *at, size_t length);
|
||||
|
||||
int on_status(struct http_parser *parser, const char *at, size_t length);
|
||||
|
||||
int on_header_field(struct http_parser *parser, const char *at, size_t length);
|
||||
|
||||
int on_header_value(struct http_parser *parser, const char *at, size_t length);
|
||||
|
||||
int on_body(struct http_parser *parser, const char *at, size_t length);
|
||||
|
||||
int on_headers_complete(struct http_parser *parser);
|
||||
|
||||
int on_message_begin(struct http_parser *parser);
|
||||
|
||||
int on_message_complete(struct http_parser *parser);
|
||||
|
||||
int on_chunk_header(struct http_parser *parser);
|
||||
|
||||
int on_chunk_complete(struct http_parser *parser);
|
||||
|
||||
#endif
|
101
samples/net/http_client/src/http_client_rcv.c
Normal file
101
samples/net/http_client/src/http_client_rcv.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "http_client_rcv.h"
|
||||
#include "http_client_types.h"
|
||||
#include "config.h"
|
||||
|
||||
#include <net/nbuf.h>
|
||||
|
||||
#ifdef LINEARIZE_BUFFER
|
||||
|
||||
NET_BUF_POOL_DEFINE(http_pool, HTTP_POOL_BUF_CTR, HTTP_POOL_BUF_SIZE, 0, NULL);
|
||||
|
||||
void http_receive_cb(struct tcp_client_ctx *tcp_ctx, struct net_buf *rx)
|
||||
{
|
||||
struct http_client_ctx *http_ctx;
|
||||
struct net_buf *data_buf = NULL;
|
||||
uint16_t data_len;
|
||||
uint16_t offset;
|
||||
int rc;
|
||||
|
||||
if (!rx) {
|
||||
return;
|
||||
}
|
||||
|
||||
data_buf = net_buf_alloc(&http_pool, tcp_ctx->timeout);
|
||||
if (data_buf == NULL) {
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
data_len = min(net_nbuf_appdatalen(rx), HTTP_POOL_BUF_SIZE);
|
||||
offset = net_buf_frags_len(rx) - data_len;
|
||||
|
||||
rc = net_nbuf_linear_copy(data_buf, rx, offset, data_len);
|
||||
if (rc != 0) {
|
||||
rc = -ENOMEM;
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
http_ctx = CONTAINER_OF(tcp_ctx, struct http_client_ctx, tcp_ctx);
|
||||
|
||||
/* The parser's error can be catched outside, reading the
|
||||
* http_errno struct member
|
||||
*/
|
||||
http_parser_execute(&http_ctx->parser, &http_ctx->settings,
|
||||
data_buf->data, data_buf->len);
|
||||
|
||||
lb_exit:
|
||||
net_buf_unref(data_buf);
|
||||
net_buf_unref(rx);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void http_receive_cb(struct tcp_client_ctx *tcp_ctx, struct net_buf *rx)
|
||||
{
|
||||
struct http_client_ctx *http_ctx;
|
||||
struct net_buf *buf = rx;
|
||||
uint16_t offset;
|
||||
|
||||
if (!rx) {
|
||||
return;
|
||||
}
|
||||
|
||||
http_ctx = CONTAINER_OF(tcp_ctx, struct http_client_ctx, tcp_ctx);
|
||||
|
||||
offset = net_buf_frags_len(buf) - net_nbuf_appdatalen(buf);
|
||||
|
||||
/* find the fragment */
|
||||
while (buf && offset >= buf->len) {
|
||||
offset -= buf->len;
|
||||
buf = buf->frags;
|
||||
}
|
||||
|
||||
while (buf) {
|
||||
(void)http_parser_execute(&http_ctx->parser,
|
||||
&http_ctx->settings,
|
||||
buf->data + offset,
|
||||
buf->len - offset);
|
||||
|
||||
/* after the first iteration, we set offset to 0 */
|
||||
offset = 0;
|
||||
|
||||
/* The parser's error can be catched outside, reading the
|
||||
* http_errno struct member
|
||||
*/
|
||||
if (http_ctx->parser.http_errno != HPE_OK) {
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
buf = buf->frags;
|
||||
}
|
||||
|
||||
lb_exit:
|
||||
net_buf_unref(rx);
|
||||
}
|
||||
|
||||
#endif
|
15
samples/net/http_client/src/http_client_rcv.h
Normal file
15
samples/net/http_client/src/http_client_rcv.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _HTTP_CLIENT_RCV_H_
|
||||
#define _HTTP_CLIENT_RCV_H_
|
||||
|
||||
#include "tcp_client.h"
|
||||
|
||||
/* HTTP reception callback */
|
||||
void http_receive_cb(struct tcp_client_ctx *tcp_ctx, struct net_buf *rx);
|
||||
|
||||
#endif
|
28
samples/net/http_client/src/http_client_types.h
Normal file
28
samples/net/http_client/src/http_client_types.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _HTTP_CLIENT_TYPES_H_
|
||||
#define _HTTP_CLIENT_TYPES_H_
|
||||
|
||||
#include <net/http_parser.h>
|
||||
#include "tcp_client.h"
|
||||
#include "config.h"
|
||||
|
||||
struct http_client_ctx {
|
||||
struct http_parser parser;
|
||||
struct http_parser_settings settings;
|
||||
|
||||
struct tcp_client_ctx tcp_ctx;
|
||||
|
||||
uint32_t content_length;
|
||||
uint32_t processed;
|
||||
char http_status[HTTP_STATUS_STR_SIZE];
|
||||
|
||||
uint8_t cl_present:1;
|
||||
uint8_t body_found:1;
|
||||
};
|
||||
|
||||
#endif
|
128
samples/net/http_client/src/main.c
Normal file
128
samples/net/http_client/src/main.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <errno.h>
|
||||
#include <misc/printk.h>
|
||||
|
||||
#include "http_client_types.h"
|
||||
#include "http_client.h"
|
||||
#include "config.h"
|
||||
|
||||
#define POST_CONTENT_TYPE "application/x-www-form-urlencoded"
|
||||
#define POST_PAYLOAD "os=ZephyrRTOS&arch="CONFIG_ARCH
|
||||
|
||||
#define MAX_ITERATIONS 100
|
||||
|
||||
static struct http_client_ctx http_ctx;
|
||||
|
||||
static void send_http_method(enum http_method method, const char *url,
|
||||
const char *content_type, const char *payload);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int i = MAX_ITERATIONS;
|
||||
int rc;
|
||||
|
||||
http_init(&http_ctx);
|
||||
http_ctx.tcp_ctx.receive_cb = http_receive_cb;
|
||||
http_ctx.tcp_ctx.timeout = HTTP_NETWORK_TIMEOUT;
|
||||
|
||||
rc = tcp_set_local_addr(&http_ctx.tcp_ctx, LOCAL_ADDR);
|
||||
if (rc) {
|
||||
printk("tcp_set_local_addr error\n");
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
while (i-- > 0) {
|
||||
send_http_method(HTTP_GET, "/index.html", NULL, NULL);
|
||||
k_sleep(APP_NAP_TIME);
|
||||
|
||||
send_http_method(HTTP_HEAD, "/", NULL, NULL);
|
||||
k_sleep(APP_NAP_TIME);
|
||||
|
||||
send_http_method(HTTP_OPTIONS, "/index.html", NULL, NULL);
|
||||
k_sleep(APP_NAP_TIME);
|
||||
|
||||
send_http_method(HTTP_POST, "/post_test.php",
|
||||
POST_CONTENT_TYPE, POST_PAYLOAD);
|
||||
k_sleep(APP_NAP_TIME);
|
||||
}
|
||||
|
||||
lb_exit:
|
||||
printk("\nBye!\n");
|
||||
}
|
||||
|
||||
void print_banner(enum http_method method)
|
||||
{
|
||||
printk("\n*******************************************\n"
|
||||
"HTTP Client: %s\nConnecting to: %s port %d\n"
|
||||
"Hostname: %s\nHTTP Request: %s\n",
|
||||
LOCAL_ADDR, SERVER_ADDR, SERVER_PORT,
|
||||
HOST_NAME, http_method_str(method));
|
||||
}
|
||||
|
||||
static
|
||||
void send_http_method(enum http_method method, const char *url,
|
||||
const char *content_type, const char *payload)
|
||||
{
|
||||
int rc;
|
||||
|
||||
print_banner(method);
|
||||
|
||||
http_reset_ctx(&http_ctx);
|
||||
|
||||
rc = tcp_connect(&http_ctx.tcp_ctx, SERVER_ADDR, SERVER_PORT);
|
||||
if (rc) {
|
||||
printk("tcp_connect error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (method) {
|
||||
case HTTP_GET:
|
||||
rc = http_send_get(&http_ctx, url);
|
||||
break;
|
||||
case HTTP_POST:
|
||||
rc = http_send_post(&http_ctx, url, content_type, payload);
|
||||
break;
|
||||
case HTTP_HEAD:
|
||||
rc = http_send_head(&http_ctx, url);
|
||||
break;
|
||||
case HTTP_OPTIONS:
|
||||
rc = http_send_options(&http_ctx, url, NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
printk("Not yet implemented\n");
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
printk("Send error\n");
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
/* this is async, so we wait until the reception callback
|
||||
* processes the server's response (if any)
|
||||
*/
|
||||
k_sleep(APP_NAP_TIME);
|
||||
|
||||
printk("\nHTTP server response status: %s\n", http_ctx.http_status);
|
||||
|
||||
printk("HTTP parser status: %s\n",
|
||||
http_errno_description(http_ctx.parser.http_errno));
|
||||
|
||||
if (method == HTTP_GET) {
|
||||
if (http_ctx.body_found) {
|
||||
printk("HTTP body: %u bytes, expected: %u bytes\n",
|
||||
http_ctx.processed, http_ctx.content_length);
|
||||
} else {
|
||||
printk("Error detected during HTTP msg processing\n");
|
||||
}
|
||||
}
|
||||
|
||||
lb_exit:
|
||||
tcp_disconnect(&http_ctx.tcp_ctx);
|
||||
}
|
162
samples/net/http_client/src/tcp_client.c
Normal file
162
samples/net/http_client/src/tcp_client.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "tcp_client.h"
|
||||
#include "config.h"
|
||||
|
||||
#include <net/net_core.h>
|
||||
#include <net/net_if.h>
|
||||
#include <net/nbuf.h>
|
||||
|
||||
#include <misc/printk.h>
|
||||
|
||||
static
|
||||
int set_addr(struct sockaddr *sock_addr, const char *addr, uint16_t server_port)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
int rc;
|
||||
|
||||
#ifdef CONFIG_NET_IPV6
|
||||
net_sin6(sock_addr)->sin6_port = htons(server_port);
|
||||
sock_addr->family = AF_INET6;
|
||||
ptr = &(net_sin6(sock_addr)->sin6_addr);
|
||||
rc = net_addr_pton(AF_INET6, addr, ptr);
|
||||
#else
|
||||
net_sin(sock_addr)->sin_port = htons(server_port);
|
||||
sock_addr->family = AF_INET;
|
||||
ptr = &(net_sin(sock_addr)->sin_addr);
|
||||
rc = net_addr_pton(AF_INET, addr, ptr);
|
||||
#endif
|
||||
if (rc) {
|
||||
printk("Invalid IP address: %s\n", addr);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static
|
||||
int if_addr_add(struct sockaddr *local_sock)
|
||||
{
|
||||
void *p = NULL;
|
||||
|
||||
#ifdef CONFIG_NET_IPV6
|
||||
p = net_if_ipv6_addr_add(net_if_get_default(),
|
||||
&net_sin6(local_sock)->sin6_addr,
|
||||
NET_ADDR_MANUAL, 0);
|
||||
#else
|
||||
p = net_if_ipv4_addr_add(net_if_get_default(),
|
||||
&net_sin(local_sock)->sin_addr,
|
||||
NET_ADDR_MANUAL, 0);
|
||||
#endif
|
||||
if (p) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int tcp_set_local_addr(struct tcp_client_ctx *ctx, const char *local_addr)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = set_addr(&ctx->local_sock, local_addr, 0);
|
||||
if (rc) {
|
||||
printk("set_addr (local) error\n");
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
rc = if_addr_add(&ctx->local_sock);
|
||||
if (rc) {
|
||||
printk("if_addr_add error\n");
|
||||
}
|
||||
|
||||
lb_exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static
|
||||
void recv_cb(struct net_context *net_ctx, struct net_buf *rx, int status,
|
||||
void *data)
|
||||
{
|
||||
struct tcp_client_ctx *ctx = (struct tcp_client_ctx *)data;
|
||||
|
||||
ARG_UNUSED(net_ctx);
|
||||
|
||||
if (status) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rx == NULL || net_nbuf_appdatalen(rx) == 0) {
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
/* receive_cb must take ownership of the rx buffer */
|
||||
if (ctx->receive_cb) {
|
||||
ctx->receive_cb(ctx, rx);
|
||||
return;
|
||||
}
|
||||
|
||||
lb_exit:
|
||||
net_buf_unref(rx);
|
||||
}
|
||||
|
||||
int tcp_connect(struct tcp_client_ctx *ctx, const char *server_addr,
|
||||
uint16_t server_port)
|
||||
{
|
||||
#if CONFIG_NET_IPV6
|
||||
socklen_t addr_len = sizeof(struct sockaddr_in6);
|
||||
sa_family_t family = AF_INET6;
|
||||
#else
|
||||
socklen_t addr_len = sizeof(struct sockaddr_in);
|
||||
sa_family_t family = AF_INET;
|
||||
#endif
|
||||
struct sockaddr server_sock;
|
||||
int rc;
|
||||
|
||||
rc = net_context_get(family, SOCK_STREAM, IPPROTO_TCP, &ctx->net_ctx);
|
||||
if (rc) {
|
||||
printk("net_context_get error\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = net_context_bind(ctx->net_ctx, &ctx->local_sock, addr_len);
|
||||
if (rc) {
|
||||
printk("net_context_bind error\n");
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
rc = set_addr(&server_sock, server_addr, server_port);
|
||||
if (rc) {
|
||||
printk("set_addr (server) error\n");
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
rc = net_context_connect(ctx->net_ctx, &server_sock, addr_len, NULL,
|
||||
ctx->timeout, NULL);
|
||||
if (rc) {
|
||||
printk("net_context_connect error\n");
|
||||
goto lb_exit;
|
||||
}
|
||||
|
||||
(void)net_context_recv(ctx->net_ctx, recv_cb, K_NO_WAIT, ctx);
|
||||
|
||||
return 0;
|
||||
|
||||
lb_exit:
|
||||
net_context_put(ctx->net_ctx);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int tcp_disconnect(struct tcp_client_ctx *ctx)
|
||||
{
|
||||
if (ctx->net_ctx) {
|
||||
net_context_put(ctx->net_ctx);
|
||||
ctx->net_ctx = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
31
samples/net/http_client/src/tcp_client.h
Normal file
31
samples/net/http_client/src/tcp_client.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _TCP_CLIENT_H_
|
||||
#define _TCP_CLIENT_H_
|
||||
|
||||
#include <net/net_context.h>
|
||||
#include <net/net_ip.h>
|
||||
|
||||
struct tcp_client_ctx {
|
||||
/* IP stack network context */
|
||||
struct net_context *net_ctx;
|
||||
/* Local sock address */
|
||||
struct sockaddr local_sock;
|
||||
/* Network timeout */
|
||||
int32_t timeout;
|
||||
/* User defined call back*/
|
||||
void (*receive_cb)(struct tcp_client_ctx *ctx, struct net_buf *rx);
|
||||
};
|
||||
|
||||
int tcp_set_local_addr(struct tcp_client_ctx *ctx, const char *local_addr);
|
||||
|
||||
int tcp_connect(struct tcp_client_ctx *ctx, const char *server_addr,
|
||||
uint16_t server_port);
|
||||
|
||||
int tcp_disconnect(struct tcp_client_ctx *ctx);
|
||||
|
||||
#endif
|
4
samples/net/http_client/testcase.ini
Normal file
4
samples/net/http_client/testcase.ini
Normal file
|
@ -0,0 +1,4 @@
|
|||
[test]
|
||||
tags = net http
|
||||
build_only = true
|
||||
platform_whitelist = frdm_k64f
|
|
@ -22,7 +22,7 @@ uint16_t http_strlen(const char *str)
|
|||
|
||||
int http_add_header(struct net_buf *tx, const char *str)
|
||||
{
|
||||
net_nbuf_append(tx, strlen(str), (uint8_t *)str);
|
||||
net_nbuf_append(tx, strlen(str), (uint8_t *)str, K_FOREVER);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -36,13 +36,13 @@ int http_add_chunk(struct net_buf *tx, const char *str)
|
|||
str_len = http_strlen(str);
|
||||
|
||||
snprintf(chunk_header, sizeof(chunk_header), "%x\r\n", str_len);
|
||||
net_nbuf_append(tx, strlen(chunk_header), chunk_header);
|
||||
net_nbuf_append(tx, strlen(chunk_header), chunk_header, K_FOREVER);
|
||||
|
||||
if (str_len) {
|
||||
net_nbuf_append(tx, str_len, (uint8_t *)str);
|
||||
net_nbuf_append(tx, str_len, (uint8_t *)str, K_FOREVER);
|
||||
}
|
||||
|
||||
net_nbuf_append(tx, strlen(rn), rn);
|
||||
net_nbuf_append(tx, strlen(rn), rn, K_FOREVER);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ int http_write(struct http_server_ctx *ctx, const char *http_header,
|
|||
struct net_buf *tx;
|
||||
int rc = -EINVAL;
|
||||
|
||||
tx = net_nbuf_get_tx(ctx->net_ctx);
|
||||
tx = net_nbuf_get_tx(ctx->net_ctx, K_FOREVER);
|
||||
printf("[%s:%d] net_nbuf_get_tx, rc: %d <%s>\n",
|
||||
__func__, __LINE__, !tx, RC_STR(!tx));
|
||||
if (tx == NULL) {
|
||||
|
|
|
@ -37,8 +37,8 @@ CONFIG_NET_L2_IEEE802154_RFD=y
|
|||
CONFIG_NET_L2_IEEE802154_FRAGMENT=y
|
||||
#CONFIG_NET_DEBUG_L2_IEEE802154_FRAGMENT=y
|
||||
|
||||
CONFIG_TI_CC2520=y
|
||||
CONFIG_TI_CC2520_AUTO_ACK=y
|
||||
CONFIG_IEEE802154_CC2520=y
|
||||
CONFIG_IEEE802154_CC2520_AUTO_ACK=y
|
||||
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=1
|
||||
|
||||
CONFIG_NET_L2_IEEE802154_SHELL=y
|
||||
|
|
|
@ -39,7 +39,7 @@ CONFIG_NET_L2_IEEE802154_RFD=y
|
|||
CONFIG_NET_L2_IEEE802154_FRAGMENT=y
|
||||
#CONFIG_NET_DEBUG_L2_IEEE802154_FRAGMENT=y
|
||||
|
||||
CONFIG_NXP_MCR20A=y
|
||||
CONFIG_IEEE802154_MCR20A=y
|
||||
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=1
|
||||
|
||||
CONFIG_NET_L2_IEEE802154_SHELL=y
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
#include <misc/printk.h>
|
||||
#define PRINT printk
|
||||
|
||||
#ifdef CONFIG_TI_CC2520_DRV_NAME
|
||||
#define IEEE802154_DRV_NAME CONFIG_TI_CC2520_DRV_NAME
|
||||
#ifdef CONFIG_IEEE802154_CC2520_DRV_NAME
|
||||
#define IEEE802154_DRV_NAME CONFIG_IEEE802154_CC2520_DRV_NAME
|
||||
#endif
|
||||
#ifdef CONFIG_NXP_MCR20A_DRV_NAME
|
||||
#define IEEE802154_DRV_NAME CONFIG_NXP_MCR20A_DRV_NAME
|
||||
#ifdef CONFIG_IEEE802154_MCR20A_DRV_NAME
|
||||
#define IEEE802154_DRV_NAME CONFIG_IEEE802154_MCR20A_DRV_NAME
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_NET_L2_IEEE802154_SHELL
|
||||
|
|
|
@ -35,5 +35,5 @@ CONFIG_NET_L2_IEEE802154_ORFD=y
|
|||
CONFIG_NET_L2_IEEE802154_FRAGMENT=y
|
||||
#CONFIG_NET_DEBUG_L2_IEEE802154_FRAGMENT=y
|
||||
|
||||
CONFIG_UPIPE_15_4=y
|
||||
CONFIG_IEEE802154_UPIPE=y
|
||||
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=4
|
||||
|
|
|
@ -26,7 +26,7 @@ static struct net_if *init_device(void)
|
|||
struct net_if *iface;
|
||||
struct device *dev;
|
||||
|
||||
dev = device_get_binding(CONFIG_UPIPE_15_4_DRV_NAME);
|
||||
dev = device_get_binding(CONFIG_IEEE802154_UPIPE_DRV_NAME);
|
||||
if (!dev) {
|
||||
PRINT("Cannot get UPIPE device\n");
|
||||
return NULL;
|
||||
|
|
|
@ -146,12 +146,12 @@ transmit(struct net_context *ctx, char buffer[], size_t len)
|
|||
{
|
||||
struct net_buf *send_buf;
|
||||
|
||||
send_buf = net_nbuf_get_tx(ctx);
|
||||
send_buf = net_nbuf_get_tx(ctx, K_FOREVER);
|
||||
if (!send_buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!net_nbuf_append(send_buf, len, buffer)) {
|
||||
if (!net_nbuf_append(send_buf, len, buffer, K_FOREVER)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -312,7 +312,7 @@ on_context_recv(struct net_context *ctx, struct net_buf *buf,
|
|||
|
||||
if (cmd_len + len > sizeof(cmd_buf)) {
|
||||
/* overrun cmd_buf - bail out */
|
||||
NET_ERR("CMD BUFFER OVERRUN!! %lu > %lu",
|
||||
NET_ERR("CMD BUFFER OVERRUN!! %zu > %zu",
|
||||
cmd_len + len,
|
||||
sizeof(cmd_buf));
|
||||
break;
|
||||
|
|
4
samples/net/irc_bot/testcase.ini
Normal file
4
samples/net/irc_bot/testcase.ini
Normal file
|
@ -0,0 +1,4 @@
|
|||
[test]
|
||||
tags = net irc
|
||||
build_only = true
|
||||
platform_whitelist = qemu_x86 frdm_k64f
|
|
@ -8,5 +8,5 @@ CONFIG_NET_LOG=y
|
|||
CONFIG_NET_UDP=y
|
||||
CONFIG_NET_YAIP=y
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_TI_CC2520=y
|
||||
CONFIG_IEEE802154_CC2520=y
|
||||
CONFIG_ZOAP=y
|
||||
|
|
|
@ -100,12 +100,12 @@ static int led_get(struct zoap_resource *resource,
|
|||
|
||||
id = zoap_header_get_id(request);
|
||||
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -167,12 +167,12 @@ static int led_post(struct zoap_resource *resource,
|
|||
|
||||
id = zoap_header_get_id(request);
|
||||
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -245,12 +245,12 @@ static int led_put(struct zoap_resource *resource,
|
|||
|
||||
id = zoap_header_get_id(request);
|
||||
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -307,12 +307,12 @@ static int dummy_get(struct zoap_resource *resource,
|
|||
|
||||
id = zoap_header_get_id(request);
|
||||
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
|
@ -66,13 +66,13 @@ int udp_tx(void *context, const unsigned char *buf, size_t size)
|
|||
|
||||
udp_ctx = ctx->net_ctx;
|
||||
|
||||
send_buf = net_nbuf_get_tx(udp_ctx);
|
||||
send_buf = net_nbuf_get_tx(udp_ctx, K_FOREVER);
|
||||
if (!send_buf) {
|
||||
printk("cannot create buf\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rc = net_nbuf_append(send_buf, size, (uint8_t *) buf);
|
||||
rc = net_nbuf_append(send_buf, size, (uint8_t *) buf, K_FOREVER);
|
||||
if (!rc) {
|
||||
printk("cannot write buf\n");
|
||||
return -EIO;
|
||||
|
|
|
@ -60,13 +60,13 @@ int udp_tx(void *context, const unsigned char *buf, size_t size)
|
|||
|
||||
net_ctx = ctx->net_ctx;
|
||||
|
||||
send_buf = net_nbuf_get_tx(net_ctx);
|
||||
send_buf = net_nbuf_get_tx(net_ctx, K_FOREVER);
|
||||
if (!send_buf) {
|
||||
printk("cannot create buf\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rc = net_nbuf_append(send_buf, size, (uint8_t *) buf);
|
||||
rc = net_nbuf_append(send_buf, size, (uint8_t *) buf, K_FOREVER);
|
||||
if (!rc) {
|
||||
printk("cannot write buf\n");
|
||||
return -EIO;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
BOARD = galileo
|
||||
CONF_FILE = prj_galileo.conf
|
||||
BOARD ?= galileo
|
||||
CONF_FILE ?= prj_$(BOARD).conf
|
||||
|
||||
include $(ZEPHYR_BASE)/Makefile.inc
|
||||
|
|
34
samples/net/mbedtls_sslclient/prj_arduino_101.conf
Normal file
34
samples/net/mbedtls_sslclient/prj_arduino_101.conf
Normal file
|
@ -0,0 +1,34 @@
|
|||
CONFIG_SYS_LOG=y
|
||||
CONFIG_NET_LOG=y
|
||||
CONFIG_INIT_STACKS=y
|
||||
CONFIG_MAIN_STACK_SIZE=4096
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
|
||||
CONFIG_NETWORKING=y
|
||||
CONFIG_NET_ARP=y
|
||||
CONFIG_NET_L2_ETHERNET=y
|
||||
CONFIG_NET_IPV4=y
|
||||
CONFIG_NET_IPV6=n
|
||||
CONFIG_NET_TCP=y
|
||||
CONFIG_NET_BUF=y
|
||||
CONFIG_NET_IFACE_UNICAST_IPV4_ADDR_COUNT=3
|
||||
CONFIG_NET_NBUF_RX_COUNT=4
|
||||
CONFIG_NET_NBUF_TX_COUNT=4
|
||||
CONFIG_NET_NBUF_DATA_COUNT=12
|
||||
|
||||
CONFIG_ETH_ENC28J60=y
|
||||
CONFIG_ETH_ENC28J60_0=y
|
||||
CONFIG_ETH_ENC28J60_0_SPI_PORT_NAME="SPI_1"
|
||||
CONFIG_ETH_ENC28J60_0_SPI_BUS_FREQ=2
|
||||
CONFIG_ETH_ENC28J60_0_MAC3=0x2D
|
||||
CONFIG_ETH_ENC28J60_0_MAC4=0x30
|
||||
CONFIG_ETH_ENC28J60_0_MAC5=0x32
|
||||
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_CS_GPIO=y
|
||||
CONFIG_SPI_1_CS_GPIO_PORT="GPIO_0"
|
||||
CONFIG_SPI_1_CS_GPIO_PIN=0
|
||||
|
||||
CONFIG_MBEDTLS=y
|
||||
CONFIG_MBEDTLS_BUILTIN=y
|
||||
CONFIG_MBEDTLS_CFG_FILE="config-ccm-psk-tls1_2.h"
|
|
@ -54,13 +54,13 @@ int tcp_tx(void *context, const unsigned char *buf, size_t size)
|
|||
|
||||
tcp_ctx = ctx->net_ctx;
|
||||
|
||||
send_buf = net_nbuf_get_tx(tcp_ctx);
|
||||
send_buf = net_nbuf_get_tx(tcp_ctx, K_FOREVER);
|
||||
if (!send_buf) {
|
||||
printk("cannot create buf\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rc = net_nbuf_append(send_buf, size, (uint8_t *) buf);
|
||||
rc = net_nbuf_append(send_buf, size, (uint8_t *) buf, K_FOREVER);
|
||||
if (!rc) {
|
||||
printk("cannot write buf\n");
|
||||
return -EIO;
|
||||
|
|
|
@ -10,7 +10,7 @@ CONFIG_SERIAL=y
|
|||
CONFIG_UART_INTERRUPT_DRIVEN=y
|
||||
CONFIG_UART_LINE_CTRL=y
|
||||
|
||||
CONFIG_TI_CC2520_RAW=y
|
||||
CONFIG_IEEE802154_CC2520_RAW=y
|
||||
CONFIG_NET_BUF=y
|
||||
CONFIG_NETWORKING=y
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
ccflags-$(CONFIG_TI_CC2520_RAW) += -I${ZEPHYR_BASE}/subsys/net/ip
|
||||
ccflags-$(CONFIG_IEEE802154_CC2520_RAW) += -I${ZEPHYR_BASE}/subsys/net/ip
|
||||
|
||||
obj-y += main.o
|
||||
|
|
|
@ -143,12 +143,12 @@ static int slip_process_byte(unsigned char c)
|
|||
#endif
|
||||
|
||||
if (!pkt_curr) {
|
||||
pkt_curr = net_nbuf_get_reserve_rx(0);
|
||||
pkt_curr = net_nbuf_get_reserve_rx(0, K_NO_WAIT);
|
||||
if (!pkt_curr) {
|
||||
SYS_LOG_ERR("No more buffers");
|
||||
return 0;
|
||||
}
|
||||
buf = net_nbuf_get_reserve_data(0);
|
||||
buf = net_nbuf_get_reserve_data(0, K_NO_WAIT);
|
||||
if (!buf) {
|
||||
SYS_LOG_ERR("No more buffers");
|
||||
net_nbuf_unref(pkt_curr);
|
||||
|
@ -220,13 +220,13 @@ static void send_data(uint8_t *cfg, uint8_t *data, size_t len)
|
|||
{
|
||||
struct net_buf *buf, *pkt;
|
||||
|
||||
pkt = net_nbuf_get_reserve_rx(0);
|
||||
pkt = net_nbuf_get_reserve_rx(0, K_NO_WAIT);
|
||||
if (!pkt) {
|
||||
SYS_LOG_DBG("No buf available");
|
||||
return;
|
||||
}
|
||||
|
||||
buf = net_nbuf_get_reserve_data(0);
|
||||
buf = net_nbuf_get_reserve_data(0, K_NO_WAIT);
|
||||
if (!buf) {
|
||||
SYS_LOG_DBG("No fragment available");
|
||||
net_nbuf_unref(pkt);
|
||||
|
@ -505,7 +505,7 @@ static bool init_ieee802154(void)
|
|||
|
||||
SYS_LOG_INF("Initialize ieee802.15.4");
|
||||
|
||||
ieee802154_dev = device_get_binding(CONFIG_TI_CC2520_DRV_NAME);
|
||||
ieee802154_dev = device_get_binding(CONFIG_IEEE802154_CC2520_DRV_NAME);
|
||||
if (!ieee802154_dev) {
|
||||
SYS_LOG_ERR("Cannot get CC250 device");
|
||||
return false;
|
||||
|
|
|
@ -15,8 +15,8 @@ CONFIG_NET_NBUF_DATA_SIZE=128
|
|||
|
||||
CONFIG_NET_L2_IEEE802154=y
|
||||
|
||||
#CONFIG_TI_CC2520=y
|
||||
CONFIG_TI_CC2520_RAW=y
|
||||
#CONFIG_IEEE802154_CC2520=y
|
||||
CONFIG_IEEE802154_CC2520_RAW=y
|
||||
|
||||
CONFIG_SYS_LOG=y
|
||||
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=1
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
ccflags-y += -I${ZEPHYR_BASE}/usb/include -I${ZEPHYR_BASE}/include/drivers/usb -I${ZEPHYR_BASE}/include/usb/
|
||||
|
||||
ccflags-$(CONFIG_TI_CC2520_LEGACY) += -I${ZEPHYR_BASE}/net/ip/contiki/os
|
||||
ccflags-$(CONFIG_TI_CC2520_LEGACY) += -I${ZEPHYR_BASE}/net/ip/contiki
|
||||
ccflags-$(CONFIG_TI_CC2520_LEGACY) += -I${ZEPHYR_BASE}/net/ip
|
||||
ccflags-$(CONFIG_IEEE802154_CC2520_LEGACY) += -I${ZEPHYR_BASE}/net/ip/contiki/os
|
||||
ccflags-$(CONFIG_IEEE802154_CC2520_LEGACY) += -I${ZEPHYR_BASE}/net/ip/contiki
|
||||
ccflags-$(CONFIG_IEEE802154_CC2520_LEGACY) += -I${ZEPHYR_BASE}/net/ip
|
||||
|
||||
ccflags-$(CONFIG_TI_CC2520_RAW) += -I${ZEPHYR_BASE}/subsys/net/ip
|
||||
ccflags-$(CONFIG_IEEE802154_CC2520_RAW) += -I${ZEPHYR_BASE}/subsys/net/ip
|
||||
|
||||
obj-y += wpanusb.o
|
||||
|
|
|
@ -382,8 +382,17 @@ static int wpanusb_vendor_handler(struct usb_setup_packet *setup,
|
|||
{
|
||||
struct net_buf *pkt, *buf;
|
||||
|
||||
pkt = net_nbuf_get_reserve_tx(0);
|
||||
buf = net_nbuf_get_reserve_data(0);
|
||||
pkt = net_nbuf_get_reserve_tx(0, K_NO_WAIT);
|
||||
if (!pkt) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
buf = net_nbuf_get_reserve_data(0, K_NO_WAIT);
|
||||
if (!buf) {
|
||||
net_nbuf_unref(pkt);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
net_buf_frag_insert(pkt, buf);
|
||||
|
||||
net_buf_add_u8(buf, setup->bRequest);
|
||||
|
@ -587,7 +596,7 @@ void main(void)
|
|||
#if DYNAMIC_REGISTER
|
||||
ieee802154_dev = ieee802154_register_raw();
|
||||
#else
|
||||
ieee802154_dev = device_get_binding(CONFIG_TI_CC2520_DRV_NAME);
|
||||
ieee802154_dev = device_get_binding(CONFIG_IEEE802154_CC2520_DRV_NAME);
|
||||
if (!ieee802154_dev) {
|
||||
SYS_LOG_ERR("Cannot get CC250 device");
|
||||
return;
|
||||
|
|
|
@ -173,13 +173,13 @@ static void event_iface_up(struct net_mgmt_event_callback *cb,
|
|||
|
||||
k_delayed_work_init(&retransmit_work, retransmit_request);
|
||||
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
printk("Unable to get TX buffer, not enough memory.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
printk("Unable to get DATA buffer, not enough memory.\n");
|
||||
return;
|
||||
|
|
|
@ -8,7 +8,7 @@ CONFIG_NET_LOG=y
|
|||
CONFIG_NET_UDP=y
|
||||
CONFIG_NET_YAIP=y
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_TI_CC2520=y
|
||||
CONFIG_IEEE802154_CC2520=y
|
||||
CONFIG_ZOAP=y
|
||||
CONFIG_NET_SAMPLES_IP_ADDRESSES=y
|
||||
CONFIG_NET_SAMPLES_MY_IPV6_ADDR="2001:db8::1"
|
||||
|
|
|
@ -64,12 +64,12 @@ static int test_del(struct zoap_resource *resource,
|
|||
NET_INFO("type: %u code %u id %u\n", type, code, id);
|
||||
NET_INFO("*******\n");
|
||||
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -123,12 +123,12 @@ static int test_put(struct zoap_resource *resource,
|
|||
NET_INFO("type: %u code %u id %u\n", type, code, id);
|
||||
NET_INFO("*******\n");
|
||||
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -188,12 +188,12 @@ static int test_post(struct zoap_resource *resource,
|
|||
NET_INFO("type: %u code %u id %u\n", type, code, id);
|
||||
NET_INFO("*******\n");
|
||||
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -257,12 +257,12 @@ static int location_query_post(struct zoap_resource *resource,
|
|||
NET_INFO("type: %u code %u id %u\n", type, code, id);
|
||||
NET_INFO("*******\n");
|
||||
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -317,12 +317,12 @@ static int piggyback_get(struct zoap_resource *resource,
|
|||
NET_INFO("type: %u code %u id %u\n", type, code, id);
|
||||
NET_INFO("*******\n");
|
||||
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -419,12 +419,12 @@ static int query_get(struct zoap_resource *resource,
|
|||
|
||||
NET_INFO("*******\n");
|
||||
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -494,12 +494,12 @@ static int separate_get(struct zoap_resource *resource,
|
|||
goto done;
|
||||
}
|
||||
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -525,12 +525,12 @@ static int separate_get(struct zoap_resource *resource,
|
|||
}
|
||||
|
||||
done:
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -614,12 +614,12 @@ static int large_get(struct zoap_resource *resource,
|
|||
NET_INFO("type: %u code %u id %u\n", type, code, id);
|
||||
NET_INFO("*******\n");
|
||||
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -712,12 +712,12 @@ static int large_update_put(struct zoap_resource *resource,
|
|||
NET_INFO("type: %u code %u id %u\n", type, code, id);
|
||||
NET_INFO("*******\n");
|
||||
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ CONFIG_NET_L2_IEEE802154_ORFD_PAN_ID=0xabcd
|
|||
CONFIG_NET_L2_IEEE802154_ORFD_CHANNEL=26
|
||||
CONFIG_NET_L2_IEEE802154_FRAGMENT=y
|
||||
|
||||
CONFIG_TI_CC2520=y
|
||||
CONFIG_IEEE802154_CC2520=y
|
||||
|
||||
CONFIG_NET_6LO=y
|
||||
CONFIG_NET_6LO_CONTEXT=y
|
||||
|
|
|
@ -54,23 +54,24 @@ void zperf_tcp_upload(struct net_context *ctx,
|
|||
loop_time = k_cycle_get_32();
|
||||
last_loop_time = loop_time;
|
||||
|
||||
buf = net_nbuf_get_tx(ctx);
|
||||
buf = net_nbuf_get_tx(ctx, K_FOREVER);
|
||||
if (!buf) {
|
||||
printk(TAG "ERROR! Failed to retrieve a buffer\n");
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(ctx);
|
||||
frag = net_nbuf_get_data(ctx, K_FOREVER);
|
||||
if (!frag) {
|
||||
net_nbuf_unref(buf);
|
||||
printk(TAG "ERROR! Failed to retrieve a fragment\n");
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
net_buf_frag_add(buf, frag);
|
||||
|
||||
/* Fill in the TCP payload */
|
||||
st = net_nbuf_append(buf, sizeof(sample_packet),
|
||||
sample_packet);
|
||||
sample_packet, K_FOREVER);
|
||||
if (!st) {
|
||||
printk(TAG "ERROR! Failed to fill packet\n");
|
||||
|
||||
|
|
|
@ -67,8 +67,8 @@ static inline struct net_buf *build_reply_buf(struct net_context *context,
|
|||
|
||||
printk(TAG "received %d bytes\n", net_nbuf_appdatalen(buf));
|
||||
|
||||
reply_buf = net_nbuf_get_tx(context);
|
||||
frag = net_nbuf_get_data(context);
|
||||
reply_buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
|
||||
net_buf_frag_add(reply_buf, frag);
|
||||
|
||||
|
|
|
@ -86,13 +86,13 @@ static inline void zperf_upload_fin(struct net_context *context,
|
|||
struct net_buf *buf, *frag;
|
||||
bool status;
|
||||
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
printk(TAG "ERROR! Failed to retrieve a buffer\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
printk(TAG "ERROR! Failed to retrieve a fragment\n");
|
||||
continue;
|
||||
|
@ -107,7 +107,7 @@ static inline void zperf_upload_fin(struct net_context *context,
|
|||
USEC_PER_SEC);
|
||||
|
||||
status = net_nbuf_append(buf, sizeof(datagram),
|
||||
(uint8_t *)&datagram);
|
||||
(uint8_t *)&datagram, K_FOREVER);
|
||||
if (!status) {
|
||||
printk(TAG "ERROR! Cannot append datagram data\n");
|
||||
break;
|
||||
|
@ -121,7 +121,8 @@ static inline void zperf_upload_fin(struct net_context *context,
|
|||
|
||||
frag = net_nbuf_write(buf, net_buf_frag_last(buf),
|
||||
sizeof(struct zperf_udp_datagram),
|
||||
&pos, size, sample_packet);
|
||||
&pos, size, sample_packet,
|
||||
K_FOREVER);
|
||||
}
|
||||
|
||||
/* Send the packet */
|
||||
|
@ -229,13 +230,13 @@ void zperf_udp_upload(struct net_context *context,
|
|||
|
||||
last_loop_time = loop_time;
|
||||
|
||||
buf = net_nbuf_get_tx(context);
|
||||
buf = net_nbuf_get_tx(context, K_FOREVER);
|
||||
if (!buf) {
|
||||
printk(TAG "ERROR! Failed to retrieve a buffer\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_data(context);
|
||||
frag = net_nbuf_get_data(context, K_FOREVER);
|
||||
if (!frag) {
|
||||
printk(TAG "ERROR! Failed to retrieve a frag\n");
|
||||
continue;
|
||||
|
@ -250,7 +251,7 @@ void zperf_udp_upload(struct net_context *context,
|
|||
htonl(HW_CYCLES_TO_USEC(loop_time) % USEC_PER_SEC);
|
||||
|
||||
status = net_nbuf_append(buf, sizeof(datagram),
|
||||
(uint8_t *)&datagram);
|
||||
(uint8_t *)&datagram, K_FOREVER);
|
||||
if (!status) {
|
||||
printk(TAG "ERROR! Cannot append datagram data\n");
|
||||
break;
|
||||
|
@ -264,7 +265,8 @@ void zperf_udp_upload(struct net_context *context,
|
|||
|
||||
frag = net_nbuf_write(buf, net_buf_frag_last(buf),
|
||||
sizeof(struct zperf_udp_datagram),
|
||||
&pos, size, sample_packet);
|
||||
&pos, size, sample_packet,
|
||||
K_FOREVER);
|
||||
}
|
||||
|
||||
/* Send the packet */
|
||||
|
|
|
@ -299,3 +299,19 @@ Here are some generic guidelines for network testing.
|
|||
for details.
|
||||
This entry should be split more to include various
|
||||
network testing frameworks.
|
||||
|
||||
|
||||
CAN
|
||||
===
|
||||
|
||||
CAN (Controller Area Network) is a networking technology
|
||||
which is used in automation, embedded devices, and
|
||||
automotive fields.
|
||||
|
||||
- Implement CAN support
|
||||
|
||||
Priority: Medium
|
||||
Complexity: C8
|
||||
|
||||
This is a placeholder for CAN support and should be
|
||||
split into smaller pieces.
|
||||
|
|
|
@ -712,10 +712,7 @@ static inline bool compress_IPHC_header(struct net_buf *buf,
|
|||
return false;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf));
|
||||
if (!frag) {
|
||||
return false;
|
||||
}
|
||||
frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf), K_FOREVER);
|
||||
|
||||
IPHC[offset++] = NET_6LO_DISPATCH_IPHC;
|
||||
IPHC[offset++] = 0;
|
||||
|
@ -787,7 +784,7 @@ end:
|
|||
net_buf_frag_insert(buf, frag);
|
||||
|
||||
/* Compact the fragments, so that gaps will be filled */
|
||||
net_nbuf_compact(buf->frags);
|
||||
net_nbuf_compact(buf);
|
||||
|
||||
if (fragment) {
|
||||
return fragment(buf, compressed - offset);
|
||||
|
@ -1287,10 +1284,7 @@ static inline bool uncompress_IPHC_header(struct net_buf *buf)
|
|||
#endif
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf));
|
||||
if (!frag) {
|
||||
return false;
|
||||
}
|
||||
frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf), K_FOREVER);
|
||||
|
||||
ipv6 = (struct net_ipv6_hdr *)(frag->data);
|
||||
|
||||
|
@ -1378,7 +1372,7 @@ end:
|
|||
|
||||
/* Insert the fragment (this one holds uncompressed headers) */
|
||||
net_buf_frag_insert(buf, frag);
|
||||
net_nbuf_compact(buf->frags);
|
||||
net_nbuf_compact(buf);
|
||||
|
||||
/* Set IPv6 header and UDP (if next header is) length */
|
||||
len = net_buf_frags_len(buf) - NET_IPV6H_LEN;
|
||||
|
@ -1406,10 +1400,7 @@ static inline bool compress_ipv6_header(struct net_buf *buf,
|
|||
{
|
||||
struct net_buf *frag;
|
||||
|
||||
frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf));
|
||||
if (!frag) {
|
||||
return false;
|
||||
}
|
||||
frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf), K_FOREVER);
|
||||
|
||||
frag->data[0] = NET_6LO_DISPATCH_IPV6;
|
||||
net_buf_add(frag, 1);
|
||||
|
@ -1417,7 +1408,7 @@ static inline bool compress_ipv6_header(struct net_buf *buf,
|
|||
net_buf_frag_insert(buf, frag);
|
||||
|
||||
/* Compact the fragments, so that gaps will be filled */
|
||||
buf->frags = net_nbuf_compact(buf->frags);
|
||||
net_nbuf_compact(buf);
|
||||
|
||||
if (fragment) {
|
||||
return fragment(buf, -1);
|
||||
|
|
|
@ -452,7 +452,7 @@ int net_conn_register(enum net_ip_protocol proto,
|
|||
if (remote_addr) {
|
||||
if (remote_addr->family != AF_INET &&
|
||||
remote_addr->family != AF_INET6) {
|
||||
NET_DBG("Remote address family not set.");
|
||||
NET_ERR("Remote address family not set.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -488,7 +488,7 @@ int net_conn_register(enum net_ip_protocol proto,
|
|||
if (local_addr) {
|
||||
if (local_addr->family != AF_INET &&
|
||||
local_addr->family != AF_INET6) {
|
||||
NET_DBG("Local address family not set.");
|
||||
NET_ERR("Local address family not set.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -522,7 +522,7 @@ int net_conn_register(enum net_ip_protocol proto,
|
|||
|
||||
if (remote_addr && local_addr) {
|
||||
if (remote_addr->family != local_addr->family) {
|
||||
NET_DBG("Address families different.");
|
||||
NET_ERR("Address families different.");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,7 +132,8 @@ static inline void unset_dhcpv4_on_iface(struct net_if *iface)
|
|||
/* Add magic cookie to DCHPv4 messages */
|
||||
static inline bool add_cookie(struct net_buf *buf)
|
||||
{
|
||||
return net_nbuf_append(buf, sizeof(magic_cookie), magic_cookie);
|
||||
return net_nbuf_append(buf, sizeof(magic_cookie), magic_cookie,
|
||||
K_FOREVER);
|
||||
}
|
||||
|
||||
/* Add DHCPv4 message type */
|
||||
|
@ -140,7 +141,7 @@ static inline bool add_msg_type(struct net_buf *buf, uint8_t type)
|
|||
{
|
||||
uint8_t data[3] = { DHCPV4_OPTIONS_MSG_TYPE, 1, type };
|
||||
|
||||
return net_nbuf_append(buf, sizeof(data), data);
|
||||
return net_nbuf_append(buf, sizeof(data), data, K_FOREVER);
|
||||
}
|
||||
|
||||
/* Add DHCPv4 minimum required options for server to reply.
|
||||
|
@ -154,7 +155,7 @@ static inline bool add_req_options(struct net_buf *buf)
|
|||
DHCPV4_OPTIONS_ROUTER,
|
||||
DHCPV4_OPTIONS_DNS_SERVER };
|
||||
|
||||
return net_nbuf_append(buf, sizeof(data), data);
|
||||
return net_nbuf_append(buf, sizeof(data), data, K_FOREVER);
|
||||
}
|
||||
|
||||
static inline bool add_server_id(struct net_buf *buf)
|
||||
|
@ -163,16 +164,17 @@ static inline bool add_server_id(struct net_buf *buf)
|
|||
uint8_t data;
|
||||
|
||||
data = DHCPV4_OPTIONS_SERVER_ID;
|
||||
if (!net_nbuf_append(buf, 1, &data)) {
|
||||
if (!net_nbuf_append(buf, 1, &data, K_FOREVER)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data = 4;
|
||||
if (!net_nbuf_append(buf, 1, &data)) {
|
||||
if (!net_nbuf_append(buf, 1, &data, K_FOREVER)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!net_nbuf_append(buf, 4, iface->dhcpv4.server_id.s4_addr)) {
|
||||
if (!net_nbuf_append(buf, 4, iface->dhcpv4.server_id.s4_addr,
|
||||
K_FOREVER)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -185,16 +187,17 @@ static inline bool add_req_ipaddr(struct net_buf *buf)
|
|||
uint8_t data;
|
||||
|
||||
data = DHCPV4_OPTIONS_REQ_IPADDR;
|
||||
if (!net_nbuf_append(buf, 1, &data)) {
|
||||
if (!net_nbuf_append(buf, 1, &data, K_FOREVER)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data = 4;
|
||||
if (!net_nbuf_append(buf, 1, &data)) {
|
||||
if (!net_nbuf_append(buf, 1, &data, K_FOREVER)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!net_nbuf_append(buf, 4, iface->dhcpv4.requested_ip.s4_addr)) {
|
||||
if (!net_nbuf_append(buf, 4, iface->dhcpv4.requested_ip.s4_addr,
|
||||
K_FOREVER)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -206,7 +209,7 @@ static inline bool add_end(struct net_buf *buf)
|
|||
{
|
||||
uint8_t data = DHCPV4_OPTIONS_END;
|
||||
|
||||
return net_nbuf_append(buf, 1, &data);
|
||||
return net_nbuf_append(buf, 1, &data, K_FOREVER);
|
||||
}
|
||||
|
||||
/* File is empty ATM */
|
||||
|
@ -216,7 +219,7 @@ static inline bool add_file(struct net_buf *buf)
|
|||
uint8_t data = 0;
|
||||
|
||||
while (len-- > 0) {
|
||||
if (!net_nbuf_append(buf, 1, &data)) {
|
||||
if (!net_nbuf_append(buf, 1, &data, K_FOREVER)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -231,7 +234,7 @@ static inline bool add_sname(struct net_buf *buf)
|
|||
uint8_t data = 0;
|
||||
|
||||
while (len-- > 0) {
|
||||
if (!net_nbuf_append(buf, 1, &data)) {
|
||||
if (!net_nbuf_append(buf, 1, &data, K_FOREVER)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -278,15 +281,10 @@ static struct net_buf *prepare_message(struct net_if *iface, uint8_t type)
|
|||
struct net_buf *frag;
|
||||
struct dhcp_msg *msg;
|
||||
|
||||
buf = net_nbuf_get_reserve_tx(0);
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
buf = net_nbuf_get_reserve_tx(0, K_FOREVER);
|
||||
|
||||
frag = net_nbuf_get_reserve_data(net_if_get_ll_reserve(iface, NULL));
|
||||
if (!frag) {
|
||||
goto fail;
|
||||
}
|
||||
frag = net_nbuf_get_reserve_data(net_if_get_ll_reserve(iface, NULL),
|
||||
K_FOREVER);
|
||||
|
||||
net_nbuf_set_ll_reserve(buf, net_buf_headroom(frag));
|
||||
net_nbuf_set_iface(buf, iface);
|
||||
|
|
|
@ -106,7 +106,7 @@ int net_icmpv4_send_echo_request(struct net_if *iface,
|
|||
/* Take the first address of the network interface */
|
||||
src = &iface->ipv4.unicast[0].address.in_addr;
|
||||
|
||||
buf = net_nbuf_get_reserve_tx(0);
|
||||
buf = net_nbuf_get_reserve_tx(0, K_FOREVER);
|
||||
|
||||
/* We cast to IPv6 address but that should be ok in this case
|
||||
* as IPv4 cannot be used in 802.15.4 where it is the reserve
|
||||
|
@ -115,7 +115,7 @@ int net_icmpv4_send_echo_request(struct net_if *iface,
|
|||
reserve = net_if_get_ll_reserve(iface,
|
||||
(const struct in6_addr *)dst);
|
||||
|
||||
frag = net_nbuf_get_reserve_data(reserve);
|
||||
frag = net_nbuf_get_reserve_data(reserve, K_FOREVER);
|
||||
|
||||
net_buf_frag_add(buf, frag);
|
||||
net_nbuf_set_family(buf, AF_INET);
|
||||
|
@ -192,7 +192,7 @@ int net_icmpv4_send_error(struct net_buf *orig, uint8_t type, uint8_t code)
|
|||
|
||||
iface = net_nbuf_iface(orig);
|
||||
|
||||
buf = net_nbuf_get_reserve_tx(0);
|
||||
buf = net_nbuf_get_reserve_tx(0, K_FOREVER);
|
||||
|
||||
reserve = sizeof(struct net_ipv4_hdr) + sizeof(struct net_icmp_hdr) +
|
||||
NET_ICMPV4_UNUSED_LEN;
|
||||
|
@ -223,7 +223,7 @@ int net_icmpv4_send_error(struct net_buf *orig, uint8_t type, uint8_t code)
|
|||
/* We only copy minimal IPv4 + next header from original message.
|
||||
* This is so that the memory pressure is minimized.
|
||||
*/
|
||||
frag = net_nbuf_copy(orig->frags, extra_len, reserve);
|
||||
frag = net_nbuf_copy(orig->frags, extra_len, reserve, K_FOREVER);
|
||||
if (!frag) {
|
||||
goto drop;
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ static enum net_verdict handle_echo_request(struct net_buf *orig)
|
|||
|
||||
iface = net_nbuf_iface(orig);
|
||||
|
||||
buf = net_nbuf_get_reserve_tx(0);
|
||||
buf = net_nbuf_get_reserve_tx(0, K_FOREVER);
|
||||
|
||||
/* We need to remember the original location of source and destination
|
||||
* addresses as the net_nbuf_copy() will mangle the original buffer.
|
||||
|
@ -96,7 +96,7 @@ static enum net_verdict handle_echo_request(struct net_buf *orig)
|
|||
payload_len = sys_get_be16(NET_IPV6_BUF(orig)->len) -
|
||||
sizeof(NET_ICMPH_LEN) - NET_ICMPV6_UNUSED_LEN;
|
||||
|
||||
frag = net_nbuf_copy_all(orig->frags, 0);
|
||||
frag = net_nbuf_copy_all(orig->frags, 0, K_FOREVER);
|
||||
if (!frag) {
|
||||
goto drop;
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ int net_icmpv6_send_error(struct net_buf *orig, uint8_t type, uint8_t code,
|
|||
|
||||
iface = net_nbuf_iface(orig);
|
||||
|
||||
buf = net_nbuf_get_reserve_tx(0);
|
||||
buf = net_nbuf_get_reserve_tx(0, K_FOREVER);
|
||||
|
||||
/* We need to remember the original location of source and destination
|
||||
* addresses as the net_nbuf_copy() will mangle the original buffer.
|
||||
|
@ -215,7 +215,7 @@ int net_icmpv6_send_error(struct net_buf *orig, uint8_t type, uint8_t code,
|
|||
/* We only copy minimal IPv6 + next header from original message.
|
||||
* This is so that the memory pressure is minimized.
|
||||
*/
|
||||
frag = net_nbuf_copy(orig->frags, extra_len, reserve);
|
||||
frag = net_nbuf_copy(orig->frags, extra_len, reserve, K_FOREVER);
|
||||
if (!frag) {
|
||||
goto drop;
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ int net_icmpv6_send_echo_request(struct net_if *iface,
|
|||
|
||||
src = net_if_ipv6_select_src_addr(iface, dst);
|
||||
|
||||
buf = net_nbuf_get_reserve_tx(0);
|
||||
buf = net_nbuf_get_reserve_tx(0, K_FOREVER);
|
||||
|
||||
reserve = net_if_get_ll_reserve(iface, dst);
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ struct net_buf *net_ipv4_create_raw(struct net_buf *buf,
|
|||
{
|
||||
struct net_buf *header;
|
||||
|
||||
header = net_nbuf_get_reserve_data(reserve);
|
||||
header = net_nbuf_get_reserve_data(reserve, K_FOREVER);
|
||||
|
||||
net_buf_frag_insert(buf, header);
|
||||
|
||||
|
|
|
@ -292,7 +292,7 @@ struct net_buf *net_ipv6_create_raw(struct net_buf *buf,
|
|||
{
|
||||
struct net_buf *header;
|
||||
|
||||
header = net_nbuf_get_reserve_data(reserve);
|
||||
header = net_nbuf_get_reserve_data(reserve, K_FOREVER);
|
||||
|
||||
net_buf_frag_insert(buf, header);
|
||||
|
||||
|
@ -520,7 +520,7 @@ static struct net_buf *update_ll_reserve(struct net_buf *buf,
|
|||
|
||||
while (orig_frag) {
|
||||
if (!room_len) {
|
||||
frag = net_nbuf_get_reserve_data(reserve);
|
||||
frag = net_nbuf_get_reserve_data(reserve, K_FOREVER);
|
||||
|
||||
net_buf_frag_add(buf, frag);
|
||||
|
||||
|
@ -874,11 +874,12 @@ int net_ipv6_send_na(struct net_if *iface, struct in6_addr *src,
|
|||
struct net_buf *buf, *frag;
|
||||
uint8_t llao_len;
|
||||
|
||||
buf = net_nbuf_get_reserve_tx(0);
|
||||
buf = net_nbuf_get_reserve_tx(0, K_FOREVER);
|
||||
|
||||
NET_ASSERT_INFO(buf, "Out of TX buffers");
|
||||
|
||||
frag = net_nbuf_get_reserve_data(net_if_get_ll_reserve(iface, dst));
|
||||
frag = net_nbuf_get_reserve_data(net_if_get_ll_reserve(iface, dst),
|
||||
K_FOREVER);
|
||||
|
||||
NET_ASSERT_INFO(frag, "Out of DATA buffers");
|
||||
|
||||
|
@ -1349,11 +1350,12 @@ send_pending:
|
|||
cached_lladdr->len));
|
||||
|
||||
if (net_send_data(pending) < 0) {
|
||||
net_nbuf_unref(pending);
|
||||
nbr_clear_ns_pending(net_ipv6_nbr_data(nbr));
|
||||
} else {
|
||||
net_ipv6_nbr_data(nbr)->pending = NULL;
|
||||
}
|
||||
|
||||
net_nbuf_unref(pending);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1452,6 +1454,8 @@ static enum net_verdict handle_na_input(struct net_buf *buf)
|
|||
goto drop;
|
||||
}
|
||||
|
||||
net_nbuf_unref(buf);
|
||||
|
||||
net_stats_update_ipv6_nd_sent();
|
||||
|
||||
return NET_OK;
|
||||
|
@ -1473,11 +1477,12 @@ int net_ipv6_send_ns(struct net_if *iface,
|
|||
struct net_nbr *nbr;
|
||||
uint8_t llao_len;
|
||||
|
||||
buf = net_nbuf_get_reserve_tx(0);
|
||||
buf = net_nbuf_get_reserve_tx(0, K_FOREVER);
|
||||
|
||||
NET_ASSERT_INFO(buf, "Out of TX buffers");
|
||||
|
||||
frag = net_nbuf_get_reserve_data(net_if_get_ll_reserve(iface, dst));
|
||||
frag = net_nbuf_get_reserve_data(net_if_get_ll_reserve(iface, dst),
|
||||
K_FOREVER);
|
||||
|
||||
NET_ASSERT_INFO(frag, "Out of DATA buffers");
|
||||
|
||||
|
@ -1608,10 +1613,11 @@ int net_ipv6_send_rs(struct net_if *iface)
|
|||
bool unspec_src;
|
||||
uint8_t llao_len = 0;
|
||||
|
||||
buf = net_nbuf_get_reserve_tx(0);
|
||||
buf = net_nbuf_get_reserve_tx(0, K_FOREVER);
|
||||
|
||||
frag = net_nbuf_get_reserve_data(
|
||||
net_if_get_ll_reserve(iface, &NET_IPV6_BUF(buf)->dst));
|
||||
net_if_get_ll_reserve(iface, &NET_IPV6_BUF(buf)->dst),
|
||||
K_FOREVER);
|
||||
|
||||
net_buf_frag_add(buf, frag);
|
||||
|
||||
|
|
|
@ -107,12 +107,13 @@ static inline struct net_buf *prepare_arp(struct net_if *iface,
|
|||
struct net_eth_hdr *eth;
|
||||
struct in_addr *my_addr;
|
||||
|
||||
buf = net_nbuf_get_reserve_tx(0);
|
||||
buf = net_nbuf_get_reserve_tx(0, K_FOREVER);
|
||||
if (!buf) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_reserve_data(sizeof(struct net_eth_hdr));
|
||||
frag = net_nbuf_get_reserve_data(sizeof(struct net_eth_hdr),
|
||||
K_FOREVER);
|
||||
if (!frag) {
|
||||
goto fail;
|
||||
}
|
||||
|
@ -202,9 +203,12 @@ struct net_buf *net_arp_prepare(struct net_buf *buf)
|
|||
|
||||
net_nbuf_set_ll_reserve(buf, sizeof(struct net_eth_hdr));
|
||||
|
||||
header = net_nbuf_get_reserve_data(sizeof(struct net_eth_hdr));
|
||||
header = net_nbuf_get_reserve_data(sizeof(struct net_eth_hdr),
|
||||
K_FOREVER);
|
||||
|
||||
hdr = (struct net_eth_hdr *)(header->data -
|
||||
net_nbuf_ll_reserve(buf));
|
||||
|
||||
hdr = (struct net_eth_hdr *)net_nbuf_ll(header);
|
||||
hdr->type = htons(NET_ETH_PTYPE_IP);
|
||||
|
||||
ll = net_nbuf_ll_dst(buf);
|
||||
|
@ -221,7 +225,7 @@ struct net_buf *net_arp_prepare(struct net_buf *buf)
|
|||
|
||||
net_buf_frag_insert(buf, header);
|
||||
|
||||
buf = net_nbuf_compact(buf);
|
||||
net_nbuf_compact(buf);
|
||||
}
|
||||
|
||||
hdr = (struct net_eth_hdr *)net_nbuf_ll(buf);
|
||||
|
@ -371,12 +375,13 @@ static inline struct net_buf *prepare_arp_reply(struct net_if *iface,
|
|||
struct net_arp_hdr *hdr, *query;
|
||||
struct net_eth_hdr *eth, *eth_query;
|
||||
|
||||
buf = net_nbuf_get_reserve_tx(0);
|
||||
buf = net_nbuf_get_reserve_tx(0, K_FOREVER);
|
||||
if (!buf) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_reserve_data(sizeof(struct net_eth_hdr));
|
||||
frag = net_nbuf_get_reserve_data(sizeof(struct net_eth_hdr),
|
||||
K_FOREVER);
|
||||
if (!frag) {
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
@ -191,7 +191,7 @@ static void ipsp_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
|
|||
net_buf_frags_len(buf));
|
||||
|
||||
/* Get buffer for bearer / protocol related data */
|
||||
nbuf = net_nbuf_get_reserve_rx(0);
|
||||
nbuf = net_nbuf_get_reserve_rx(0, K_FOREVER);
|
||||
|
||||
/* Set destination address */
|
||||
net_nbuf_ll_dst(nbuf)->addr = ctxt->src.val;
|
||||
|
@ -216,7 +216,7 @@ static struct net_buf *ipsp_alloc_buf(struct bt_l2cap_chan *chan)
|
|||
{
|
||||
NET_DBG("Channel %p requires buffer", chan);
|
||||
|
||||
return net_nbuf_get_reserve_data(0);
|
||||
return net_nbuf_get_reserve_data(0, K_FOREVER);
|
||||
}
|
||||
|
||||
static struct bt_l2cap_chan_ops ipsp_ops = {
|
||||
|
|
|
@ -92,12 +92,12 @@ static inline void ieee802154_acknowledge(struct net_if *iface,
|
|||
return;
|
||||
}
|
||||
|
||||
buf = net_nbuf_get_reserve_tx(0);
|
||||
buf = net_nbuf_get_reserve_tx(0, K_FOREVER);
|
||||
if (!buf) {
|
||||
return;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_reserve_data(IEEE802154_ACK_PKT_LENGTH);
|
||||
frag = net_nbuf_get_reserve_data(IEEE802154_ACK_PKT_LENGTH, K_FOREVER);
|
||||
|
||||
net_buf_frag_insert(buf, frag);
|
||||
net_nbuf_set_ll_reserve(buf, net_buf_headroom(frag));
|
||||
|
|
|
@ -78,6 +78,28 @@ static struct frag_cache cache[REASS_CACHE_SIZE];
|
|||
* +-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
static inline struct net_buf *prepare_new_fragment(struct net_buf *buf,
|
||||
uint8_t offset)
|
||||
{
|
||||
struct net_buf *frag;
|
||||
|
||||
frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf), K_FOREVER);
|
||||
if (!frag) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Reserve space for fragmentation header */
|
||||
if (!offset) {
|
||||
net_buf_add(frag, NET_6LO_FRAG1_HDR_LEN);
|
||||
} else {
|
||||
net_buf_add(frag, NET_6LO_FRAGN_HDR_LEN);
|
||||
}
|
||||
|
||||
net_buf_frag_add(buf, frag);
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
static inline void set_datagram_size(uint8_t *ptr, uint16_t size)
|
||||
{
|
||||
ptr[0] |= ((size & 0x7FF) >> 8);
|
||||
|
@ -126,28 +148,43 @@ static inline uint8_t calc_max_payload(struct net_buf *buf,
|
|||
|
||||
static inline uint8_t move_frag_data(struct net_buf *frag,
|
||||
struct net_buf *next,
|
||||
uint8_t max, uint8_t moved,
|
||||
uint8_t offset,
|
||||
int hdr_diff)
|
||||
uint8_t max,
|
||||
bool first,
|
||||
int hdr_diff,
|
||||
uint8_t *room_left)
|
||||
{
|
||||
uint8_t remaining = max - moved;
|
||||
uint8_t room;
|
||||
uint8_t move;
|
||||
uint8_t occupied;
|
||||
|
||||
if (!offset) {
|
||||
remaining -= hdr_diff;
|
||||
/* First fragment */
|
||||
if (first) {
|
||||
occupied = frag->len - NET_6LO_FRAG1_HDR_LEN;
|
||||
} else {
|
||||
occupied = frag->len - NET_6LO_FRAGN_HDR_LEN;
|
||||
}
|
||||
|
||||
/* Calculate remaining space for data to move */
|
||||
move = next->len > remaining ? remaining : next->len;
|
||||
/* Remaining room for data */
|
||||
room = max - occupied;
|
||||
|
||||
if (first) {
|
||||
room -= hdr_diff;
|
||||
}
|
||||
|
||||
/* Calculate remaining room space for data to move */
|
||||
move = next->len > room ? room : next->len;
|
||||
|
||||
memmove(frag->data + frag->len, next->data, move);
|
||||
|
||||
net_buf_add(frag, move);
|
||||
|
||||
/* Room left in current fragment */
|
||||
*room_left = room - move;
|
||||
|
||||
return move;
|
||||
}
|
||||
|
||||
static inline uint8_t compact_frag(struct net_buf *frag, uint8_t moved)
|
||||
static inline void compact_frag(struct net_buf *frag, uint8_t moved)
|
||||
{
|
||||
uint8_t remaining = frag->len - moved;
|
||||
|
||||
|
@ -155,13 +192,10 @@ static inline uint8_t compact_frag(struct net_buf *frag, uint8_t moved)
|
|||
* (leave space for header).
|
||||
*/
|
||||
if (remaining) {
|
||||
memmove(frag->data + NET_6LO_FRAGN_HDR_LEN,
|
||||
frag->data + moved, remaining);
|
||||
memmove(frag->data, frag->data + moved, remaining);
|
||||
}
|
||||
|
||||
frag->len = NET_6LO_FRAGN_HDR_LEN + remaining;
|
||||
|
||||
return remaining;
|
||||
frag->len = remaining;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -194,9 +228,10 @@ bool ieee802154_fragment(struct net_buf *buf, int hdr_diff)
|
|||
uint16_t processed;
|
||||
uint16_t offset;
|
||||
uint16_t size;
|
||||
uint8_t moved;
|
||||
uint8_t room;
|
||||
uint8_t move;
|
||||
uint8_t max;
|
||||
bool first;
|
||||
|
||||
if (!buf || !buf->frags) {
|
||||
return false;
|
||||
|
@ -207,65 +242,55 @@ bool ieee802154_fragment(struct net_buf *buf, int hdr_diff)
|
|||
return true;
|
||||
}
|
||||
|
||||
datagram_tag++;
|
||||
|
||||
/* Datagram_size: total length before compression */
|
||||
size = net_buf_frags_len(buf) + hdr_diff;
|
||||
|
||||
frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf));
|
||||
if (!frag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Reserve space for fragmentation header */
|
||||
net_buf_add(frag, NET_6LO_FRAG1_HDR_LEN);
|
||||
net_buf_frag_insert(buf, frag);
|
||||
|
||||
room = 0;
|
||||
offset = 0;
|
||||
moved = 0;
|
||||
processed = 0;
|
||||
next = frag->frags;
|
||||
first = true;
|
||||
datagram_tag++;
|
||||
|
||||
next = buf->frags;
|
||||
buf->frags = NULL;
|
||||
|
||||
/* First fragment has compressed header, but SIZE and OFFSET
|
||||
* values in fragmentation header are based on uncompressed
|
||||
* IP packet.
|
||||
*/
|
||||
while (1) {
|
||||
/* Set fragmentation header in the beginning */
|
||||
set_up_frag_hdr(frag, size, offset);
|
||||
|
||||
/* Calculate max payload in multiples of 8 bytes */
|
||||
max = calc_max_payload(buf, frag, offset);
|
||||
|
||||
/* Move data from next fragment to current fragment */
|
||||
move = move_frag_data(frag, next, max, moved, offset,
|
||||
hdr_diff);
|
||||
|
||||
/* Compact the next fragment, returns how much data moved */
|
||||
moved = compact_frag(next, move);
|
||||
|
||||
/* Calculate how much data is processed */
|
||||
processed += max;
|
||||
|
||||
offset = processed >> 3;
|
||||
|
||||
/** If next fragment is last and data already moved to previous
|
||||
* fragment, then delete this fragment, if data is left insert
|
||||
* header.
|
||||
*/
|
||||
if (!next->frags) {
|
||||
if (next->len == NET_6LO_FRAGN_HDR_LEN) {
|
||||
net_buf_frag_del(frag, next);
|
||||
} else {
|
||||
set_up_frag_hdr(next, size, offset);
|
||||
if (!room) {
|
||||
/* Prepare new fragment based on offset */
|
||||
frag = prepare_new_fragment(buf, offset);
|
||||
if (!frag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
/* Set fragmentation header in the beginning */
|
||||
set_up_frag_hdr(frag, size, offset);
|
||||
|
||||
/* Calculate max payload in multiples of 8 bytes */
|
||||
max = calc_max_payload(buf, frag, offset);
|
||||
|
||||
/* Calculate how much data is processed */
|
||||
processed += max;
|
||||
|
||||
offset = processed >> 3;
|
||||
}
|
||||
|
||||
/* Repeat the steps */
|
||||
frag = next;
|
||||
next = next->frags;
|
||||
/* Move data from next fragment to current fragment */
|
||||
move = move_frag_data(frag, next, max, first, hdr_diff, &room);
|
||||
first = false;
|
||||
|
||||
/* Compact the next fragment */
|
||||
compact_frag(next, move);
|
||||
|
||||
if (!next->len) {
|
||||
next = net_buf_frag_del(NULL, next);
|
||||
if (!next) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -397,7 +422,7 @@ static inline bool copy_frag(struct net_buf *buf,
|
|||
|
||||
while (input) {
|
||||
write = net_nbuf_write(buf, write, pos, &pos, input->len,
|
||||
input->data);
|
||||
input->data, K_FOREVER);
|
||||
if (!write && pos == 0xffff) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -635,12 +635,12 @@ ieee802154_create_mac_cmd_frame(struct net_if *iface,
|
|||
struct net_buf *buf, *frag;
|
||||
uint8_t *p_buf;
|
||||
|
||||
buf = net_nbuf_get_reserve_tx(0);
|
||||
buf = net_nbuf_get_reserve_tx(0, K_FOREVER);
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_reserve_data(0);
|
||||
frag = net_nbuf_get_reserve_data(0, K_FOREVER);
|
||||
if (!frag) {
|
||||
goto error;
|
||||
}
|
||||
|
|
|
@ -311,11 +311,13 @@ void net_nbuf_print_frags(struct net_buf *buf)
|
|||
|
||||
static struct net_buf *net_nbuf_get_reserve_debug(struct net_buf_pool *pool,
|
||||
uint16_t reserve_head,
|
||||
int32_t timeout,
|
||||
const char *caller,
|
||||
int line)
|
||||
#else /* CONFIG_NET_DEBUG_NET_BUF */
|
||||
static struct net_buf *net_nbuf_get_reserve(struct net_buf_pool *pool,
|
||||
uint16_t reserve_head)
|
||||
uint16_t reserve_head,
|
||||
int32_t timeout)
|
||||
#endif /* CONFIG_NET_DEBUG_NET_BUF */
|
||||
{
|
||||
struct net_buf *buf = NULL;
|
||||
|
@ -327,11 +329,12 @@ static struct net_buf *net_nbuf_get_reserve(struct net_buf_pool *pool,
|
|||
|
||||
if (k_is_in_isr()) {
|
||||
buf = net_buf_alloc(pool, K_NO_WAIT);
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
buf = net_buf_alloc(pool, K_FOREVER);
|
||||
buf = net_buf_alloc(pool, timeout);
|
||||
}
|
||||
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pool == &data_buffers) {
|
||||
|
@ -356,41 +359,47 @@ static struct net_buf *net_nbuf_get_reserve(struct net_buf_pool *pool,
|
|||
|
||||
#if defined(CONFIG_NET_DEBUG_NET_BUF)
|
||||
struct net_buf *net_nbuf_get_reserve_rx_debug(uint16_t reserve_head,
|
||||
int32_t timeout,
|
||||
const char *caller, int line)
|
||||
{
|
||||
return net_nbuf_get_reserve_debug(&rx_buffers, reserve_head,
|
||||
return net_nbuf_get_reserve_debug(&rx_buffers, reserve_head, timeout,
|
||||
caller, line);
|
||||
}
|
||||
|
||||
struct net_buf *net_nbuf_get_reserve_tx_debug(uint16_t reserve_head,
|
||||
int32_t timeout,
|
||||
const char *caller, int line)
|
||||
{
|
||||
return net_nbuf_get_reserve_debug(&tx_buffers, reserve_head,
|
||||
return net_nbuf_get_reserve_debug(&tx_buffers, reserve_head, timeout,
|
||||
caller, line);
|
||||
}
|
||||
|
||||
struct net_buf *net_nbuf_get_reserve_data_debug(uint16_t reserve_head,
|
||||
int32_t timeout,
|
||||
const char *caller, int line)
|
||||
{
|
||||
return net_nbuf_get_reserve_debug(&data_buffers, reserve_head,
|
||||
caller, line);
|
||||
timeout, caller, line);
|
||||
}
|
||||
|
||||
#else /* CONFIG_NET_DEBUG_NET_BUF */
|
||||
|
||||
struct net_buf *net_nbuf_get_reserve_rx(uint16_t reserve_head)
|
||||
struct net_buf *net_nbuf_get_reserve_rx(uint16_t reserve_head,
|
||||
int32_t timeout)
|
||||
{
|
||||
return net_nbuf_get_reserve(&rx_buffers, reserve_head);
|
||||
return net_nbuf_get_reserve(&rx_buffers, reserve_head, timeout);
|
||||
}
|
||||
|
||||
struct net_buf *net_nbuf_get_reserve_tx(uint16_t reserve_head)
|
||||
struct net_buf *net_nbuf_get_reserve_tx(uint16_t reserve_head,
|
||||
int32_t timeout)
|
||||
{
|
||||
return net_nbuf_get_reserve(&tx_buffers, reserve_head);
|
||||
return net_nbuf_get_reserve(&tx_buffers, reserve_head, timeout);
|
||||
}
|
||||
|
||||
struct net_buf *net_nbuf_get_reserve_data(uint16_t reserve_head)
|
||||
struct net_buf *net_nbuf_get_reserve_data(uint16_t reserve_head,
|
||||
int32_t timeout)
|
||||
{
|
||||
return net_nbuf_get_reserve(&data_buffers, reserve_head);
|
||||
return net_nbuf_get_reserve(&data_buffers, reserve_head, timeout);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET_DEBUG_NET_BUF */
|
||||
|
@ -399,10 +408,12 @@ struct net_buf *net_nbuf_get_reserve_data(uint16_t reserve_head)
|
|||
#if defined(CONFIG_NET_DEBUG_NET_BUF)
|
||||
static struct net_buf *net_nbuf_get_debug(struct net_buf_pool *pool,
|
||||
struct net_context *context,
|
||||
int32_t timeout,
|
||||
const char *caller, int line)
|
||||
#else
|
||||
static struct net_buf *net_nbuf_get(struct net_buf_pool *pool,
|
||||
struct net_context *context)
|
||||
struct net_context *context,
|
||||
int32_t timeout)
|
||||
#endif /* CONFIG_NET_DEBUG_NET_BUF */
|
||||
{
|
||||
struct in6_addr *addr6 = NULL;
|
||||
|
@ -425,9 +436,9 @@ static struct net_buf *net_nbuf_get(struct net_buf_pool *pool,
|
|||
reserve = net_if_get_ll_reserve(iface, addr6);
|
||||
|
||||
#if defined(CONFIG_NET_DEBUG_NET_BUF)
|
||||
buf = net_nbuf_get_reserve_debug(pool, reserve, caller, line);
|
||||
buf = net_nbuf_get_reserve_debug(pool, reserve, timeout, caller, line);
|
||||
#else
|
||||
buf = net_nbuf_get_reserve(pool, reserve);
|
||||
buf = net_nbuf_get_reserve(pool, reserve, timeout);
|
||||
#endif
|
||||
if (!buf) {
|
||||
return buf;
|
||||
|
@ -449,44 +460,48 @@ static struct net_buf *net_nbuf_get(struct net_buf_pool *pool,
|
|||
|
||||
#if defined(CONFIG_NET_DEBUG_NET_BUF)
|
||||
struct net_buf *net_nbuf_get_rx_debug(struct net_context *context,
|
||||
int32_t timeout,
|
||||
const char *caller, int line)
|
||||
{
|
||||
return net_nbuf_get_debug(&rx_buffers, context, caller, line);
|
||||
return net_nbuf_get_debug(&rx_buffers, context, timeout, caller, line);
|
||||
}
|
||||
|
||||
struct net_buf *net_nbuf_get_tx_debug(struct net_context *context,
|
||||
int32_t timeout,
|
||||
const char *caller, int line)
|
||||
{
|
||||
return net_nbuf_get_debug(&tx_buffers, context, caller, line);
|
||||
return net_nbuf_get_debug(&tx_buffers, context, timeout, caller, line);
|
||||
}
|
||||
|
||||
struct net_buf *net_nbuf_get_data_debug(struct net_context *context,
|
||||
int32_t timeout,
|
||||
const char *caller, int line)
|
||||
{
|
||||
return net_nbuf_get_debug(&data_buffers, context, caller, line);
|
||||
return net_nbuf_get_debug(&data_buffers, context, timeout,
|
||||
caller, line);
|
||||
}
|
||||
|
||||
#else /* CONFIG_NET_DEBUG_NET_BUF */
|
||||
|
||||
struct net_buf *net_nbuf_get_rx(struct net_context *context)
|
||||
struct net_buf *net_nbuf_get_rx(struct net_context *context, int32_t timeout)
|
||||
{
|
||||
NET_ASSERT_INFO(context, "RX context not set");
|
||||
|
||||
return net_nbuf_get(&rx_buffers, context);
|
||||
return net_nbuf_get(&rx_buffers, context, timeout);
|
||||
}
|
||||
|
||||
struct net_buf *net_nbuf_get_tx(struct net_context *context)
|
||||
struct net_buf *net_nbuf_get_tx(struct net_context *context, int32_t timeout)
|
||||
{
|
||||
NET_ASSERT_INFO(context, "TX context not set");
|
||||
|
||||
return net_nbuf_get(&tx_buffers, context);
|
||||
return net_nbuf_get(&tx_buffers, context, timeout);
|
||||
}
|
||||
|
||||
struct net_buf *net_nbuf_get_data(struct net_context *context)
|
||||
struct net_buf *net_nbuf_get_data(struct net_context *context, int32_t timeout)
|
||||
{
|
||||
NET_ASSERT_INFO(context, "Data context not set");
|
||||
|
||||
return net_nbuf_get(&data_buffers, context);
|
||||
return net_nbuf_get(&data_buffers, context, timeout);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET_DEBUG_NET_BUF */
|
||||
|
@ -564,7 +579,7 @@ struct net_buf *net_nbuf_ref(struct net_buf *buf)
|
|||
}
|
||||
|
||||
struct net_buf *net_nbuf_copy(struct net_buf *orig, size_t amount,
|
||||
size_t reserve)
|
||||
size_t reserve, int32_t timeout)
|
||||
{
|
||||
uint16_t ll_reserve = net_buf_headroom(orig);
|
||||
struct net_buf *frag, *first;
|
||||
|
@ -574,7 +589,10 @@ struct net_buf *net_nbuf_copy(struct net_buf *orig, size_t amount,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_reserve_data(ll_reserve);
|
||||
frag = net_nbuf_get_reserve_data(ll_reserve, timeout);
|
||||
if (!frag) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (reserve > net_buf_tailroom(frag)) {
|
||||
NET_ERR("Reserve %zu is too long, max is %zu",
|
||||
|
@ -622,7 +640,12 @@ struct net_buf *net_nbuf_copy(struct net_buf *orig, size_t amount,
|
|||
* We must allocate a new one.
|
||||
*/
|
||||
struct net_buf *new_frag =
|
||||
net_nbuf_get_reserve_data(ll_reserve);
|
||||
net_nbuf_get_reserve_data(ll_reserve,
|
||||
timeout);
|
||||
if (!new_frag) {
|
||||
net_nbuf_unref(first);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
net_buf_frag_add(frag, new_frag);
|
||||
|
||||
|
@ -728,20 +751,19 @@ bool net_nbuf_is_compact(struct net_buf *buf)
|
|||
return false;
|
||||
}
|
||||
|
||||
struct net_buf *net_nbuf_compact(struct net_buf *buf)
|
||||
bool net_nbuf_compact(struct net_buf *buf)
|
||||
{
|
||||
struct net_buf *first, *prev;
|
||||
struct net_buf *prev;
|
||||
|
||||
first = buf;
|
||||
|
||||
if (!is_from_data_pool(buf)) {
|
||||
NET_DBG("Buffer %p is not a data fragment", buf);
|
||||
buf = buf->frags;
|
||||
if (is_from_data_pool(buf)) {
|
||||
NET_DBG("Buffer %p is a data fragment", buf);
|
||||
return false;
|
||||
}
|
||||
|
||||
prev = NULL;
|
||||
NET_DBG("Compacting data to buf %p", buf);
|
||||
|
||||
NET_DBG("Compacting data to buf %p", first);
|
||||
buf = buf->frags;
|
||||
prev = NULL;
|
||||
|
||||
while (buf) {
|
||||
if (buf->frags) {
|
||||
|
@ -766,16 +788,10 @@ struct net_buf *net_nbuf_compact(struct net_buf *buf)
|
|||
|
||||
/* Is there any more space in this fragment */
|
||||
if (net_buf_tailroom(buf)) {
|
||||
struct net_buf *frag;
|
||||
|
||||
/* There is. This also means that the next
|
||||
* fragment is empty as otherwise we could
|
||||
* not have copied all data.
|
||||
*/
|
||||
frag = buf->frags;
|
||||
|
||||
/* Remove next fragment as there is no
|
||||
* data in it any more.
|
||||
* not have copied all data. Remove next
|
||||
* fragment as there is no data in it any more.
|
||||
*/
|
||||
net_buf_frag_del(buf, buf->frags);
|
||||
|
||||
|
@ -787,10 +803,9 @@ struct net_buf *net_nbuf_compact(struct net_buf *buf)
|
|||
/* Remove the last fragment because there is no
|
||||
* data in it.
|
||||
*/
|
||||
NET_ASSERT_INFO(prev,
|
||||
"First element cannot be deleted!");
|
||||
|
||||
net_buf_frag_del(prev, buf);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -798,36 +813,7 @@ struct net_buf *net_nbuf_compact(struct net_buf *buf)
|
|||
buf = buf->frags;
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
struct net_buf *net_nbuf_push(struct net_buf *parent,
|
||||
struct net_buf *buf,
|
||||
size_t amount)
|
||||
{
|
||||
struct net_buf *frag;
|
||||
|
||||
NET_ASSERT_INFO(amount > 3,
|
||||
"Amount %zu very small and not recommended", amount);
|
||||
|
||||
if (amount > buf->len) {
|
||||
NET_DBG("Cannot move amount %zu because the buf "
|
||||
"length is only %u bytes", amount, buf->len);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_reserve_data(net_buf_headroom(buf));
|
||||
|
||||
net_buf_add(frag, amount);
|
||||
|
||||
if (parent) {
|
||||
net_buf_frag_insert(parent, frag);
|
||||
} else {
|
||||
net_buf_frag_insert(frag, buf);
|
||||
parent = frag;
|
||||
}
|
||||
|
||||
return net_nbuf_compact(parent);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct net_buf *net_nbuf_pull(struct net_buf *buf, size_t amount)
|
||||
|
@ -898,7 +884,7 @@ struct net_buf *net_nbuf_pull(struct net_buf *buf, size_t amount)
|
|||
* the buffer. It assumes that the buffer has at least one fragment.
|
||||
*/
|
||||
static inline bool net_nbuf_append_bytes(struct net_buf *buf, uint8_t *value,
|
||||
uint16_t len)
|
||||
uint16_t len, int32_t timeout)
|
||||
{
|
||||
struct net_buf *frag = net_buf_frag_last(buf);
|
||||
uint16_t ll_reserve = net_nbuf_ll_reserve(buf);
|
||||
|
@ -915,7 +901,7 @@ static inline bool net_nbuf_append_bytes(struct net_buf *buf, uint8_t *value,
|
|||
return true;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_reserve_data(ll_reserve);
|
||||
frag = net_nbuf_get_reserve_data(ll_reserve, timeout);
|
||||
if (!frag) {
|
||||
return false;
|
||||
}
|
||||
|
@ -926,7 +912,8 @@ static inline bool net_nbuf_append_bytes(struct net_buf *buf, uint8_t *value,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool net_nbuf_append(struct net_buf *buf, uint16_t len, uint8_t *data)
|
||||
bool net_nbuf_append(struct net_buf *buf, uint16_t len, uint8_t *data,
|
||||
int32_t timeout)
|
||||
{
|
||||
struct net_buf *frag;
|
||||
|
||||
|
@ -944,7 +931,8 @@ bool net_nbuf_append(struct net_buf *buf, uint16_t len, uint8_t *data)
|
|||
}
|
||||
|
||||
if (!buf->frags) {
|
||||
frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf));
|
||||
frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf),
|
||||
timeout);
|
||||
if (!frag) {
|
||||
return false;
|
||||
}
|
||||
|
@ -952,7 +940,7 @@ bool net_nbuf_append(struct net_buf *buf, uint16_t len, uint8_t *data)
|
|||
net_buf_frag_add(buf, frag);
|
||||
}
|
||||
|
||||
return net_nbuf_append_bytes(buf, data, len);
|
||||
return net_nbuf_append_bytes(buf, data, len, timeout);
|
||||
}
|
||||
|
||||
/* Helper routine to retrieve single byte from fragment and move
|
||||
|
@ -1069,7 +1057,8 @@ struct net_buf *net_nbuf_read_be32(struct net_buf *buf, uint16_t offset,
|
|||
}
|
||||
|
||||
static inline struct net_buf *check_and_create_data(struct net_buf *buf,
|
||||
struct net_buf *data)
|
||||
struct net_buf *data,
|
||||
int32_t timeout)
|
||||
{
|
||||
struct net_buf *frag;
|
||||
|
||||
|
@ -1077,7 +1066,8 @@ static inline struct net_buf *check_and_create_data(struct net_buf *buf,
|
|||
return data;
|
||||
}
|
||||
|
||||
frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf));
|
||||
frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf),
|
||||
timeout);
|
||||
if (!frag) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1090,12 +1080,13 @@ static inline struct net_buf *check_and_create_data(struct net_buf *buf,
|
|||
static inline struct net_buf *adjust_write_offset(struct net_buf *buf,
|
||||
struct net_buf *frag,
|
||||
uint16_t offset,
|
||||
uint16_t *pos)
|
||||
uint16_t *pos,
|
||||
int32_t timeout)
|
||||
{
|
||||
uint16_t tailroom;
|
||||
|
||||
do {
|
||||
frag = check_and_create_data(buf, frag);
|
||||
frag = check_and_create_data(buf, frag, timeout);
|
||||
if (!frag) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1122,7 +1113,8 @@ static inline struct net_buf *adjust_write_offset(struct net_buf *buf,
|
|||
|
||||
*pos = 0;
|
||||
|
||||
return check_and_create_data(buf, frag->frags);
|
||||
return check_and_create_data(buf, frag->frags,
|
||||
timeout);
|
||||
}
|
||||
|
||||
/* If the offset is more than current fragment length, remove
|
||||
|
@ -1150,7 +1142,9 @@ static inline struct net_buf *adjust_write_offset(struct net_buf *buf,
|
|||
|
||||
*pos = 0;
|
||||
|
||||
return check_and_create_data(buf, frag->frags);
|
||||
return check_and_create_data(buf,
|
||||
frag->frags,
|
||||
timeout);
|
||||
}
|
||||
|
||||
if (offset > tailroom) {
|
||||
|
@ -1158,7 +1152,9 @@ static inline struct net_buf *adjust_write_offset(struct net_buf *buf,
|
|||
net_buf_add(frag, tailroom);
|
||||
offset -= tailroom;
|
||||
|
||||
frag = check_and_create_data(buf, frag->frags);
|
||||
frag = check_and_create_data(buf,
|
||||
frag->frags,
|
||||
timeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1169,7 +1165,8 @@ static inline struct net_buf *adjust_write_offset(struct net_buf *buf,
|
|||
|
||||
struct net_buf *net_nbuf_write(struct net_buf *buf, struct net_buf *frag,
|
||||
uint16_t offset, uint16_t *pos,
|
||||
uint16_t len, uint8_t *data)
|
||||
uint16_t len, uint8_t *data,
|
||||
int32_t timeout)
|
||||
{
|
||||
uint16_t ll_reserve;
|
||||
|
||||
|
@ -1180,7 +1177,7 @@ struct net_buf *net_nbuf_write(struct net_buf *buf, struct net_buf *frag,
|
|||
|
||||
ll_reserve = net_nbuf_ll_reserve(buf);
|
||||
|
||||
frag = adjust_write_offset(buf, frag, offset, &offset);
|
||||
frag = adjust_write_offset(buf, frag, offset, &offset, timeout);
|
||||
if (!frag) {
|
||||
NET_DBG("Failed to adjust offset");
|
||||
goto error;
|
||||
|
@ -1213,7 +1210,7 @@ struct net_buf *net_nbuf_write(struct net_buf *buf, struct net_buf *frag,
|
|||
frag = frag->frags;
|
||||
|
||||
if (!frag) {
|
||||
frag = net_nbuf_get_reserve_data(ll_reserve);
|
||||
frag = net_nbuf_get_reserve_data(ll_reserve, timeout);
|
||||
if (!frag) {
|
||||
goto error;
|
||||
}
|
||||
|
@ -1230,7 +1227,8 @@ error:
|
|||
|
||||
static inline bool insert_data(struct net_buf *buf, struct net_buf *frag,
|
||||
struct net_buf *temp, uint16_t offset,
|
||||
uint16_t len, uint8_t *data)
|
||||
uint16_t len, uint8_t *data,
|
||||
int32_t timeout)
|
||||
{
|
||||
struct net_buf *insert;
|
||||
|
||||
|
@ -1262,7 +1260,8 @@ static inline bool insert_data(struct net_buf *buf, struct net_buf *frag,
|
|||
data += count;
|
||||
offset = 0;
|
||||
|
||||
insert = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf));
|
||||
insert = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf),
|
||||
timeout);
|
||||
if (!insert) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1314,7 +1313,8 @@ static inline struct net_buf *adjust_insert_offset(struct net_buf *buf,
|
|||
}
|
||||
|
||||
bool net_nbuf_insert(struct net_buf *buf, struct net_buf *frag,
|
||||
uint16_t offset, uint16_t len, uint8_t *data)
|
||||
uint16_t offset, uint16_t len, uint8_t *data,
|
||||
int32_t timeout)
|
||||
{
|
||||
struct net_buf *temp = NULL;
|
||||
uint16_t bytes;
|
||||
|
@ -1333,7 +1333,8 @@ bool net_nbuf_insert(struct net_buf *buf, struct net_buf *frag,
|
|||
*/
|
||||
bytes = frag->len - offset;
|
||||
if (bytes) {
|
||||
temp = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf));
|
||||
temp = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf),
|
||||
timeout);
|
||||
if (!temp) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1344,7 +1345,7 @@ bool net_nbuf_insert(struct net_buf *buf, struct net_buf *frag,
|
|||
}
|
||||
|
||||
/* Insert data into current(frag) fragment from "offset". */
|
||||
return insert_data(buf, frag, temp, offset, len, data);
|
||||
return insert_data(buf, frag, temp, offset, len, data, timeout);
|
||||
}
|
||||
|
||||
void net_nbuf_get_info(size_t *tx_size, size_t *rx_size, size_t *data_size,
|
||||
|
|
|
@ -422,7 +422,9 @@ int net_context_put(struct net_context *context)
|
|||
|
||||
#if defined(CONFIG_NET_TCP)
|
||||
if (net_context_get_ip_proto(context) == IPPROTO_TCP) {
|
||||
if (!context->tcp->fin_rcvd) {
|
||||
if ((net_context_get_state(context) == NET_CONTEXT_CONNECTED ||
|
||||
net_context_get_state(context) == NET_CONTEXT_LISTENING)
|
||||
&& !context->tcp->fin_rcvd) {
|
||||
NET_DBG("TCP connection in active close, not "
|
||||
"disposing yet");
|
||||
queue_fin(context);
|
||||
|
@ -446,6 +448,7 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr,
|
|||
struct net_if *iface;
|
||||
struct in6_addr *ptr;
|
||||
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
|
||||
int ret;
|
||||
|
||||
if (addrlen < sizeof(struct sockaddr_in6)) {
|
||||
return -EINVAL;
|
||||
|
@ -479,7 +482,7 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr,
|
|||
}
|
||||
|
||||
if (!iface) {
|
||||
NET_DBG("Cannot bind to %s",
|
||||
NET_ERR("Cannot bind to %s",
|
||||
net_sprint_ipv6_addr(&addr6->sin6_addr));
|
||||
|
||||
return -EADDRNOTAVAIL;
|
||||
|
@ -500,7 +503,18 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr,
|
|||
|
||||
net_sin6_ptr(&context->local)->sin6_family = AF_INET6;
|
||||
net_sin6_ptr(&context->local)->sin6_addr = ptr;
|
||||
net_sin6_ptr(&context->local)->sin6_port = addr6->sin6_port;
|
||||
if (addr6->sin6_port) {
|
||||
ret = check_used_port(AF_INET6, addr6->sin6_port,
|
||||
addr);
|
||||
if (!ret) {
|
||||
net_sin6_ptr(&context->local)->sin6_port =
|
||||
addr6->sin6_port;
|
||||
} else {
|
||||
NET_ERR("Port %d is in use!",
|
||||
ntohs(addr6->sin6_port));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
NET_DBG("Context %p binding to [%s]:%d iface %p", context,
|
||||
net_sprint_ipv6_addr(ptr), ntohs(addr6->sin6_port),
|
||||
|
@ -516,6 +530,7 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr,
|
|||
struct net_if_addr *ifaddr;
|
||||
struct net_if *iface;
|
||||
struct in_addr *ptr;
|
||||
int ret;
|
||||
|
||||
if (addrlen < sizeof(struct sockaddr_in)) {
|
||||
return -EINVAL;
|
||||
|
@ -536,7 +551,7 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr,
|
|||
}
|
||||
|
||||
if (!iface) {
|
||||
NET_DBG("Cannot bind to %s",
|
||||
NET_ERR("Cannot bind to %s",
|
||||
net_sprint_ipv4_addr(&addr4->sin_addr));
|
||||
|
||||
return -EADDRNOTAVAIL;
|
||||
|
@ -557,7 +572,18 @@ int net_context_bind(struct net_context *context, const struct sockaddr *addr,
|
|||
|
||||
net_sin_ptr(&context->local)->sin_family = AF_INET;
|
||||
net_sin_ptr(&context->local)->sin_addr = ptr;
|
||||
net_sin_ptr(&context->local)->sin_port = addr4->sin_port;
|
||||
if (addr4->sin_port) {
|
||||
ret = check_used_port(AF_INET, addr4->sin_port,
|
||||
addr);
|
||||
if (!ret) {
|
||||
net_sin_ptr(&context->local)->sin_port =
|
||||
addr4->sin_port;
|
||||
} else {
|
||||
NET_ERR("Port %d is in use!",
|
||||
ntohs(addr4->sin_port));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
NET_DBG("Context %p binding to %s:%d iface %p", context,
|
||||
net_sprint_ipv4_addr(ptr),
|
||||
|
@ -758,7 +784,7 @@ NET_CONN_CB(tcp_established)
|
|||
NET_ASSERT(context && context->tcp);
|
||||
|
||||
if (net_tcp_get_state(context->tcp) != NET_TCP_ESTABLISHED) {
|
||||
NET_DBG("Context %p in wrong state %d",
|
||||
NET_ERR("Context %p in wrong state %d",
|
||||
context, net_tcp_get_state(context->tcp));
|
||||
return NET_DROP;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue