diff options
author | Anas Nashif <nashif@linux.intel.com> | 2017-02-08 12:03:09 +0000 |
---|---|---|
committer | Anas Nashif <nashif@linux.intel.com> | 2017-02-08 12:03:09 +0000 |
commit | 31f01f8ed648193e664afd985f742cfbd3ea90a2 (patch) | |
tree | 1c5cfc99b8092adebbf3bd252651c97f2bbb33aa | |
parent | a19d4ad0412d9424c074478b166ffa4a330a3ff2 (diff) | |
parent | 7498e22f6e2c65edc009eed0e3c1bc86fbf3f74f (diff) |
Merge "Merge net branch into master"
121 files changed, 2503 insertions, 1030 deletions
diff --git a/boards/arm/frdm_k64f/pinmux.c b/boards/arm/frdm_k64f/pinmux.c index 884fffe58..a1ef0cdd9 100644 --- a/boards/arm/frdm_k64f/pinmux.c +++ b/boards/arm/frdm_k64f/pinmux.c @@ -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) */ diff --git a/boards/x86/quark_se_c1000_devboard/Kconfig.defconfig b/boards/x86/quark_se_c1000_devboard/Kconfig.defconfig index 95d0cbeac..a4467fde8 100644 --- a/boards/x86/quark_se_c1000_devboard/Kconfig.defconfig +++ b/boards/x86/quark_se_c1000_devboard/Kconfig.defconfig @@ -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 diff --git a/boards/x86/quark_se_c1000_devboard/board.c b/boards/x86/quark_se_c1000_devboard/board.c index d837ef7f6..6a0152488 100644 --- a/boards/x86/quark_se_c1000_devboard/board.c +++ b/boards/x86/quark_se_c1000_devboard/board.c @@ -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 + */ diff --git a/boards/x86/quark_se_c1000_devboard/board.h b/boards/x86/quark_se_c1000_devboard/board.h index ca7ed244b..429cc535a 100644 --- a/boards/x86/quark_se_c1000_devboard/board.h +++ b/boards/x86/quark_se_c1000_devboard/board.h @@ -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 */ diff --git a/doc/subsystems/networking/connectivity-example-app.c b/doc/subsystems/networking/connectivity-example-app.c index 207b369ad..09b7c8a5c 100644 --- a/doc/subsystems/networking/connectivity-example-app.c +++ b/doc/subsystems/networking/connectivity-example-app.c @@ -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); diff --git a/doc/subsystems/networking/l2-and-drivers.rst b/doc/subsystems/networking/l2-and-drivers.rst new file mode 100644 index 000000000..805f39aa9 --- /dev/null +++ b/doc/subsystems/networking/l2-and-drivers.rst @@ -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); diff --git a/doc/subsystems/networking/networking.rst b/doc/subsystems/networking/networking.rst index 3de616ca1..35c765566 100644 --- a/doc/subsystems/networking/networking.rst +++ b/doc/subsystems/networking/networking.rst @@ -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 - diff --git a/drivers/console/telnet_console.c b/drivers/console/telnet_console.c index 5fc254631..5e55f3a5c 100644 --- a/drivers/console/telnet_console.c +++ b/drivers/console/telnet_console.c @@ -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); diff --git a/drivers/ethernet/eth_enc28j60.c b/drivers/ethernet/eth_enc28j60.c index c29abb576..c42edd333 100644 --- a/drivers/ethernet/eth_enc28j60.c +++ b/drivers/ethernet/eth_enc28j60.c @@ -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); diff --git a/drivers/ethernet/eth_enc28j60_priv.h b/drivers/ethernet/eth_enc28j60_priv.h index cca9a76be..d521b1aaf 100644 --- a/drivers/ethernet/eth_enc28j60_priv.h +++ b/drivers/ethernet/eth_enc28j60_priv.h @@ -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 diff --git a/drivers/ethernet/eth_mcux.c b/drivers/ethernet/eth_mcux.c index 51ab66858..2b1111b08 100644 --- a/drivers/ethernet/eth_mcux.c +++ b/drivers/ethernet/eth_mcux.c @@ -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; } diff --git a/drivers/ethernet/eth_sam_gmac.c b/drivers/ethernet/eth_sam_gmac.c index 63efa9800..e78fbc568 100644 --- a/drivers/ethernet/eth_sam_gmac.c +++ b/drivers/ethernet/eth_sam_gmac.c @@ -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); diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig index 577906a53..e845cccca 100644 --- a/drivers/ieee802154/Kconfig +++ b/drivers/ieee802154/Kconfig @@ -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 - -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 - - 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 +source "drivers/ieee802154/Kconfig.cc2520" -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. +source "drivers/ieee802154/Kconfig.mcr20a" -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 diff --git a/drivers/ieee802154/Kconfig.cc2520 b/drivers/ieee802154/Kconfig.cc2520 new file mode 100644 index 000000000..472e7c9f1 --- /dev/null +++ b/drivers/ieee802154/Kconfig.cc2520 @@ -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 diff --git a/drivers/ieee802154/Kconfig.mcr20a b/drivers/ieee802154/Kconfig.mcr20a new file mode 100644 index 000000000..8b7f40549 --- /dev/null +++ b/drivers/ieee802154/Kconfig.mcr20a @@ -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 diff --git a/drivers/ieee802154/Makefile b/drivers/ieee802154/Makefile index 801726e4c..60efa9a6f 100644 --- a/drivers/ieee802154/Makefile +++ b/drivers/ieee802154/Makefile @@ -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 diff --git a/drivers/ieee802154/ieee802154_cc2520.c b/drivers/ieee802154/ieee802154_cc2520.c index 253ee4cc5..4b3280240 100644 --- a/drivers/ieee802154/ieee802154_cc2520.c +++ b/drivers/ieee802154/ieee802154_cc2520.c @@ -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); diff --git a/drivers/ieee802154/ieee802154_cc2520.h b/drivers/ieee802154/ieee802154_cc2520.h index 0ff7cd3fb..37be2e174 100644 --- a/drivers/ieee802154/ieee802154_cc2520.h +++ b/drivers/ieee802154/ieee802154_cc2520.h @@ -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; diff --git a/drivers/ieee802154/ieee802154_mcr20a.c b/drivers/ieee802154/ieee802154_mcr20a.c index 2d150415c..756cc89c1 100644 --- a/drivers/ieee802154/ieee802154_mcr20a.c +++ b/drivers/ieee802154/ieee802154_mcr20a.c @@ -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); + + k_sem_give(&spi->spi_sem); - return (spi_write(spi->dev, spi->cmd_buf, len) == 0); + 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 diff --git a/drivers/ieee802154/ieee802154_mcr20a.h b/drivers/ieee802154/ieee802154_mcr20a.h index acc85ec51..e84a5211d 100644 --- a/drivers/ieee802154/ieee802154_mcr20a.h +++ b/drivers/ieee802154/ieee802154_mcr20a.h @@ -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; }; diff --git a/drivers/ieee802154/ieee802154_uart_pipe.c b/drivers/ieee802154/ieee802154_uart_pipe.c index 6736f4fd0..5daa2e6d0 100644 --- a/drivers/ieee802154/ieee802154_uart_pipe.c +++ b/drivers/ieee802154/ieee802154_uart_pipe.c @@ -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, diff --git a/drivers/slip/slip.c b/drivers/slip/slip.c index 2d44d0b5b..f64783ff2 100644 --- a/drivers/slip/slip.c +++ b/drivers/slip/slip.c @@ -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); diff --git a/ext/hal/nxp/mcux/Makefile b/ext/hal/nxp/mcux/Makefile index 4fb490c94..5fed754bd 100644 --- a/ext/hal/nxp/mcux/Makefile +++ b/ext/hal/nxp/mcux/Makefile @@ -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 diff --git a/include/net/nbuf.h b/include/net/nbuf.h index 2f0939087..69c2b99c8 100644 --- a/include/net/nbuf.h +++ b/include/net/nbuf.h @@ -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. @@ -543,24 +589,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 * the fragment list instead of one fragment. @@ -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); } /** diff --git a/samples/bluetooth/ipsp/src/main.c b/samples/bluetooth/ipsp/src/main.c index 378dca0c7..e29b95cce 100644 --- a/samples/bluetooth/ipsp/src/main.c +++ b/samples/bluetooth/ipsp/src/main.c @@ -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); diff --git a/samples/net/coaps_client/src/udp.c b/samples/net/coaps_client/src/udp.c index 1da593e84..b2c8e3799 100644 --- a/samples/net/coaps_client/src/udp.c +++ b/samples/net/coaps_client/src/udp.c @@ -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; } diff --git a/samples/net/coaps_server/src/udp.c b/samples/net/coaps_server/src/udp.c index f2a7081db..76cd1500e 100644 --- a/samples/net/coaps_server/src/udp.c +++ b/samples/net/coaps_server/src/udp.c @@ -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; diff --git a/samples/net/echo_client/prj_arduino_101_cc2520.conf b/samples/net/echo_client/prj_arduino_101_cc2520.conf index 70cfd90d5..4a5a3e072 100644 --- a/samples/net/echo_client/prj_arduino_101_cc2520.conf +++ b/samples/net/echo_client/prj_arduino_101_cc2520.conf @@ -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
\ No newline at end of file +CONFIG_IEEE802154_CC2520_SPI_DRV_NAME="SPI_1" +CONFIG_IEEE802154_CC2520_SPI_FREQ=4 +CONFIG_IEEE802154_CC2520_SPI_SLAVE=1
\ No newline at end of file diff --git a/samples/net/echo_client/prj_cc2520.conf b/samples/net/echo_client/prj_cc2520.conf index 71edb1c9c..86ae60956 100644 --- a/samples/net/echo_client/prj_cc2520.conf +++ b/samples/net/echo_client/prj_cc2520.conf @@ -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 diff --git a/samples/net/echo_client/prj_frdm_k64f_cc2520.conf b/samples/net/echo_client/prj_frdm_k64f_cc2520.conf index 2f34f5659..e47274194 100644 --- a/samples/net/echo_client/prj_frdm_k64f_cc2520.conf +++ b/samples/net/echo_client/prj_frdm_k64f_cc2520.conf @@ -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" diff --git a/samples/net/echo_client/prj_frdm_k64f_mcr20a.conf b/samples/net/echo_client/prj_frdm_k64f_mcr20a.conf index c5f2e455f..ac8f07499 100644 --- a/samples/net/echo_client/prj_frdm_k64f_mcr20a.conf +++ b/samples/net/echo_client/prj_frdm_k64f_mcr20a.conf @@ -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 diff --git a/samples/net/echo_client/prj_qemu_802154.conf b/samples/net/echo_client/prj_qemu_802154.conf index dd67ac581..d4ea56f5d 100644 --- a/samples/net/echo_client/prj_qemu_802154.conf +++ b/samples/net/echo_client/prj_qemu_802154.conf @@ -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 diff --git a/samples/net/echo_client/src/Makefile b/samples/net/echo_client/src/Makefile index 8802055a5..a05869c93 100644 --- a/samples/net/echo_client/src/Makefile +++ b/samples/net/echo_client/src/Makefile @@ -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/ diff --git a/samples/net/echo_client/src/echo-client.c b/samples/net/echo_client/src/echo-client.c index 67cd58514..06f4ceafc 100644 --- a/samples/net/echo_client/src/echo-client.c +++ b/samples/net/echo_client/src/echo-client.c @@ -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; diff --git a/samples/net/echo_server/prj_arduino_101_cc2520.conf b/samples/net/echo_server/prj_arduino_101_cc2520.conf index 70cfd90d5..4a5a3e072 100644 --- a/samples/net/echo_server/prj_arduino_101_cc2520.conf +++ b/samples/net/echo_server/prj_arduino_101_cc2520.conf @@ -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
\ No newline at end of file +CONFIG_IEEE802154_CC2520_SPI_DRV_NAME="SPI_1" +CONFIG_IEEE802154_CC2520_SPI_FREQ=4 +CONFIG_IEEE802154_CC2520_SPI_SLAVE=1
\ No newline at end of file diff --git a/samples/net/echo_server/prj_cc2520.conf b/samples/net/echo_server/prj_cc2520.conf index aa4e9bed8..7159d4a8d 100644 --- a/samples/net/echo_server/prj_cc2520.conf +++ b/samples/net/echo_server/prj_cc2520.conf @@ -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 diff --git a/samples/net/echo_server/prj_frdm_k64f_cc2520.conf b/samples/net/echo_server/prj_frdm_k64f_cc2520.conf index a913a06e0..7fbf67414 100644 --- a/samples/net/echo_server/prj_frdm_k64f_cc2520.conf +++ b/samples/net/echo_server/prj_frdm_k64f_cc2520.conf @@ -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" diff --git a/samples/net/echo_server/prj_frdm_k64f_mcr20a.conf b/samples/net/echo_server/prj_frdm_k64f_mcr20a.conf index e8f8d2ff0..724420b43 100644 --- a/samples/net/echo_server/prj_frdm_k64f_mcr20a.conf +++ b/samples/net/echo_server/prj_frdm_k64f_mcr20a.conf @@ -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 diff --git a/samples/net/echo_server/prj_qemu_802154.conf b/samples/net/echo_server/prj_qemu_802154.conf index b42b67ca0..0e2157e02 100644 --- a/samples/net/echo_server/prj_qemu_802154.conf +++ b/samples/net/echo_server/prj_qemu_802154.conf @@ -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 diff --git a/samples/net/echo_server/src/Makefile b/samples/net/echo_server/src/Makefile index c4dd7f726..3f8b03393 100644 --- a/samples/net/echo_server/src/Makefile +++ b/samples/net/echo_server/src/Makefile @@ -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/ diff --git a/samples/net/echo_server/src/echo-server.c b/samples/net/echo_server/src/echo-server.c index 4d6b2c3b2..fb3deecbd 100644 --- a/samples/net/echo_server/src/echo-server.c +++ b/samples/net/echo_server/src/echo-server.c @@ -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'); diff --git a/samples/net/http_client/Makefile b/samples/net/http_client/Makefile new file mode 100644 index 000000000..f9767a77f --- /dev/null +++ b/samples/net/http_client/Makefile @@ -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 diff --git a/samples/net/http_client/README.rst b/samples/net/http_client/README.rst new file mode 100644 index 000000000..e3df1da85 --- /dev/null +++ b/samples/net/http_client/README.rst @@ -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 diff --git a/samples/net/http_client/prj_frdm_k64f.conf b/samples/net/http_client/prj_frdm_k64f.conf new file mode 100644 index 000000000..c2f4410b1 --- /dev/null +++ b/samples/net/http_client/prj_frdm_k64f.conf @@ -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 diff --git a/samples/net/http_client/src/Makefile b/samples/net/http_client/src/Makefile new file mode 100644 index 000000000..32a9e074c --- /dev/null +++ b/samples/net/http_client/src/Makefile @@ -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 diff --git a/samples/net/http_client/src/config.h b/samples/net/http_client/src/config.h new file mode 100644 index 000000000..40523329b --- /dev/null +++ b/samples/net/http_client/src/config.h @@ -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 diff --git a/samples/net/http_client/src/http_client.c b/samples/net/http_client/src/http_client.c new file mode 100644 index 000000000..5ae15713e --- /dev/null +++ b/samples/net/http_client/src/http_client.c @@ -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); +} diff --git a/samples/net/http_client/src/http_client.h b/samples/net/http_client/src/http_client.h new file mode 100644 index 000000000..9096dfda0 --- /dev/null +++ b/samples/net/http_client/src/http_client.h @@ -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 diff --git a/samples/net/http_client/src/http_client_cb.c b/samples/net/http_client/src/http_client_cb.c new file mode 100644 index 000000000..21368fdb8 --- /dev/null +++ b/samples/net/http_client/src/http_client_cb.c @@ -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; +} diff --git a/samples/net/http_client/src/http_client_cb.h b/samples/net/http_client/src/http_client_cb.h new file mode 100644 index 000000000..457ee15e8 --- /dev/null +++ b/samples/net/http_client/src/http_client_cb.h @@ -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 diff --git a/samples/net/http_client/src/http_client_rcv.c b/samples/net/http_client/src/http_client_rcv.c new file mode 100644 index 000000000..5c6a220dc --- /dev/null +++ b/samples/net/http_client/src/http_client_rcv.c @@ -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 diff --git a/samples/net/http_client/src/http_client_rcv.h b/samples/net/http_client/src/http_client_rcv.h new file mode 100644 index 000000000..d75d9708e --- /dev/null +++ b/samples/net/http_client/src/http_client_rcv.h @@ -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 diff --git a/samples/net/http_client/src/http_client_types.h b/samples/net/http_client/src/http_client_types.h new file mode 100644 index 000000000..16032607e --- /dev/null +++ b/samples/net/http_client/src/http_client_types.h @@ -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 diff --git a/samples/net/http_client/src/main.c b/samples/net/http_client/src/main.c new file mode 100644 index 000000000..520728421 --- /dev/null +++ b/samples/net/http_client/src/main.c @@ -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); +} diff --git a/samples/net/http_client/src/tcp_client.c b/samples/net/http_client/src/tcp_client.c new file mode 100644 index 000000000..43403f46d --- /dev/null +++ b/samples/net/http_client/src/tcp_client.c @@ -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; +} diff --git a/samples/net/http_client/src/tcp_client.h b/samples/net/http_client/src/tcp_client.h new file mode 100644 index 000000000..581321c35 --- /dev/null +++ b/samples/net/http_client/src/tcp_client.h @@ -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 diff --git a/samples/net/http_client/testcase.ini b/samples/net/http_client/testcase.ini new file mode 100644 index 000000000..1c14f3d70 --- /dev/null +++ b/samples/net/http_client/testcase.ini @@ -0,0 +1,4 @@ +[test] +tags = net http +build_only = true +platform_whitelist = frdm_k64f diff --git a/samples/net/http_server/src/http_write_utils.c b/samples/net/http_server/src/http_write_utils.c index a96853040..1167cfdcb 100644 --- a/samples/net/http_server/src/http_write_utils.c +++ b/samples/net/http_server/src/http_write_utils.c @@ -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) { diff --git a/samples/net/ieee802154/hw/prj.conf b/samples/net/ieee802154/hw/prj.conf index 5af2d29b4..311ed0f69 100644 --- a/samples/net/ieee802154/hw/prj.conf +++ b/samples/net/ieee802154/hw/prj.conf @@ -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 diff --git a/samples/net/ieee802154/hw/prj_mcr20a.conf b/samples/net/ieee802154/hw/prj_mcr20a.conf index 271efe4d1..0b47ba553 100644 --- a/samples/net/ieee802154/hw/prj_mcr20a.conf +++ b/samples/net/ieee802154/hw/prj_mcr20a.conf @@ -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 diff --git a/samples/net/ieee802154/hw/src/ieee802154_test.c b/samples/net/ieee802154/hw/src/ieee802154_test.c index 6bfe55fc9..4dc1dbcef 100644 --- a/samples/net/ieee802154/hw/src/ieee802154_test.c +++ b/samples/net/ieee802154/hw/src/ieee802154_test.c @@ -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 diff --git a/samples/net/ieee802154/qemu/prj.conf b/samples/net/ieee802154/qemu/prj.conf index 6112e5164..926023ee3 100644 --- a/samples/net/ieee802154/qemu/prj.conf +++ b/samples/net/ieee802154/qemu/prj.conf @@ -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 diff --git a/samples/net/ieee802154/qemu/src/ieee802154_qemu_test.c b/samples/net/ieee802154/qemu/src/ieee802154_qemu_test.c index ed406f846..50237842b 100644 --- a/samples/net/ieee802154/qemu/src/ieee802154_qemu_test.c +++ b/samples/net/ieee802154/qemu/src/ieee802154_qemu_test.c @@ -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; diff --git a/samples/net/irc_bot/src/irc-bot.c b/samples/net/irc_bot/src/irc-bot.c index d3c668eb9..4c7246931 100644 --- a/samples/net/irc_bot/src/irc-bot.c +++ b/samples/net/irc_bot/src/irc-bot.c @@ -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; diff --git a/samples/net/irc_bot/testcase.ini b/samples/net/irc_bot/testcase.ini new file mode 100644 index 000000000..e0efde996 --- /dev/null +++ b/samples/net/irc_bot/testcase.ini @@ -0,0 +1,4 @@ +[test] +tags = net irc +build_only = true +platform_whitelist = qemu_x86 frdm_k64f diff --git a/samples/net/leds_demo/prj_802154.conf b/samples/net/leds_demo/prj_802154.conf index c459d3993..1efd33265 100644 --- a/samples/net/leds_demo/prj_802154.conf +++ b/samples/net/leds_demo/prj_802154.conf @@ -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 diff --git a/samples/net/leds_demo/src/leds-demo.c b/samples/net/leds_demo/src/leds-demo.c index 0fe8044d8..5f081bbea 100644 --- a/samples/net/leds_demo/src/leds-demo.c +++ b/samples/net/leds_demo/src/leds-demo.c @@ -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; } diff --git a/samples/net/mbedtls_dtlsclient/src/udp.c b/samples/net/mbedtls_dtlsclient/src/udp.c index 06f7fb9da..bf6f3142f 100644 --- a/samples/net/mbedtls_dtlsclient/src/udp.c +++ b/samples/net/mbedtls_dtlsclient/src/udp.c @@ -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; diff --git a/samples/net/mbedtls_dtlsserver/src/udp.c b/samples/net/mbedtls_dtlsserver/src/udp.c index 20b68a2d5..7ed500d8c 100644 --- a/samples/net/mbedtls_dtlsserver/src/udp.c +++ b/samples/net/mbedtls_dtlsserver/src/udp.c @@ -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; diff --git a/samples/net/mbedtls_sslclient/Makefile b/samples/net/mbedtls_sslclient/Makefile index 6f417152f..80dcd69d7 100644 --- a/samples/net/mbedtls_sslclient/Makefile +++ b/samples/net/mbedtls_sslclient/Makefile @@ -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 diff --git a/samples/net/mbedtls_sslclient/prj_arduino_101.conf b/samples/net/mbedtls_sslclient/prj_arduino_101.conf new file mode 100644 index 000000000..8ed0f9db9 --- /dev/null +++ b/samples/net/mbedtls_sslclient/prj_arduino_101.conf @@ -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" diff --git a/samples/net/mbedtls_sslclient/src/tcp.c b/samples/net/mbedtls_sslclient/src/tcp.c index 675cef09b..5f7cca16e 100644 --- a/samples/net/mbedtls_sslclient/src/tcp.c +++ b/samples/net/mbedtls_sslclient/src/tcp.c @@ -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; diff --git a/samples/net/wpan_serial/prj.conf b/samples/net/wpan_serial/prj.conf index 4343b0c77..b0c200cb2 100644 --- a/samples/net/wpan_serial/prj.conf +++ b/samples/net/wpan_serial/prj.conf @@ -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 diff --git a/samples/net/wpan_serial/src/Makefile b/samples/net/wpan_serial/src/Makefile index 7ed962485..c560055f2 100644 --- a/samples/net/wpan_serial/src/Makefile +++ b/samples/net/wpan_serial/src/Makefile @@ -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 diff --git a/samples/net/wpan_serial/src/main.c b/samples/net/wpan_serial/src/main.c index a92e3b973..da56daf42 100644 --- a/samples/net/wpan_serial/src/main.c +++ b/samples/net/wpan_serial/src/main.c @@ -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; diff --git a/samples/net/wpanusb/prj.conf b/samples/net/wpanusb/prj.conf index 0fc0536a7..4fe6b8243 100644 --- a/samples/net/wpanusb/prj.conf +++ b/samples/net/wpanusb/prj.conf @@ -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 diff --git a/samples/net/wpanusb/src/Makefile b/samples/net/wpanusb/src/Makefile index 16a6a702f..23af5ad92 100644 --- a/samples/net/wpanusb/src/Makefile +++ b/samples/net/wpanusb/src/Makefile @@ -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 diff --git a/samples/net/wpanusb/src/wpanusb.c b/samples/net/wpanusb/src/wpanusb.c index 528d93f2f..ee9bc0992 100644 --- a/samples/net/wpanusb/src/wpanusb.c +++ b/samples/net/wpanusb/src/wpanusb.c @@ -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; diff --git a/samples/net/zoap_client/src/zoap-client.c b/samples/net/zoap_client/src/zoap-client.c index 984afa451..6e12077a2 100644 --- a/samples/net/zoap_client/src/zoap-client.c +++ b/samples/net/zoap_client/src/zoap-client.c @@ -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; diff --git a/samples/net/zoap_server/prj_cc2520.conf b/samples/net/zoap_server/prj_cc2520.conf index ea85c8242..934a1a598 100644 --- a/samples/net/zoap_server/prj_cc2520.conf +++ b/samples/net/zoap_server/prj_cc2520.conf @@ -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" diff --git a/samples/net/zoap_server/src/zoap-server.c b/samples/net/zoap_server/src/zoap-server.c index 1c7d1a783..51862fe12 100644 --- a/samples/net/zoap_server/src/zoap-server.c +++ b/samples/net/zoap_server/src/zoap-server.c @@ -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; } diff --git a/samples/net/zperf/prj_quark_se_c1000_devboard.conf b/samples/net/zperf/prj_quark_se_c1000_devboard.conf index cff8c26ff..a2b532137 100644 --- a/samples/net/zperf/prj_quark_se_c1000_devboard.conf +++ b/samples/net/zperf/prj_quark_se_c1000_devboard.conf @@ -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 diff --git a/samples/net/zperf/src/zperf_tcp_uploader.c b/samples/net/zperf/src/zperf_tcp_uploader.c index 7d1735203..c40b96dc8 100644 --- a/samples/net/zperf/src/zperf_tcp_uploader.c +++ b/samples/net/zperf/src/zperf_tcp_uploader.c @@ -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"); diff --git a/samples/net/zperf/src/zperf_udp_receiver.c b/samples/net/zperf/src/zperf_udp_receiver.c index 68ff53e90..cf3681e89 100644 --- a/samples/net/zperf/src/zperf_udp_receiver.c +++ b/samples/net/zperf/src/zperf_udp_receiver.c @@ -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); diff --git a/samples/net/zperf/src/zperf_udp_uploader.c b/samples/net/zperf/src/zperf_udp_uploader.c index cdff49d60..794dfb373 100644 --- a/samples/net/zperf/src/zperf_udp_uploader.c +++ b/samples/net/zperf/src/zperf_udp_uploader.c @@ -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 */ diff --git a/subsys/net/TODO b/subsys/net/TODO index 6b23c90a4..22519f47f 100644 --- a/subsys/net/TODO +++ b/subsys/net/TODO @@ -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. diff --git a/subsys/net/ip/6lo.c b/subsys/net/ip/6lo.c index 6dbf4b9f3..4a307a286 100644 --- a/subsys/net/ip/6lo.c +++ b/subsys/net/ip/6lo.c @@ -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); diff --git a/subsys/net/ip/connection.c b/subsys/net/ip/connection.c index 64653fd58..8787fae89 100644 --- a/subsys/net/ip/connection.c +++ b/subsys/net/ip/connection.c @@ -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; } } diff --git a/subsys/net/ip/dhcpv4.c b/subsys/net/ip/dhcpv4.c index 64052551c..d8efbf4cc 100644 --- a/subsys/net/ip/dhcpv4.c +++ b/subsys/net/ip/dhcpv4.c @@ -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); diff --git a/subsys/net/ip/icmpv4.c b/subsys/net/ip/icmpv4.c index 09a283821..1f58cf2c9 100644 --- a/subsys/net/ip/icmpv4.c +++ b/subsys/net/ip/icmpv4.c @@ -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; } diff --git a/subsys/net/ip/icmpv6.c b/subsys/net/ip/icmpv6.c index 58b8874b9..a4a849990 100644 --- a/subsys/net/ip/icmpv6.c +++ b/subsys/net/ip/icmpv6.c @@ -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); diff --git a/subsys/net/ip/ipv4.c b/subsys/net/ip/ipv4.c index 07710cdc3..5235b9739 100644 --- a/subsys/net/ip/ipv4.c +++ b/subsys/net/ip/ipv4.c @@ -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); diff --git a/subsys/net/ip/ipv6.c b/subsys/net/ip/ipv6.c index 8fc88d36e..3e12f7bae 100644 --- a/subsys/net/ip/ipv6.c +++ b/subsys/net/ip/ipv6.c @@ -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); diff --git a/subsys/net/ip/l2/arp.c b/subsys/net/ip/l2/arp.c index e5ab786c6..1ef951e39 100644 --- a/subsys/net/ip/l2/arp.c +++ b/subsys/net/ip/l2/arp.c @@ -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; } diff --git a/subsys/net/ip/l2/bluetooth.c b/subsys/net/ip/l2/bluetooth.c index b3b59737b..de55c618a 100644 --- a/subsys/net/ip/l2/bluetooth.c +++ b/subsys/net/ip/l2/bluetooth.c @@ -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 = { diff --git a/subsys/net/ip/l2/ieee802154/ieee802154.c b/subsys/net/ip/l2/ieee802154/ieee802154.c index 1c6a19f5c..c1e9e2d83 100644 --- a/subsys/net/ip/l2/ieee802154/ieee802154.c +++ b/subsys/net/ip/l2/ieee802154/ieee802154.c @@ -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)); diff --git a/subsys/net/ip/l2/ieee802154/ieee802154_fragment.c b/subsys/net/ip/l2/ieee802154/ieee802154_fragment.c index 5dc700258..05417dfe8 100644 --- a/subsys/net/ip/l2/ieee802154/ieee802154_fragment.c +++ b/subsys/net/ip/l2/ieee802154/ieee802154_fragment.c @@ -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); + if (!room) { + /* Prepare new fragment based on offset */ + frag = prepare_new_fragment(buf, offset); + if (!frag) { + return false; + } - /* Calculate max payload in multiples of 8 bytes */ - max = calc_max_payload(buf, frag, offset); + /* Set fragmentation header in the beginning */ + set_up_frag_hdr(frag, size, offset); - /* Move data from next fragment to current fragment */ - move = move_frag_data(frag, next, max, moved, offset, - hdr_diff); + /* Calculate max payload in multiples of 8 bytes */ + max = calc_max_payload(buf, frag, offset); + + /* Calculate how much data is processed */ + processed += max; - /* Compact the next fragment, returns how much data moved */ - moved = compact_frag(next, move); + offset = processed >> 3; + } - /* Calculate how much data is processed */ - processed += max; + /* Move data from next fragment to current fragment */ + move = move_frag_data(frag, next, max, first, hdr_diff, &room); + first = false; - offset = processed >> 3; + /* Compact the next fragment */ + compact_frag(next, move); - /** 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 (!next->len) { + next = net_buf_frag_del(NULL, next); + if (!next) { + break; } - - break; } - - /* Repeat the steps */ - frag = next; - next = next->frags; } 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; } diff --git a/subsys/net/ip/l2/ieee802154/ieee802154_frame.c b/subsys/net/ip/l2/ieee802154/ieee802154_frame.c index 5ac42f2a1..a32e39913 100644 --- a/subsys/net/ip/l2/ieee802154/ieee802154_frame.c +++ b/subsys/net/ip/l2/ieee802154/ieee802154_frame.c @@ -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; } diff --git a/subsys/net/ip/nbuf.c b/subsys/net/ip/nbuf.c index db7d33724..49f0ba92d 100644 --- a/subsys/net/ip/nbuf.c +++ b/subsys/net/ip/nbuf.c @@ -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, diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index f28a35394..cb9c9fb46 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -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; } diff --git a/subsys/net/ip/net_private.h b/subsys/net/ip/net_private.h index fad706c27..704ca820f 100644 --- a/subsys/net/ip/net_private.h +++ b/subsys/net/ip/net_private.h @@ -144,6 +144,33 @@ static inline void net_hexdump_frags(const char *str, struct net_buf *buf) } } +/* Print fragment chain */ +static inline void net_print_frags(const char *str, struct net_buf *buf) +{ + struct net_buf *frag = buf->frags; + + if (str) { + printk("%s", str); + } + + printk("%p[%d]", buf, buf->ref); + + if (frag) { + printk("->"); + } + + while (frag) { + printk("%p[%d/%d]", frag, frag->ref, frag->len); + + frag = frag->frags; + if (frag) { + printk("->"); + } + } + + printk("\n"); +} + #else /* NET_LOG_ENABLED */ static inline char *net_sprint_ll_addr(const uint8_t *ll, uint8_t ll_len) @@ -178,4 +205,6 @@ static inline char *net_sprint_ip_addr(const struct net_addr *addr) #define net_hexdump(str, packet, length) #define net_hexdump_frags(...) +#define net_print_frags(...) + #endif /* NET_LOG_ENABLED */ diff --git a/subsys/net/ip/rpl.c b/subsys/net/ip/rpl.c index dcf2ad1f0..a7c7c4dc1 100644 --- a/subsys/net/ip/rpl.c +++ b/subsys/net/ip/rpl.c @@ -445,7 +445,7 @@ int net_rpl_dio_send(struct net_if *iface, uint16_t value; int ret; - buf = net_nbuf_get_reserve_tx(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); if (!buf) { return -ENOMEM; } @@ -482,7 +482,8 @@ int net_rpl_dio_send(struct net_if *iface, /* Flags and reserved are set to 0 */ net_nbuf_append_be16(buf, 0); - net_nbuf_append(buf, sizeof(struct in6_addr), dag->dag_id.s6_addr); + net_nbuf_append(buf, sizeof(struct in6_addr), dag->dag_id.s6_addr, + K_FOREVER); if (instance->mc.type != NET_RPL_MC_NONE) { net_rpl_of_update_mc(instance); @@ -542,7 +543,8 @@ int net_rpl_dio_send(struct net_if *iface, net_nbuf_append_be32(buf, 0); /* reserved */ net_nbuf_append(buf, sizeof(struct in6_addr), - dag->prefix_info.prefix.s6_addr); + dag->prefix_info.prefix.s6_addr, + K_FOREVER); NET_DBG("Sending prefix info in DIO for %s", net_sprint_ipv6_addr(&dag->prefix_info.prefix)); @@ -719,7 +721,7 @@ int net_rpl_dis_send(struct in6_addr *dst, struct net_if *iface) return 0; } - buf = net_nbuf_get_reserve_tx(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); if (!buf) { return -ENOMEM; } @@ -2964,7 +2966,7 @@ int net_rpl_dao_send(struct net_if *iface, return -EINVAL; } - buf = net_nbuf_get_reserve_tx(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); if (!buf) { return -ENOMEM; } @@ -2993,7 +2995,8 @@ int net_rpl_dao_send(struct net_if *iface, net_nbuf_append_u8(buf, rpl_dao_sequence); #if defined(CONFIG_NET_RPL_DAO_SPECIFY_DAG) - net_nbuf_append(buf, sizeof(dag->dag_id), dag->dag_id.s6_addr); + net_nbuf_append(buf, sizeof(dag->dag_id), dag->dag_id.s6_addr, + K_FOREVER); #endif prefixlen = sizeof(*prefix) * CHAR_BIT; @@ -3003,7 +3006,7 @@ int net_rpl_dao_send(struct net_if *iface, net_nbuf_append_u8(buf, 2 + prefix_bytes); net_nbuf_append_u8(buf, 0); /* reserved */ net_nbuf_append_u8(buf, prefixlen); - net_nbuf_append(buf, prefix_bytes, prefix->s6_addr); + net_nbuf_append(buf, prefix_bytes, prefix->s6_addr, K_FOREVER); net_nbuf_append_u8(buf, NET_RPL_OPTION_TRANSIT); net_nbuf_append_u8(buf, 4); /* length */ @@ -3051,7 +3054,7 @@ static inline int dao_forward(struct net_if *iface, struct net_buf *buf; int ret; - buf = net_nbuf_get_reserve_tx(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); if (!buf) { return -ENOMEM; } @@ -3089,7 +3092,7 @@ static int dao_ack_send(struct net_buf *orig, NET_DBG("Sending a DAO ACK with sequence number %d to %s", sequence, net_sprint_ipv6_addr(dst)); - buf = net_nbuf_get_reserve_tx(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); if (!buf) { return -ENOMEM; } diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 2909e89f5..b0cb0b7be 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -245,7 +245,7 @@ static struct net_buf *prepare_segment(struct net_tcp *tcp, tail = buf->frags; buf->frags = NULL; } else { - buf = net_nbuf_get_tx(context); + buf = net_nbuf_get_tx(context, K_FOREVER); } #if defined(CONFIG_NET_IPV4) @@ -274,7 +274,7 @@ static struct net_buf *prepare_segment(struct net_tcp *tcp, goto proto_err; } - header = net_nbuf_get_data(context); + header = net_nbuf_get_data(context, K_FOREVER); net_buf_frag_add(buf, header); tcphdr = (struct net_tcp_hdr *)net_buf_add(header, NET_TCPH_LEN); @@ -307,7 +307,7 @@ static struct net_buf *prepare_segment(struct net_tcp *tcp, return NULL; } - buf = net_nbuf_compact(buf); + net_nbuf_compact(buf); net_tcp_trace("", buf); diff --git a/subsys/net/lib/dns/dns_client.c b/subsys/net/lib/dns/dns_client.c index 85430297b..1254e8a59 100644 --- a/subsys/net/lib/dns/dns_client.c +++ b/subsys/net/lib/dns/dns_client.c @@ -162,13 +162,13 @@ int dns_write(struct dns_context *ctx, struct net_buf *dns_data, goto exit_write; } - tx = net_nbuf_get_tx(ctx->net_ctx); + tx = net_nbuf_get_tx(ctx->net_ctx, K_FOREVER); if (tx == NULL) { rc = -ENOMEM; goto exit_write; } - rc = net_nbuf_append(tx, dns_data->len, dns_data->data); + rc = net_nbuf_append(tx, dns_data->len, dns_data->data, K_FOREVER); if (rc != true) { rc = -ENOMEM; goto exit_write; diff --git a/subsys/net/lib/mqtt/mqtt.c b/subsys/net/lib/mqtt/mqtt.c index 87bf5cace..9b57c8cf4 100644 --- a/subsys/net/lib/mqtt/mqtt.c +++ b/subsys/net/lib/mqtt/mqtt.c @@ -43,7 +43,7 @@ int mqtt_tx_connect(struct mqtt_ctx *ctx, struct mqtt_connect_msg *msg) goto exit_connect; } - tx = net_nbuf_get_tx(ctx->net_ctx); + tx = net_nbuf_get_tx(ctx->net_ctx, ctx->net_timeout); if (tx == NULL) { rc = -ENOMEM; goto exit_connect; @@ -81,13 +81,13 @@ int mqtt_tx_disconnect(struct mqtt_ctx *ctx) goto exit_disconnect; } - tx = net_nbuf_get_tx(ctx->net_ctx); + tx = net_nbuf_get_tx(ctx->net_ctx, ctx->net_timeout); if (tx == NULL) { rc = -ENOMEM; goto exit_disconnect; } - rc = net_nbuf_append(tx, len, msg); + rc = net_nbuf_append(tx, len, msg, ctx->net_timeout); if (rc != true) { rc = -ENOMEM; goto exit_disconnect; @@ -154,13 +154,13 @@ int mqtt_tx_pub_msgs(struct mqtt_ctx *ctx, uint16_t id, return -EINVAL; } - tx = net_nbuf_get_tx(ctx->net_ctx); + tx = net_nbuf_get_tx(ctx->net_ctx, ctx->net_timeout); if (tx == NULL) { rc = -ENOMEM; goto exit_send; } - rc = net_nbuf_append(tx, len, msg); + rc = net_nbuf_append(tx, len, msg, ctx->net_timeout); if (rc != true) { rc = -ENOMEM; goto exit_send; @@ -218,7 +218,7 @@ int mqtt_tx_publish(struct mqtt_ctx *ctx, struct mqtt_publish_msg *msg) goto exit_publish; } - tx = net_nbuf_get_tx(ctx->net_ctx); + tx = net_nbuf_get_tx(ctx->net_ctx, ctx->net_timeout); if (tx == NULL) { rc = -ENOMEM; goto exit_publish; @@ -255,13 +255,13 @@ int mqtt_tx_pingreq(struct mqtt_ctx *ctx) goto exit_pingreq; } - tx = net_nbuf_get_tx(ctx->net_ctx); + tx = net_nbuf_get_tx(ctx->net_ctx, ctx->net_timeout); if (tx == NULL) { rc = -ENOMEM; goto exit_pingreq; } - rc = net_nbuf_append(tx, len, msg); + rc = net_nbuf_append(tx, len, msg, ctx->net_timeout); if (rc != true) { rc = -ENOMEM; goto exit_pingreq; @@ -302,7 +302,7 @@ int mqtt_tx_subscribe(struct mqtt_ctx *ctx, uint16_t pkt_id, uint8_t items, goto exit_subs; } - tx = net_nbuf_get_tx(ctx->net_ctx); + tx = net_nbuf_get_tx(ctx->net_ctx, ctx->net_timeout); if (tx == NULL) { rc = -ENOMEM; goto exit_subs; @@ -346,7 +346,7 @@ int mqtt_tx_unsubscribe(struct mqtt_ctx *ctx, uint16_t pkt_id, uint8_t items, goto exit_unsub; } - tx = net_nbuf_get_tx(ctx->net_ctx); + tx = net_nbuf_get_tx(ctx->net_ctx, ctx->net_timeout); if (tx == NULL) { rc = -ENOMEM; goto exit_unsub; diff --git a/subsys/net/lib/zoap/zoap_link_format.c b/subsys/net/lib/zoap/zoap_link_format.c index db896111f..c98874be8 100644 --- a/subsys/net/lib/zoap/zoap_link_format.c +++ b/subsys/net/lib/zoap/zoap_link_format.c @@ -246,12 +246,12 @@ int _zoap_well_known_core_get(struct zoap_resource *resource, context = net_nbuf_context(request->buf); - 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) { net_nbuf_unref(buf); return -ENOMEM; diff --git a/tests/net/6lo/src/main.c b/tests/net/6lo/src/main.c index b666326a1..0f59a8745 100644 --- a/tests/net/6lo/src/main.c +++ b/tests/net/6lo/src/main.c @@ -308,7 +308,7 @@ static struct net_buf *create_buf(struct net_6lo_data *data) uint16_t len; int remaining; - buf = net_nbuf_get_reserve_tx(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); if (!buf) { return NULL; } @@ -322,7 +322,7 @@ static struct net_buf *create_buf(struct net_6lo_data *data) net_nbuf_ll_dst(buf)->addr = dst_mac; net_nbuf_ll_dst(buf)->len = 8; - frag = net_nbuf_get_reserve_data(0); + frag = net_nbuf_get_reserve_data(0, K_FOREVER); if (!frag) { net_nbuf_unref(buf); return NULL; @@ -384,7 +384,7 @@ static struct net_buf *create_buf(struct net_6lo_data *data) net_buf_frag_add(buf, frag); if (remaining > 0) { - frag = net_nbuf_get_reserve_data(0); + frag = net_nbuf_get_reserve_data(0, K_FOREVER); } } diff --git a/tests/net/arp/src/main.c b/tests/net/arp/src/main.c index 8c43d8a7a..084c7c842 100644 --- a/tests/net/arp/src/main.c +++ b/tests/net/arp/src/main.c @@ -169,12 +169,12 @@ static inline struct net_buf *prepare_arp_reply(struct net_if *iface, struct net_arp_hdr *hdr; struct net_eth_hdr *eth; - 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; } @@ -223,12 +223,13 @@ static inline struct net_buf *prepare_arp_request(struct net_if *iface, struct net_arp_hdr *hdr, *req_hdr; struct net_eth_hdr *eth, *eth_req; - buf = net_nbuf_get_reserve_rx(0); + buf = net_nbuf_get_reserve_rx(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; } @@ -333,13 +334,14 @@ static bool run_tests(void) ifaddr->addr_state = NET_ADDR_PREFERRED; /* Application data for testing */ - buf = net_nbuf_get_reserve_tx(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); if (!buf) { printk("Out of mem TX\n"); return false; } - 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) { printk("Out of mem DATA\n"); return false; @@ -559,14 +561,15 @@ static bool run_tests(void) /* The arp request packet is now verified, create an arp reply. * The previous value of buf is stored in arp table and is not lost. */ - buf = net_nbuf_get_reserve_rx(0); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); if (!buf) { printk("Out of mem RX reply\n"); return false; } printk("%d buf %p\n", __LINE__, buf); - 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) { printk("Out of mem DATA reply\n"); return false; @@ -615,13 +618,14 @@ static bool run_tests(void) net_nbuf_unref(buf); /* Then feed in ARP request */ - buf = net_nbuf_get_reserve_rx(0); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); if (!buf) { printk("Out of mem RX request\n"); return false; } - 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) { printk("Out of mem DATA request\n"); return false; diff --git a/tests/net/context/src/main.c b/tests/net/context/src/main.c index 560e9a287..4b3e1a3f4 100644 --- a/tests/net/context/src/main.c +++ b/tests/net/context/src/main.c @@ -499,8 +499,8 @@ static bool net_ctx_send_v6(void) int ret, len; struct net_buf *buf, *frag; - buf = net_nbuf_get_tx(udp_v6_ctx); - frag = net_nbuf_get_data(udp_v6_ctx); + buf = net_nbuf_get_tx(udp_v6_ctx, K_FOREVER); + frag = net_nbuf_get_data(udp_v6_ctx, K_FOREVER); net_buf_frag_add(buf, frag); @@ -527,8 +527,8 @@ static bool net_ctx_send_v4(void) int ret, len; struct net_buf *buf, *frag; - buf = net_nbuf_get_tx(udp_v4_ctx); - frag = net_nbuf_get_data(udp_v4_ctx); + buf = net_nbuf_get_tx(udp_v4_ctx, K_FOREVER); + frag = net_nbuf_get_data(udp_v4_ctx, K_FOREVER); net_buf_frag_add(buf, frag); @@ -561,8 +561,8 @@ static bool net_ctx_sendto_v6(void) 0, 0, 0, 0, 0, 0, 0, 0x2 } } }, }; - buf = net_nbuf_get_tx(udp_v6_ctx); - frag = net_nbuf_get_data(udp_v6_ctx); + buf = net_nbuf_get_tx(udp_v6_ctx, K_FOREVER); + frag = net_nbuf_get_data(udp_v6_ctx, K_FOREVER); net_buf_frag_add(buf, frag); @@ -597,8 +597,8 @@ static bool net_ctx_sendto_v4(void) .sin_addr = { { { 192, 0, 2, 2 } } }, }; - buf = net_nbuf_get_tx(udp_v4_ctx); - frag = net_nbuf_get_data(udp_v4_ctx); + buf = net_nbuf_get_tx(udp_v4_ctx, K_FOREVER); + frag = net_nbuf_get_data(udp_v4_ctx, K_FOREVER); net_buf_frag_add(buf, frag); @@ -695,8 +695,8 @@ static bool net_ctx_sendto_v6_wrong_src(void) 0, 0, 0, 0, 0, 0, 0, 0x3 } } }, }; - buf = net_nbuf_get_tx(udp_v6_ctx); - frag = net_nbuf_get_data(udp_v6_ctx); + buf = net_nbuf_get_tx(udp_v6_ctx, K_FOREVER); + frag = net_nbuf_get_data(udp_v6_ctx, K_FOREVER); net_buf_frag_add(buf, frag); @@ -752,8 +752,8 @@ static bool net_ctx_sendto_v4_wrong_src(void) .sin_addr = { { { 192, 0, 2, 3 } } }, }; - buf = net_nbuf_get_tx(udp_v4_ctx); - frag = net_nbuf_get_data(udp_v4_ctx); + buf = net_nbuf_get_tx(udp_v4_ctx, K_FOREVER); + frag = net_nbuf_get_data(udp_v4_ctx, K_FOREVER); net_buf_frag_add(buf, frag); diff --git a/tests/net/dhcpv4/src/main.c b/tests/net/dhcpv4/src/main.c index 84a4733c5..a5b1cb842 100644 --- a/tests/net/dhcpv4/src/main.c +++ b/tests/net/dhcpv4/src/main.c @@ -206,7 +206,8 @@ static struct net_buf *nbuf_get_data(struct net_if *iface) struct net_buf *buf; struct net_eth_hdr *hdr; - buf = net_nbuf_get_reserve_data(net_if_get_ll_reserve(iface, NULL)); + buf = net_nbuf_get_reserve_data(net_if_get_ll_reserve(iface, NULL), + K_FOREVER); if (!buf) { return NULL; } @@ -265,7 +266,7 @@ struct net_buf *prepare_dhcp_offer(struct net_if *iface, uint32_t xid) int bytes, remaining = sizeof(offer), pos = 0; uint16_t offset; - buf = net_nbuf_get_reserve_rx(0); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); if (!buf) { return NULL; } @@ -334,7 +335,7 @@ struct net_buf *prepare_dhcp_ack(struct net_if *iface, uint32_t xid) int bytes, remaining = sizeof(ack), pos = 0; uint16_t offset; - buf = net_nbuf_get_reserve_rx(0); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); if (!buf) { return NULL; } diff --git a/tests/net/ieee802154/fragment/prj.conf b/tests/net/ieee802154/fragment/prj.conf index 7f4381432..f55acf6fc 100644 --- a/tests/net/ieee802154/fragment/prj.conf +++ b/tests/net/ieee802154/fragment/prj.conf @@ -18,5 +18,5 @@ CONFIG_SYS_LOG_SHOW_COLOR=y CONFIG_NET_DEBUG_IF=y CONFIG_NET_DEBUG_CORE=y CONFIG_NET_6LO_DEBUG=n -CONFIG_NET_L2_IEEE802154_FRAGMENT_DEBUG=y +CONFIG_NET_DEBUG_L2_IEEE802154_FRAGMENT=y CONFIG_NET_DEBUG_NET_BUF=n diff --git a/tests/net/ieee802154/fragment/src/main.c b/tests/net/ieee802154/fragment/src/main.c index 76106e5d1..974e3b633 100644 --- a/tests/net/ieee802154/fragment/src/main.c +++ b/tests/net/ieee802154/fragment/src/main.c @@ -221,7 +221,7 @@ static struct net_buf *create_buf(struct net_fragment_data *data) uint16_t len; int remaining; - buf = net_nbuf_get_reserve_tx(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); if (!buf) { return NULL; } @@ -230,7 +230,7 @@ static struct net_buf *create_buf(struct net_fragment_data *data) net_nbuf_set_iface(buf, net_if_get_default()); net_nbuf_set_ip_hdr_len(buf, NET_IPV6H_LEN); - frag = net_nbuf_get_reserve_data(0); + frag = net_nbuf_get_reserve_data(0, K_FOREVER); if (!frag) { net_nbuf_unref(buf); return NULL; @@ -271,7 +271,7 @@ static struct net_buf *create_buf(struct net_fragment_data *data) net_buf_frag_add(buf, frag); if (remaining > 0) { - frag = net_nbuf_get_reserve_data(0); + frag = net_nbuf_get_reserve_data(0, K_FOREVER); } } @@ -376,7 +376,7 @@ static struct net_fragment_data test_data_6 = { .udp.dst_port = htons(udp_dst_port_8bit), .udp.len = 0x00, .udp.chksum = 0x00, - .len = 900, + .len = 1200, .iphc = true }; @@ -410,7 +410,7 @@ static struct net_fragment_data test_data_8 = { .udp.dst_port = htons(udp_dst_port_16bit), .udp.len = 0x00, .udp.chksum = 0x00, - .len = 800, + .len = 1200, .iphc = false }; @@ -446,14 +446,14 @@ static int test_fragment(struct net_fragment_data *data) frag = buf->frags; while (frag) { - rxbuf = net_nbuf_get_reserve_rx(0); + rxbuf = net_nbuf_get_reserve_rx(0, K_FOREVER); if (!rxbuf) { goto end; } net_nbuf_set_ll_reserve(rxbuf, 0); - dfrag = net_nbuf_get_reserve_data(0); + dfrag = net_nbuf_get_reserve_data(0, K_FOREVER); if (!dfrag) { goto end; } diff --git a/tests/net/ieee802154/l2/src/ieee802154_test.c b/tests/net/ieee802154/l2/src/ieee802154_test.c index 2457c3a8a..8bbdd4859 100644 --- a/tests/net/ieee802154/l2/src/ieee802154_test.c +++ b/tests/net/ieee802154/l2/src/ieee802154_test.c @@ -192,8 +192,8 @@ static inline int test_ack_reply(struct ieee802154_pkt_test *t) TC_PRINT("- Sending ACK reply to a data packet\n"); - buf = net_nbuf_get_reserve_rx(0); - frag = net_nbuf_get_reserve_rx(0); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); + frag = net_nbuf_get_reserve_rx(0, K_FOREVER); memcpy(frag->data, data_pkt, sizeof(data_pkt)); frag->len = sizeof(data_pkt); @@ -236,7 +236,7 @@ static inline int initialize_test_environment(void) k_sem_init(&driver_lock, 0, UINT_MAX); - current_buf = net_nbuf_get_reserve_rx(0); + current_buf = net_nbuf_get_reserve_rx(0, K_FOREVER); if (!current_buf) { TC_ERROR("*** No buffer to allocate\n"); return TC_FAIL; diff --git a/tests/net/iface/src/main.c b/tests/net/iface/src/main.c index 5a175ef9d..684934158 100644 --- a/tests/net/iface/src/main.c +++ b/tests/net/iface/src/main.c @@ -283,10 +283,10 @@ static bool send_iface(struct net_if *iface, int val, bool expect_fail) struct net_buf *buf; int ret; - buf = net_nbuf_get_reserve_tx(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); net_nbuf_set_iface(buf, iface); - net_nbuf_append(buf, sizeof(data), data); + net_nbuf_append(buf, sizeof(data), data, K_FOREVER); ret = net_send_data(buf); if (!expect_fail && ret < 0) { diff --git a/tests/net/ipv6/src/main.c b/tests/net/ipv6/src/main.c index 5fb277f44..cb0319a57 100644 --- a/tests/net/ipv6/src/main.c +++ b/tests/net/ipv6/src/main.c @@ -168,7 +168,7 @@ static struct net_buf *prepare_ra_message(void) struct net_if *iface; uint16_t reserve; - buf = net_nbuf_get_reserve_rx(0); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); NET_ASSERT_INFO(buf, "Out of RX buffers"); @@ -176,7 +176,7 @@ static struct net_buf *prepare_ra_message(void) reserve = net_if_get_ll_reserve(iface, NULL); - frag = net_nbuf_get_reserve_data(reserve); + frag = net_nbuf_get_reserve_data(reserve, K_FOREVER); net_buf_frag_add(buf, frag); @@ -413,7 +413,7 @@ static bool net_test_send_ns_extra_options(void) struct net_if *iface; uint16_t reserve; - buf = net_nbuf_get_reserve_tx(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); NET_ASSERT_INFO(buf, "Out of TX buffers"); @@ -421,7 +421,7 @@ static bool net_test_send_ns_extra_options(void) reserve = net_if_get_ll_reserve(iface, NULL); - frag = net_nbuf_get_reserve_data(reserve); + frag = net_nbuf_get_reserve_data(reserve, K_FOREVER); net_buf_frag_add(buf, frag); @@ -449,7 +449,7 @@ static bool net_test_send_ns_no_options(void) struct net_if *iface; uint16_t reserve; - buf = net_nbuf_get_reserve_tx(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); NET_ASSERT_INFO(buf, "Out of TX buffers"); @@ -457,7 +457,7 @@ static bool net_test_send_ns_no_options(void) reserve = net_if_get_ll_reserve(iface, NULL); - frag = net_nbuf_get_reserve_data(reserve); + frag = net_nbuf_get_reserve_data(reserve, K_FOREVER); net_buf_frag_add(buf, frag); @@ -569,7 +569,7 @@ static bool net_test_hbho_message(void) struct net_if *iface; uint16_t reserve; - buf = net_nbuf_get_reserve_tx(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); NET_ASSERT_INFO(buf, "Out of TX buffers"); @@ -577,7 +577,7 @@ static bool net_test_hbho_message(void) reserve = net_if_get_ll_reserve(iface, NULL); - frag = net_nbuf_get_reserve_data(reserve); + frag = net_nbuf_get_reserve_data(reserve, K_FOREVER); net_buf_frag_add(buf, frag); @@ -614,7 +614,7 @@ static bool net_test_change_ll_addr(void) net_ipv6_addr_create(&dst, 0xff02, 0, 0, 0, 0, 0, 0, 1); - buf = net_nbuf_get_reserve_tx(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); NET_ASSERT_INFO(buf, "Out of TX buffers"); @@ -622,7 +622,7 @@ static bool net_test_change_ll_addr(void) reserve = net_if_get_ll_reserve(iface, NULL); - frag = net_nbuf_get_reserve_data(reserve); + frag = net_nbuf_get_reserve_data(reserve, K_FOREVER); net_buf_frag_add(buf, frag); diff --git a/tests/net/nbuf/src/main.c b/tests/net/nbuf/src/main.c index afde9aa29..8a09f3730 100644 --- a/tests/net/nbuf/src/main.c +++ b/tests/net/nbuf/src/main.c @@ -62,8 +62,8 @@ static int test_ipv6_multi_frags(void) int bytes, remaining = strlen(example_data), pos = 0; /* Example of multi fragment scenario with IPv6 */ - buf = net_nbuf_get_reserve_rx(0); - frag = net_nbuf_get_reserve_data(LL_RESERVE); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); + frag = net_nbuf_get_reserve_data(LL_RESERVE, K_FOREVER); /* Place the IP + UDP header in the first fragment */ if (!net_buf_tailroom(frag)) { @@ -91,7 +91,7 @@ static int test_ipv6_multi_frags(void) net_buf_frag_add(buf, frag); /* Put some data to rest of the fragments */ - frag = net_nbuf_get_reserve_data(LL_RESERVE); + frag = net_nbuf_get_reserve_data(LL_RESERVE, K_FOREVER); if (net_buf_tailroom(frag) - (CONFIG_NET_NBUF_DATA_SIZE - LL_RESERVE)) { printk("Invalid number of bytes available in the buf, " @@ -130,7 +130,8 @@ static int test_ipv6_multi_frags(void) net_buf_frag_add(buf, frag); if (remaining > 0) { - frag = net_nbuf_get_reserve_data(LL_RESERVE); + frag = net_nbuf_get_reserve_data(LL_RESERVE, + K_FOREVER); } } @@ -184,8 +185,8 @@ static int test_fragment_copy(void) size_t orig_len; int pos; - buf = net_nbuf_get_reserve_rx(0); - frag = net_nbuf_get_reserve_data(LL_RESERVE); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); + frag = net_nbuf_get_reserve_data(LL_RESERVE, K_FOREVER); /* Place the IP + UDP header in the first fragment */ if (net_buf_tailroom(frag)) { @@ -224,13 +225,13 @@ static int test_fragment_copy(void) /* Then copy a fragment list to a new fragment list */ new_frag = net_nbuf_copy_all(buf->frags, sizeof(struct ipv6_hdr) + - sizeof(struct icmp_hdr)); + sizeof(struct icmp_hdr), K_FOREVER); if (!new_frag) { printk("Cannot copy fragment list.\n"); return -EINVAL; } - new_buf = net_nbuf_get_reserve_tx(0); + new_buf = net_nbuf_get_reserve_tx(0, K_FOREVER); net_buf_frag_add(new_buf, new_frag); printk("Total new data len %zd\n", net_buf_frags_len(new_buf)); @@ -270,9 +271,8 @@ static int test_fragment_copy(void) /* Empty data and test data must be the same size in order the test to work */ static const char test_data[] = { '0', '1', '2', '3', '4', '5', '6', '7' }; -static const char empty_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 }; +#if HEXDUMP static void hexdump(const char *str, const uint8_t *packet, size_t length) { int n = 0; @@ -303,170 +303,19 @@ static void hexdump(const char *str, const uint8_t *packet, size_t length) printk("\n"); } } - -static int test_fragment_push(void) -{ -#define FRAG_COUNT 7 - struct net_buf *buf, *frags[FRAG_COUNT], *frag; - uint8_t *ptr; - int i, bytes; - - buf = net_nbuf_get_reserve_rx(0); - frag = NULL; - - for (i = 0; i < FRAG_COUNT; i++) { - frags[i] = net_nbuf_get_reserve_data(12); - - if (frag) { - net_buf_frag_add(frag, frags[i]); - } - - frag = frags[i]; - - /* Copy character test data in front of the fragment */ - memcpy(net_buf_add(frags[i], sizeof(test_data)), - test_data, sizeof(test_data)); - - /* Followed by bytes of zeroes */ - memset(net_buf_add(frags[i], sizeof(test_data)), 0, - sizeof(test_data)); - } - - net_buf_frag_add(buf, frags[0]); - - bytes = net_buf_frags_len(buf); - if (bytes != FRAG_COUNT * sizeof(test_data) * 2) { - printk("Push test failed, fragments had %d bytes but " - "should have had %zd\n", bytes, - FRAG_COUNT * sizeof(test_data) * 2); - return -1; - } - - if (net_nbuf_is_compact(buf->frags)) { - printk("The buf->frags is not compact. Test fails\n"); - return -1; - } - - if (net_nbuf_is_compact(buf)) { - printk("The buf is definitely not compact. Test fails\n"); - return -1; - } - - buf = net_nbuf_compact(buf); - - if (!net_nbuf_is_compact(buf)) { - printk("The buf should be in compact form. Test fails\n"); - return -1; - } - - /* Try compacting again, nothing should happen */ - buf = net_nbuf_compact(buf); - - if (!net_nbuf_is_compact(buf)) { - printk("The buf should be compacted now. Test fails\n"); - return -1; - } - - buf = net_nbuf_push(buf, buf->frags, sizeof(empty_data)); - if (!buf) { - printk("push test failed, even with fragment pointer\n"); - return -1; - } - - /* Clear the just allocated area */ - memcpy(buf->frags->data, empty_data, sizeof(empty_data)); - - /* The data should look now something like this (frag->data will point - * into this part). - * empty - * test data - * empty - * test data - * empty - * test data - * empty - * test data - * empty - * test data - * empty - * - * Then the second fragment: - * test data - * empty - * test data - * empty - */ - - frag = buf->frags; - - hexdump("frag 1", frag->data, frag->len); - - ptr = frag->data; - - for (i = 0; i < frag->len / (sizeof(empty_data) * 2); i++) { - if (memcmp(ptr, empty_data, sizeof(empty_data))) { - printk("%d: No empty data at pos %p\n", - __LINE__, ptr); - return -1; - } - - ptr += sizeof(empty_data); - - if (memcmp(ptr, test_data, sizeof(test_data))) { - printk("%d: No test data at pos %p\n", - __LINE__, ptr); - return -1; - } - - ptr += sizeof(empty_data); - } - - /* One empty data at the end of first fragment */ - if (memcmp(ptr, empty_data, sizeof(empty_data))) { - printk("%d: No empty data at pos %p\n", - __LINE__, ptr); - return -1; - } - - frag = frag->frags; - - hexdump("frag 2", frag->data, frag->len); - - ptr = frag->data; - - for (i = 0; i < frag->len / (sizeof(empty_data) * 2); i++) { - if (memcmp(ptr, test_data, sizeof(test_data))) { - printk("%d: No test data at pos %p\n", - __LINE__, ptr); - return -1; - } - - ptr += sizeof(test_data); - - if (memcmp(ptr, empty_data, sizeof(empty_data))) { - printk("%d: No empty data at pos %p\n", - __LINE__, ptr); - return -1; - } - - ptr += sizeof(empty_data); - } - - net_nbuf_unref(buf); - - return 0; -} +#endif static int test_fragment_pull(void) { +#define FRAG_COUNT 7 struct net_buf *buf, *newbuf, *frags[FRAG_COUNT], *frag; int i, bytes_before, bytes_after, amount = 10, bytes_before2; - buf = net_nbuf_get_reserve_tx(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); frag = NULL; for (i = 0; i < FRAG_COUNT; i++) { - frags[i] = net_nbuf_get_reserve_data(12); + frags[i] = net_nbuf_get_reserve_data(12, K_FOREVER); if (frag) { net_buf_frag_add(frag, frags[i]); @@ -518,13 +367,13 @@ static int test_fragment_pull(void) net_nbuf_unref(buf); /* Trying without TX or RX buf as a first element */ - frags[0] = net_nbuf_get_reserve_data(12); + frags[0] = net_nbuf_get_reserve_data(12, K_FOREVER); frag = frags[0]; memcpy(net_buf_add(frags[0], sizeof(test_data)), test_data, sizeof(test_data)); for (i = 1; i < FRAG_COUNT; i++) { - frags[i] = net_nbuf_get_reserve_data(12); + frags[i] = net_nbuf_get_reserve_data(12, K_FOREVER); if (frag) { net_buf_frag_add(frag, frags[i]); @@ -621,8 +470,8 @@ static int test_nbuf_read_append(void) uint16_t fail_pos; /* Example of multi fragment read, append and skip APS's */ - buf = net_nbuf_get_reserve_rx(0); - frag = net_nbuf_get_reserve_data(LL_RESERVE); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); + frag = net_nbuf_get_reserve_data(LL_RESERVE, K_FOREVER); /* Place the IP + UDP header in the first fragment */ if (!net_buf_tailroom(frag)) { @@ -650,7 +499,7 @@ static int test_nbuf_read_append(void) net_buf_frag_add(buf, frag); /* Put some data to rest of the fragments */ - frag = net_nbuf_get_reserve_data(LL_RESERVE); + frag = net_nbuf_get_reserve_data(LL_RESERVE, K_FOREVER); if (net_buf_tailroom(frag) - (CONFIG_NET_NBUF_DATA_SIZE - LL_RESERVE)) { printk("Invalid number of bytes available in the buf, " @@ -689,7 +538,8 @@ static int test_nbuf_read_append(void) net_buf_frag_add(buf, frag); if (remaining > 0) { - frag = net_nbuf_get_reserve_data(LL_RESERVE); + frag = net_nbuf_get_reserve_data(LL_RESERVE, + K_FOREVER); } } @@ -765,12 +615,14 @@ static int test_nbuf_read_append(void) tfrag = net_buf_frag_last(buf->frags); off = tfrag->len; - if (!net_nbuf_append(buf, sizeof(test_rw_short), test_rw_short)) { + if (!net_nbuf_append(buf, sizeof(test_rw_short), test_rw_short, + K_FOREVER)) { printk("net_nbuf_append failed\n"); return -EINVAL; } - if (!net_nbuf_append(buf, sizeof(test_rw_short), test_rw_short)) { + if (!net_nbuf_append(buf, sizeof(test_rw_short), test_rw_short, + K_FOREVER)) { printk("net_nbuf_append failed\n"); return -EINVAL; } @@ -799,12 +651,14 @@ static int test_nbuf_read_append(void) tfrag = net_buf_frag_last(buf->frags); off = tfrag->len; - if (!net_nbuf_append(buf, sizeof(test_rw_long), test_rw_long)) { + if (!net_nbuf_append(buf, sizeof(test_rw_long), test_rw_long, + K_FOREVER)) { printk("net_nbuf_append failed\n"); return -EINVAL; } - if (!net_nbuf_append(buf, sizeof(test_rw_long), test_rw_long)) { + if (!net_nbuf_append(buf, sizeof(test_rw_long), test_rw_long, + K_FOREVER)) { printk("net_nbuf_append failed\n"); return -EINVAL; } @@ -812,7 +666,8 @@ static int test_nbuf_read_append(void) /* Try to pass fragment to net_nbuf_append(), this should fail * as we always need to pass the first buf into it. */ - if (net_nbuf_append(buf->frags, sizeof(test_rw_short), test_rw_short)) { + if (net_nbuf_append(buf->frags, sizeof(test_rw_short), test_rw_short, + K_FOREVER)) { printk("net_nbuf_append succeed but should have failed\n"); return -EINVAL; } @@ -847,10 +702,10 @@ static int test_nbuf_read_write_insert(void) uint16_t pos; /* Example of multi fragment read, append and skip APS's */ - buf = net_nbuf_get_reserve_rx(0); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); net_nbuf_set_ll_reserve(buf, LL_RESERVE); - frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf)); + frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf), K_FOREVER); net_buf_frag_add(buf, frag); /* 1) Offset is with in input fragment. @@ -859,7 +714,7 @@ static int test_nbuf_read_write_insert(void) * and write data). */ frag = net_nbuf_write(buf, frag, NET_IPV6UDPH_LEN, &pos, 10, - (uint8_t *)sample_data); + (uint8_t *)sample_data, K_FOREVER); if (!frag || pos != 58) { printk("Usecase 1: Write failed\n"); return -EINVAL; @@ -882,7 +737,7 @@ static int test_nbuf_read_write_insert(void) * there shouldn't be any length change). */ frag = net_nbuf_write(buf, frag, 0, &pos, NET_IPV6UDPH_LEN, - (uint8_t *)sample_data); + (uint8_t *)sample_data, K_FOREVER); if (!frag || pos != 48) { printk("Usecase 2: Write failed\n"); return -EINVAL; @@ -903,7 +758,7 @@ static int test_nbuf_read_write_insert(void) /* Unref */ net_nbuf_unref(buf); - buf = net_nbuf_get_reserve_rx(0); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); net_nbuf_set_ll_reserve(buf, LL_RESERVE); /* 3) Offset is in next to next fragment. @@ -911,7 +766,7 @@ static int test_nbuf_read_write_insert(void) * create empty fragments(space) till offset and write data). */ frag = net_nbuf_write(buf, buf->frags, 200, &pos, 10, - (uint8_t *)sample_data + 10); + (uint8_t *)sample_data + 10, K_FOREVER); if (!frag) { printk("Usecase 3: Write failed"); } @@ -934,7 +789,7 @@ static int test_nbuf_read_write_insert(void) * the existing data. */ frag = net_nbuf_write(buf, buf->frags, 190, &pos, 10, - (uint8_t *)sample_data); + (uint8_t *)sample_data, K_FOREVER); if (!frag) { printk("Usecase 4: Write failed\n"); return -EINVAL; @@ -959,16 +814,17 @@ static int test_nbuf_read_write_insert(void) * API should overwrite on first 10 bytes and create extra 10 bytes * and write there. */ - buf = net_nbuf_get_reserve_rx(0); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); net_nbuf_set_ll_reserve(buf, LL_RESERVE); - frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf)); + frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf), K_FOREVER); net_buf_frag_add(buf, frag); /* Create 10 bytes space. */ net_buf_add(frag, 10); - frag = net_nbuf_write(buf, frag, 0, &pos, 20, (uint8_t *)sample_data); + frag = net_nbuf_write(buf, frag, 0, &pos, 20, (uint8_t *)sample_data, + K_FOREVER); if (!frag && pos != 20) { printk("Usecase 5: Write failed\n"); return -EINVAL; @@ -996,18 +852,18 @@ static int test_nbuf_read_write_insert(void) * bytes and write data. Third fragment 5 bytes overwritten and space * for 5 bytes created. */ - buf = net_nbuf_get_reserve_rx(0); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); net_nbuf_set_ll_reserve(buf, LL_RESERVE); /* First fragment make it fully occupied. */ - frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf)); + frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf), K_FOREVER); net_buf_frag_add(buf, frag); len = net_buf_tailroom(frag); net_buf_add(frag, len); /* 2nd fragment last 10 bytes tailroom, rest occupied */ - frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf)); + frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf), K_FOREVER); net_buf_frag_add(buf, frag); len = net_buf_tailroom(frag); @@ -1017,12 +873,12 @@ static int test_nbuf_read_write_insert(void) read_pos = frag->len - 10; /* 3rd fragment, only 5 bytes occupied */ - frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf)); + frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf), K_FOREVER); net_buf_frag_add(buf, frag); net_buf_add(frag, 5); temp_frag = net_nbuf_write(buf, temp_frag, temp_frag->len - 10, &pos, - 30, (uint8_t *) sample_data); + 30, (uint8_t *) sample_data, K_FOREVER); if (!temp_frag) { printk("Use case 6: Write failed\n"); return -EINVAL; @@ -1050,15 +906,15 @@ static int test_nbuf_read_write_insert(void) * before first set of app data. */ - buf = net_nbuf_get_reserve_rx(0); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); net_nbuf_set_ll_reserve(buf, LL_RESERVE); /* First fragment make it fully occupied. */ - frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf)); + frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf), K_FOREVER); net_buf_frag_add(buf, frag); frag = net_nbuf_write(buf, frag, NET_IPV6UDPH_LEN, &pos, 10, - (uint8_t *)sample_data + 10); + (uint8_t *)sample_data + 10, K_FOREVER); if (!frag || pos != 58) { printk("Usecase 7: Write failed\n"); return -EINVAL; @@ -1077,7 +933,7 @@ static int test_nbuf_read_write_insert(void) } if (!net_nbuf_insert(buf, frag, NET_IPV6UDPH_LEN, 10, - (uint8_t *)sample_data)) { + (uint8_t *)sample_data, K_FOREVER)) { printk("Usecase 7: Insert failed\n"); return -EINVAL; } @@ -1095,7 +951,8 @@ static int test_nbuf_read_write_insert(void) } /* Insert data outside input fragment length, error case. */ - if (net_nbuf_insert(buf, frag, 70, 10, (uint8_t *)sample_data)) { + if (net_nbuf_insert(buf, frag, 70, 10, (uint8_t *)sample_data, + K_FOREVER)) { printk("Usecase 7: False insert failed\n"); return -EINVAL; } @@ -1110,15 +967,15 @@ static int test_nbuf_read_write_insert(void) * before first set of app data. Insertion data is long which will * take two fragments. */ - buf = net_nbuf_get_reserve_rx(0); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); net_nbuf_set_ll_reserve(buf, LL_RESERVE); /* First fragment make it fully occupied. */ - frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf)); + frag = net_nbuf_get_reserve_data(net_nbuf_ll_reserve(buf), K_FOREVER); net_buf_frag_add(buf, frag); frag = net_nbuf_write(buf, frag, NET_IPV6UDPH_LEN, &pos, 10, - (uint8_t *)sample_data + 60); + (uint8_t *)sample_data + 60, K_FOREVER); if (!frag || pos != 58) { printk("Usecase 8: Write failed\n"); return -EINVAL; @@ -1137,7 +994,7 @@ static int test_nbuf_read_write_insert(void) } if (!net_nbuf_insert(buf, frag, NET_IPV6UDPH_LEN, 60, - (uint8_t *)sample_data)) { + (uint8_t *)sample_data, K_FOREVER)) { printk("Usecase 8: Insert failed\n"); return -EINVAL; } @@ -1177,11 +1034,11 @@ static int test_fragment_compact(void) struct net_buf *buf, *frags[FRAG_COUNT], *frag; int i, bytes, total, count; - buf = net_nbuf_get_reserve_rx(0); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); frag = NULL; for (i = 0, total = 0; i < FRAG_COUNT; i++) { - frags[i] = net_nbuf_get_reserve_data(12); + frags[i] = net_nbuf_get_reserve_data(12, K_FOREVER); if (frag) { net_buf_frag_add(frag, frags[i]); @@ -1226,7 +1083,7 @@ static int test_fragment_compact(void) return -1; } - buf = net_nbuf_compact(buf); + net_nbuf_compact(buf); if (!net_nbuf_is_compact(buf)) { printk("The buf should be in compact form. Test fails\n"); @@ -1234,7 +1091,7 @@ static int test_fragment_compact(void) } /* Try compacting again, nothing should happen */ - buf = net_nbuf_compact(buf); + net_nbuf_compact(buf); if (!net_nbuf_is_compact(buf)) { printk("The buf should be compacted now. Test fails\n"); @@ -1246,13 +1103,13 @@ static int test_fragment_compact(void) /* Add empty fragment at the end and compact, the last fragment * should be removed. */ - frag = net_nbuf_get_reserve_data(0); + frag = net_nbuf_get_reserve_data(0, K_FOREVER); net_buf_frag_add(buf, frag); count = calc_fragments(buf); - buf = net_nbuf_compact(buf); + net_nbuf_compact(buf); i = calc_fragments(buf); @@ -1271,17 +1128,17 @@ static int test_fragment_compact(void) /* Add two empty fragments at the end and compact, the last two * fragment should be removed. */ - frag = net_nbuf_get_reserve_data(0); + frag = net_nbuf_get_reserve_data(0, K_FOREVER); net_buf_frag_add(buf, frag); - frag = net_nbuf_get_reserve_data(0); + frag = net_nbuf_get_reserve_data(0, K_FOREVER); net_buf_frag_add(buf, frag); count = calc_fragments(buf); - buf = net_nbuf_compact(buf); + net_nbuf_compact(buf); i = calc_fragments(buf); @@ -1300,17 +1157,17 @@ static int test_fragment_compact(void) /* Add empty fragment at the beginning and at the end, and then * compact, the two fragment should be removed. */ - frag = net_nbuf_get_reserve_data(0); + frag = net_nbuf_get_reserve_data(0, K_FOREVER); net_buf_frag_insert(buf, frag); - frag = net_nbuf_get_reserve_data(0); + frag = net_nbuf_get_reserve_data(0, K_FOREVER); net_buf_frag_add(buf, frag); count = calc_fragments(buf); - buf = net_nbuf_compact(buf); + net_nbuf_compact(buf); i = calc_fragments(buf); @@ -1339,10 +1196,6 @@ void main(void) goto fail; } - if (test_fragment_push() < 0) { - goto fail; - } - if (test_fragment_pull() < 0) { goto fail; } diff --git a/tests/net/route/src/main.c b/tests/net/route/src/main.c index aefe2e18e..7995185f5 100644 --- a/tests/net/route/src/main.c +++ b/tests/net/route/src/main.c @@ -357,14 +357,14 @@ static bool net_test_send_na(struct net_if *iface, 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"); buf = net_ipv6_create_raw(buf, net_if_get_ll_reserve(iface, dst), addr, dst, iface, IPPROTO_ICMPV6); - frag = net_nbuf_get_reserve_data(0); + frag = net_nbuf_get_reserve_data(0, K_FOREVER); NET_ASSERT_INFO(frag, "Out of DATA buffers"); diff --git a/tests/net/rpl/src/main.c b/tests/net/rpl/src/main.c index 0c9beba21..bd6a78246 100644 --- a/tests/net/rpl/src/main.c +++ b/tests/net/rpl/src/main.c @@ -316,8 +316,8 @@ static bool test_dio_dummy_input(void) struct net_buf *buf, *frag; int ret; - buf = net_nbuf_get_tx(udp_ctx); - frag = net_nbuf_get_data(udp_ctx); + buf = net_nbuf_get_tx(udp_ctx, K_FOREVER); + frag = net_nbuf_get_data(udp_ctx, K_FOREVER); net_buf_frag_add(buf, frag); diff --git a/tests/net/tcp/src/main.c b/tests/net/tcp/src/main.c index 442e1efb7..554993ddb 100644 --- a/tests/net/tcp/src/main.c +++ b/tests/net/tcp/src/main.c @@ -325,8 +325,8 @@ static bool send_ipv6_tcp_msg(struct net_if *iface, struct net_buf *frag; int ret; - buf = net_nbuf_get_reserve_tx(0); - frag = net_nbuf_get_reserve_data(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); + frag = net_nbuf_get_reserve_data(0, K_FOREVER); net_buf_frag_add(buf, frag); net_nbuf_set_iface(buf, iface); @@ -373,8 +373,8 @@ static bool send_ipv4_tcp_msg(struct net_if *iface, struct net_buf *frag; int ret; - buf = net_nbuf_get_reserve_tx(0); - frag = net_nbuf_get_reserve_data(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); + frag = net_nbuf_get_reserve_data(0, K_FOREVER); net_buf_frag_add(buf, frag); net_nbuf_set_iface(buf, iface); diff --git a/tests/net/udp/src/main.c b/tests/net/udp/src/main.c index 2884de09a..05ff5e336 100644 --- a/tests/net/udp/src/main.c +++ b/tests/net/udp/src/main.c @@ -242,8 +242,8 @@ static bool send_ipv6_udp_msg(struct net_if *iface, struct net_buf *frag; int ret; - buf = net_nbuf_get_reserve_tx(0); - frag = net_nbuf_get_reserve_data(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); + frag = net_nbuf_get_reserve_data(0, K_FOREVER); net_buf_frag_add(buf, frag); net_nbuf_set_iface(buf, iface); @@ -290,8 +290,8 @@ static bool send_ipv4_udp_msg(struct net_if *iface, struct net_buf *frag; int ret; - buf = net_nbuf_get_reserve_tx(0); - frag = net_nbuf_get_reserve_data(0); + buf = net_nbuf_get_reserve_tx(0, K_FOREVER); + frag = net_nbuf_get_reserve_data(0, K_FOREVER); net_buf_frag_add(buf, frag); net_nbuf_set_iface(buf, iface); diff --git a/tests/net/utils/src/main.c b/tests/net/utils/src/main.c index 48172a5ef..30d30daae 100644 --- a/tests/net/utils/src/main.c +++ b/tests/net/utils/src/main.c @@ -154,8 +154,8 @@ static bool run_tests(void) int hdr_len, i, chunk, datalen, total = 0; /* Packet fits to one fragment */ - buf = net_nbuf_get_reserve_rx(0); - frag = net_nbuf_get_reserve_data(10); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); + frag = net_nbuf_get_reserve_data(10, K_FOREVER); net_buf_frag_add(buf, frag); memcpy(net_buf_add(frag, sizeof(pkt1)), pkt1, sizeof(pkt1)); @@ -184,8 +184,8 @@ static bool run_tests(void) net_nbuf_unref(buf); /* Then a case where there will be two fragments */ - buf = net_nbuf_get_reserve_rx(0); - frag = net_nbuf_get_reserve_data(10); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); + frag = net_nbuf_get_reserve_data(10, K_FOREVER); net_buf_frag_add(buf, frag); memcpy(net_buf_add(frag, sizeof(pkt2) / 2), pkt2, sizeof(pkt2) / 2); @@ -198,7 +198,7 @@ static bool run_tests(void) frag->data[hdr_len + 2] = 0; frag->data[hdr_len + 3] = 0; - frag = net_nbuf_get_reserve_data(10); + frag = net_nbuf_get_reserve_data(10, K_FOREVER); net_buf_frag_add(buf, frag); memcpy(net_buf_add(frag, sizeof(pkt2) - sizeof(pkt2) / 2), pkt2 + sizeof(pkt2) / 2, sizeof(pkt2) - sizeof(pkt2) / 2); @@ -212,8 +212,8 @@ static bool run_tests(void) net_nbuf_unref(buf); /* Then a case where there will be two fragments but odd data size */ - buf = net_nbuf_get_reserve_rx(0); - frag = net_nbuf_get_reserve_data(10); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); + frag = net_nbuf_get_reserve_data(10, K_FOREVER); net_buf_frag_add(buf, frag); memcpy(net_buf_add(frag, sizeof(pkt3) / 2), pkt3, sizeof(pkt3) / 2); printk("First fragment will have %zd bytes\n", sizeof(pkt3) / 2); @@ -227,7 +227,7 @@ static bool run_tests(void) frag->data[hdr_len + 2] = 0; frag->data[hdr_len + 3] = 0; - frag = net_nbuf_get_reserve_data(10); + frag = net_nbuf_get_reserve_data(10, K_FOREVER); net_buf_frag_add(buf, frag); memcpy(net_buf_add(frag, sizeof(pkt3) - sizeof(pkt3) / 2), pkt3 + sizeof(pkt3) / 2, sizeof(pkt3) - sizeof(pkt3) / 2); @@ -243,8 +243,8 @@ static bool run_tests(void) net_nbuf_unref(buf); /* Then a case where there will be several fragments */ - buf = net_nbuf_get_reserve_rx(0); - frag = net_nbuf_get_reserve_data(10); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); + frag = net_nbuf_get_reserve_data(10, K_FOREVER); net_buf_frag_add(buf, frag); memcpy(net_buf_add(frag, sizeof(struct net_ipv6_hdr)), pkt3, sizeof(struct net_ipv6_hdr)); @@ -259,7 +259,7 @@ static bool run_tests(void) for (i = 0; i < datalen/chunk; i++) { /* Next fragments will contain the data in odd sizes */ - frag = net_nbuf_get_reserve_data(10); + frag = net_nbuf_get_reserve_data(10, K_FOREVER); net_buf_frag_add(buf, frag); memcpy(net_buf_add(frag, chunk), pkt3 + sizeof(struct net_ipv6_hdr) + i * chunk, chunk); @@ -278,7 +278,7 @@ static bool run_tests(void) } } if ((datalen - total) > 0) { - frag = net_nbuf_get_reserve_data(10); + frag = net_nbuf_get_reserve_data(10, K_FOREVER); net_buf_frag_add(buf, frag); memcpy(net_buf_add(frag, datalen - total), pkt3 + sizeof(struct net_ipv6_hdr) + i * chunk, @@ -309,8 +309,9 @@ static bool run_tests(void) /* Another packet that fits to one fragment. * This one has ethernet header before IPv4 data. */ - buf = net_nbuf_get_reserve_rx(0); - frag = net_nbuf_get_reserve_data(sizeof(struct net_eth_hdr)); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); + frag = net_nbuf_get_reserve_data(sizeof(struct net_eth_hdr), + K_FOREVER); net_buf_frag_add(buf, frag); net_nbuf_set_ll_reserve(buf, sizeof(struct net_eth_hdr)); @@ -337,8 +338,9 @@ static bool run_tests(void) /* Another packet that fits to one fragment and which has correct * checksum. This one has ethernet header before IPv4 data. */ - buf = net_nbuf_get_reserve_rx(0); - frag = net_nbuf_get_reserve_data(sizeof(struct net_eth_hdr)); + buf = net_nbuf_get_reserve_rx(0, K_FOREVER); + frag = net_nbuf_get_reserve_data(sizeof(struct net_eth_hdr), + K_FOREVER); net_buf_frag_add(buf, frag); net_nbuf_set_ll_reserve(buf, sizeof(struct net_eth_hdr)); |