diff --git a/boards/x86/quark_se_c1000_devboard/Makefile b/boards/x86/quark_se_c1000_devboard/Makefile index 50c8745ff580c0ed9bb5c8c25d82cf0fb81b85d9..097c04d76c337ac2ed8dd542aa1b43d6fafb8c17 100644 --- a/boards/x86/quark_se_c1000_devboard/Makefile +++ b/boards/x86/quark_se_c1000_devboard/Makefile @@ -3,14 +3,5 @@ ccflags-y += -I$(srctree)/drivers ccflags-y += -I$(srctree)/drivers/pinmux asflags-y := ${ccflags-y} -ccflags-$(CONFIG_TI_CC2520_LEGACY) += \ - -I${srctree}/net/ip/contiki -ccflags-$(CONFIG_TI_CC2520_LEGACY) += \ - -I${srctree}/net/ip/contiki/os/lib -ccflags-$(CONFIG_TI_CC2520_LEGACY) += \ - -I${srctree}/net/ip/contiki/os -ccflags-$(CONFIG_TI_CC2520_LEGACY) += \ - -I${srctree}/net/ip - obj-$(CONFIG_PINMUX) += pinmux.o obj-y += board.o diff --git a/drivers/ethernet/Makefile b/drivers/ethernet/Makefile index 22f6fafdf1d6353e0527cfb9960d3cc71bc011f8..cd217f0d75c25c79c606b70d804228a7d2fceef5 100644 --- a/drivers/ethernet/Makefile +++ b/drivers/ethernet/Makefile @@ -1,14 +1,5 @@ -ccflags-y += -I${srctree}/net/ip/contiki -ccflags-y += -I${srctree}/net/ip/contiki/os/lib -ccflags-y += -I${srctree}/net/ip/contiki/os -ccflags-y += -I${srctree}/net/ip ccflags-y += -I${srctree} obj-$(CONFIG_ETH_DW) += eth_dw.o -ifdef CONFIG_NET_YAIP obj-$(CONFIG_ETH_KSDK) += eth_ksdk.o obj-$(CONFIG_ETH_ENC28J60) += eth_enc28j60.o -else -obj-$(CONFIG_ETH_KSDK) += eth_ksdk_legacy.o -obj-$(CONFIG_ETH_ENC28J60) += eth_enc28j60_legacy.o -endif diff --git a/drivers/ethernet/eth_ksdk_legacy.c b/drivers/ethernet/eth_ksdk_legacy.c deleted file mode 100644 index 64960677ed958a732a90b4d29e3547d2f671174a..0000000000000000000000000000000000000000 --- a/drivers/ethernet/eth_ksdk_legacy.c +++ /dev/null @@ -1,335 +0,0 @@ -/* KSDK Ethernet Driver - * - * Copyright (c) 2016 ARM Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* The driver performs one shot PHY setup. There is no support for - * PHY disconnect, reconnect or configuration change. The PHY setup, - * implemented via KSDK contains polled code that can block the - * initialization thread for a few seconds. - * - * There is no statistics collection for either normal operation or - * error behaviour. - */ - -#include -#include -#include -#include -#include - -#include "fsl_enet.h" -#include "fsl_phy.h" -#include "fsl_port.h" - -#define SYS_LOG_DOMAIN "dev/eth_ksdk" -#define SYS_LOG_LEVEL CONFIG_SYS_LOG_ETHERNET_LEVEL -#include - -struct eth_context { - enet_handle_t enet_handle; - struct nano_sem tx_buf_sem; - uint8_t mac_addr[6]; -}; - -static int eth_net_tx(struct net_buf *); -static void eth_0_config_func(void); - -static enet_rx_bd_struct_t __aligned(ENET_BUFF_ALIGNMENT) -rx_buffer_desc[CONFIG_ETH_KSDK_TX_BUFFERS]; - -static enet_tx_bd_struct_t __aligned(ENET_BUFF_ALIGNMENT) -tx_buffer_desc[CONFIG_ETH_KSDK_TX_BUFFERS]; - -/* Use ENET_FRAME_MAX_VALNFRAMELEN for VLAN frame size - * Use ENET_FRAME_MAX_FRAMELEN for ethernet frame size - */ -#define ETH_KSDK_BUFFER_SIZE \ - ROUND_UP(ENET_FRAME_MAX_VALNFRAMELEN, ENET_BUFF_ALIGNMENT) - -static uint8_t __aligned(ENET_BUFF_ALIGNMENT) -rx_buffer[CONFIG_ETH_KSDK_RX_BUFFERS][ETH_KSDK_BUFFER_SIZE]; - -static uint8_t __aligned(ENET_BUFF_ALIGNMENT) -tx_buffer[CONFIG_ETH_KSDK_TX_BUFFERS][ETH_KSDK_BUFFER_SIZE]; - -static int eth_tx(struct device *iface, struct net_buf *buf) -{ - struct eth_context *context = iface->driver_data; - status_t status; - - nano_sem_take(&context->tx_buf_sem, TICKS_UNLIMITED); - - status = ENET_SendFrame(ENET, &context->enet_handle, uip_buf(buf), - uip_len(buf)); - if (status) { - SYS_LOG_ERR("ENET_SendFrame error: %d\n", status); - return 0; - } - return 1; -} - -static void eth_rx(struct device *iface) -{ - struct eth_context *context = iface->driver_data; - struct net_buf *buf; - uint32_t frame_length = 0; - status_t status; - - status = ENET_GetRxFrameSize(&context->enet_handle, &frame_length); - if (status) { - enet_data_error_stats_t error_stats; - - SYS_LOG_ERR("ENET_GetRxFrameSize return: %d", status); - - ENET_GetRxErrBeforeReadFrame(&context->enet_handle, - &error_stats); - /* Flush the current read buffer. This operation can - * only report failure if there is no frame to flush, - * which cannot happen in this context. - */ - status = ENET_ReadFrame(ENET, &context->enet_handle, NULL, 0); - assert(status == kStatus_Success); - return; - } - - buf = ip_buf_get_reserve_rx(0); - if (buf == NULL) { - /* We failed to get a receive buffer. We don't add - * any further logging here because the allocator - * issued a diagnostic when it failed to allocate. - * - * Flush the current read buffer. This operation can - * only report failure if there is no frame to flush, - * which cannot happen in this context. - */ - status = ENET_ReadFrame(ENET, &context->enet_handle, NULL, 0); - assert(status == kStatus_Success); - return; - } - - if (net_buf_tailroom(buf) < frame_length) { - SYS_LOG_ERR("frame too large\n"); - net_buf_unref(buf); - status = ENET_ReadFrame(ENET, &context->enet_handle, NULL, 0); - assert(status == kStatus_Success); - return; - } - - status = ENET_ReadFrame(ENET, &context->enet_handle, - net_buf_add(buf, frame_length), frame_length); - if (status) { - SYS_LOG_ERR("ENET_ReadFrame failed: %d\n", status); - net_buf_unref(buf); - return; - } - - uip_len(buf) = frame_length; - net_driver_ethernet_recv(buf); -} - -void eth_callback(ENET_Type *base, enet_handle_t *handle, enet_event_t event, - void *param) -{ - struct device *iface = param; - struct eth_context *context = iface->driver_data; - - switch (event) { - case kENET_RxEvent: - eth_rx(iface); - break; - case kENET_TxEvent: - /* Free the TX buffer. */ - nano_sem_give(&context->tx_buf_sem); - break; - case kENET_ErrEvent: - /* Error event: BABR/BABT/EBERR/LC/RL/UN/PLR. */ - break; - case kENET_WakeUpEvent: - /* Wake up from sleep mode event. */ - break; -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - case kENET_TimeStampEvent: - /* Time stamp event. */ - break; - case kENET_TimeStampAvailEvent: - /* Time stamp available event. */ - break; -#endif - } -} - -#if defined(CONFIG_ETH_KSDK_0_RANDOM_MAC) -static void generate_mac(uint8_t *mac_addr) -{ - uint32_t entropy; - - entropy = sys_rand32_get(); - - /* Locally administered, unicast */ - mac_addr[0] = ((entropy >> 0) & 0xfc) | 0x02; - - mac_addr[1] = entropy >> 8; - mac_addr[2] = entropy >> 16; - mac_addr[3] = entropy >> 24; - - entropy = sys_rand32_get(); - - mac_addr[4] = entropy >> 0; - mac_addr[5] = entropy >> 8; -} -#endif - -static int eth_0_init(struct device *dev) -{ - struct eth_context *context = dev->driver_data; - enet_config_t enet_config; - uint32_t sys_clock; - const uint32_t phy_addr = 0x0; - bool link; - status_t status; - int result; - enet_buffer_config_t buffer_config = { - .rxBdNumber = CONFIG_ETH_KSDK_RX_BUFFERS, - .txBdNumber = CONFIG_ETH_KSDK_TX_BUFFERS, - .rxBuffSizeAlign = ETH_KSDK_BUFFER_SIZE, - .txBuffSizeAlign = ETH_KSDK_BUFFER_SIZE, - .rxBdStartAddrAlign = rx_buffer_desc, - .txBdStartAddrAlign = tx_buffer_desc, - .rxBufferAlign = rx_buffer[0], - .txBufferAlign = tx_buffer[0], - }; - - nano_sem_init(&context->tx_buf_sem); - for (int i = 0; i < CONFIG_ETH_KSDK_TX_BUFFERS; i++) { - nano_sem_give(&context->tx_buf_sem); - } - - sys_clock = CLOCK_GetFreq(kCLOCK_CoreSysClk); - - ENET_GetDefaultConfig(&enet_config); - enet_config.interrupt |= kENET_RxFrameInterrupt; - enet_config.interrupt |= kENET_TxFrameInterrupt; - - status = PHY_Init(ENET, phy_addr, sys_clock); - if (status) { - SYS_LOG_ERR("PHY_Init() failed: %d", status); - return 1; - } - - PHY_GetLinkStatus(ENET, phy_addr, &link); - if (link) { - phy_speed_t phy_speed; - phy_duplex_t phy_duplex; - - PHY_GetLinkSpeedDuplex(ENET, phy_addr, &phy_speed, &phy_duplex); - enet_config.miiSpeed = (enet_mii_speed_t) phy_speed; - enet_config.miiDuplex = (enet_mii_duplex_t) phy_duplex; - - SYS_LOG_INF("Enabled %dM %s-duplex mode.", - (phy_speed ? 100 : 10), - (phy_duplex ? "full" : "half")); - } else { - SYS_LOG_INF("Link down."); - } - -#if defined(CONFIG_ETH_KSDK_0_RANDOM_MAC) - generate_mac(context->mac_addr); -#endif - - ENET_Init(ENET, - &context->enet_handle, - &enet_config, - &buffer_config, - context->mac_addr, - sys_clock); - - SYS_LOG_DBG("MAC %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", - context->mac_addr[0], context->mac_addr[1], - context->mac_addr[2], context->mac_addr[3], - context->mac_addr[4], context->mac_addr[5]); - - result = net_set_mac(context->mac_addr, sizeof(context->mac_addr)); - if (result) { - return 1; - } - - ENET_SetCallback(&context->enet_handle, eth_callback, dev); - net_driver_ethernet_register_tx(eth_net_tx); - eth_0_config_func(); - ENET_ActiveRead(ENET); - return 0; -} - -static void eth_ksdk_rx_isr(void *p) -{ - struct device *dev = p; - struct eth_context *context = dev->driver_data; - - ENET_ReceiveIRQHandler(ENET, &context->enet_handle); -} - -static void eth_ksdk_tx_isr(void *p) -{ - struct device *dev = p; - struct eth_context *context = dev->driver_data; - - ENET_TransmitIRQHandler(ENET, &context->enet_handle); -} - -static void eth_ksdk_error_isr(void *p) -{ - struct device *dev = p; - struct eth_context *context = dev->driver_data; - - ENET_ErrorIRQHandler(ENET, &context->enet_handle); -} - -static struct eth_context eth_0_context = { -#if !defined(CONFIG_ETH_KSDK_0_RANDOM_MAC) - .mac_addr = { - CONFIG_ETH_KSDK_0_MAC0, - CONFIG_ETH_KSDK_0_MAC1, - CONFIG_ETH_KSDK_0_MAC2, - CONFIG_ETH_KSDK_0_MAC3, - CONFIG_ETH_KSDK_0_MAC4, - CONFIG_ETH_KSDK_0_MAC5 - } -#endif -}; - -DEVICE_INIT(eth_ksdk_0, CONFIG_ETH_KSDK_0_NAME, eth_0_init, - ð_0_context, NULL, - NANOKERNEL, CONFIG_ETH_INIT_PRIORITY); - -static int eth_net_tx(struct net_buf *buf) -{ - return eth_tx(DEVICE_GET(eth_ksdk_0), buf); -} - -static void eth_0_config_func(void) -{ - IRQ_CONNECT(IRQ_ETH_RX, CONFIG_ETH_KSDK_0_IRQ_PRI, - eth_ksdk_rx_isr, DEVICE_GET(eth_ksdk_0), 0); - irq_enable(IRQ_ETH_RX); - - IRQ_CONNECT(IRQ_ETH_TX, CONFIG_ETH_KSDK_0_IRQ_PRI, - eth_ksdk_tx_isr, DEVICE_GET(eth_ksdk_0), 0); - irq_enable(IRQ_ETH_TX); - - IRQ_CONNECT(IRQ_ETH_ERR_MISC, CONFIG_ETH_KSDK_0_IRQ_PRI, - eth_ksdk_error_isr, DEVICE_GET(eth_ksdk_0), 0); - irq_enable(IRQ_ETH_ERR_MISC); -} diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig index d8750057b47d6e3f80af3060fcf40797087a1a61..a659cbed281eb784c3e54574cff35d612aea898d 100644 --- a/drivers/ieee802154/Kconfig +++ b/drivers/ieee802154/Kconfig @@ -35,11 +35,6 @@ # menu "IEEE 802.15.4 drivers options" -config TI_CC2520_LEGACY - bool "TI CC2520 Driver support" - depends on NET_UIP - default n - config TI_CC2520 bool "TI CC2520 Driver support" depends on NET_YAIP @@ -56,7 +51,7 @@ config TI_CC2520_RAW The CC2520 driver with RAW channel allows to export radio interface over USB making an USB 802.15.4 dongle. -if TI_CC2520_LEGACY || TI_CC2520 || TI_CC2520_RAW +if TI_CC2520 || TI_CC2520_RAW config SYS_LOG_TI_CC2520_LEVEL int @@ -121,36 +116,6 @@ config TI_CC2520_CHANNEL All the 802.15.4 devices that want to connect to each other need to have same channel. Default channel is 26. -config TI_CC2520_AUTO_CRC - bool "Let the chip handling CRC on reception" - default y - depends on TI_CC2520_LEGACY - help - When receiving a packet, the hardware can verify the CRC by itself - and will provide a flag letting know the success - or not - on - a flag on the footer. - -config TI_CC2520_LINK_DETAILS - bool "Forward RSSI and link information on reception to upper stack" - default n - depends on TI_CC2520_LEGACY - select TI_CC2520_AUTO_CRC - help - If necessary, it will be possible to grab link and RSSI information - from the packet footer and forward them to the above stack. - -config TI_CC2520_AUTO_ACK - bool "Let the chip handle TX/RX IEEE 802.15.4 ACK requests" - default n - depends on TI_CC2520_LEGACY - select TI_CC2520_AUTO_CRC - help - The chip is able to reply by itself to ACK requests as well as - waiting for an ACK when a TX packet is requesting an ACK. However, - this feature requires the chip to get hardware filtering on, and - thus the above stack needs to provide the right information for such - filtering feature to work. - config TI_CC2520_INIT_PRIO int "CC2520 intialization priority" default 80 diff --git a/drivers/ieee802154/Makefile b/drivers/ieee802154/Makefile index 82c31d09904b2a4ec77f1d6dccdeee1232686e92..ed213ba63cb2ea5b0dfa82754bd9d6017453bdcf 100644 --- a/drivers/ieee802154/Makefile +++ b/drivers/ieee802154/Makefile @@ -1,9 +1,3 @@ -subdir-ccflags-$(CONFIG_TI_CC2520_LEGACY) +=-I${srctree}/net/ip/contiki -subdir-ccflags-$(CONFIG_TI_CC2520_LEGACY) +=-I${srctree}/net/ip/contiki/os/lib -subdir-ccflags-$(CONFIG_TI_CC2520_LEGACY) +=-I${srctree}/net/ip/contiki/os -subdir-ccflags-$(CONFIG_TI_CC2520_LEGACY) +=-I${srctree}/net/ip - -obj-$(CONFIG_TI_CC2520_LEGACY) += ieee802154_cc2520_legacy.o obj-$(CONFIG_TI_CC2520) += ieee802154_cc2520.o obj-$(CONFIG_TI_CC2520_RAW) += ieee802154_cc2520.o obj-$(CONFIG_UPIPE_15_4) += ieee802154_uart_pipe.o diff --git a/drivers/ieee802154/ieee802154_cc2520_legacy.c b/drivers/ieee802154/ieee802154_cc2520_legacy.c deleted file mode 100644 index 34c5db7938b43b72f8d3c1a26ff2daf767c3b6fd..0000000000000000000000000000000000000000 --- a/drivers/ieee802154/ieee802154_cc2520_legacy.c +++ /dev/null @@ -1,1181 +0,0 @@ -/* ieee802154_cc2520.c - IEEE 802.15.4 driver for TI CC2520 */ - -/* - * Copyright (c) 2016 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define SYS_LOG_LEVEL CONFIG_SYS_LOG_TI_CC2520_LEVEL -#define SYS_LOG_NO_NEWLINE -#include - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include - -#include -#include -static struct device *cc2520_sglt; - -#include "ieee802154_cc2520.h" - -/** - * Content is split as follows: - * 1 - Debug related functions - * 2 - Generic helper functions (for any parts) - * 3 - GPIO related functions - * 4 - TX related helper functions - * 5 - RX related helper functions - * 6 - Radio device API functions - * 7 - Legacy radio device API functions - * 8 - Initialization - */ - - -#if defined(CONFIG_TI_CC2520_AUTO_CRC) && defined(CONFIG_TI_CC2520_AUTO_ACK) -#define CC2520_AUTOMATISM (FRMCTRL0_AUTOCRC | FRMCTRL0_AUTOACK) -#elif defined(CONFIG_TI_CC2520_AUTO_CRC) -#define CC2520_AUTOMATISM (FRMCTRL0_AUTOCRC) -#else -#define CC2520_AUTOMATISM (0) -#endif - -#define CC2520_TX_THRESHOLD (0x7F) -#define CC2520_FCS_LENGTH (2) - -/********* - * DEBUG * - ********/ -#ifndef CONFIG_TI_CC2520_DEBUG -#define _cc2520_print_gpio_config(...) -#define _cc2520_print_exceptions(...) -#define _cc2520_print_errors(...) -#else -static inline void _cc2520_print_gpio_config(struct device *dev) -{ - struct cc2520_context *cc2520 = dev->driver_data; - - SYS_LOG_DBG("%s: GPIOCTRL0/1/2/3/4/5 = 0x%x/0x%x/0x%x/0x%x/0x%x/0x%x\n", - __func__, - read_reg_gpioctrl0(&cc2520->spi), - read_reg_gpioctrl1(&cc2520->spi), - read_reg_gpioctrl2(&cc2520->spi), - read_reg_gpioctrl3(&cc2520->spi), - read_reg_gpioctrl4(&cc2520->spi), - read_reg_gpioctrl5(&cc2520->spi)); - SYS_LOG_DBG("%s: GPIOPOLARITY: 0x%x\n", - __func__, read_reg_gpiopolarity(&cc2520->spi)); - SYS_LOG_DBG("%s: GPIOCTRL: 0x%x\n", - __func__, read_reg_gpioctrl(&cc2520->spi)); -} - -static inline void _cc2520_print_exceptions(struct cc2520_context *cc2520) -{ - uint8_t flag = read_reg_excflag0(&cc2520->spi); - - SYS_LOG_DBG("%s: EXCFLAG0: ", __func__); - if (flag & EXCFLAG0_RF_IDLE) { - SYS_LOG_DBG("RF_IDLE "); - } - if (flag & EXCFLAG0_TX_FRM_DONE) { - SYS_LOG_DBG("TX_FRM_DONE "); - } - if (flag & EXCFLAG0_TX_ACK_DONE) { - SYS_LOG_DBG("TX_ACK_DONE "); - } - if (flag & EXCFLAG0_TX_UNDERFLOW) { - SYS_LOG_DBG("TX_UNDERFLOW "); - } - if (flag & EXCFLAG0_TX_OVERFLOW) { - SYS_LOG_DBG("TX_OVERFLOW "); - } - if (flag & EXCFLAG0_RX_UNDERFLOW) { - SYS_LOG_DBG("RX_UNDERFLOW "); - } - if (flag & EXCFLAG0_RX_OVERFLOW) { - SYS_LOG_DBG("RX_OVERFLOW "); - } - if (flag & EXCFLAG0_RXENABLE_ZERO) { - SYS_LOG_DBG("RXENABLE_ZERO"); - } - SYS_LOG_DBG("\n"); - - flag = read_reg_excflag1(&cc2520->spi); - - SYS_LOG_DBG("%s: EXCFLAG1: ", __func__); - if (flag & EXCFLAG1_RX_FRM_DONE) { - SYS_LOG_DBG("RX_FRM_DONE "); - } - if (flag & EXCFLAG1_RX_FRM_ACCEPTED) { - SYS_LOG_DBG("RX_FRM_ACCEPTED "); - } - if (flag & EXCFLAG1_SRC_MATCH_DONE) { - SYS_LOG_DBG("SRC_MATCH_DONE "); - } - if (flag & EXCFLAG1_SRC_MATCH_FOUND) { - SYS_LOG_DBG("SRC_MATCH_FOUND "); - } - if (flag & EXCFLAG1_FIFOP) { - SYS_LOG_DBG("FIFOP "); - } - if (flag & EXCFLAG1_SFD) { - SYS_LOG_DBG("SFD "); - } - if (flag & EXCFLAG1_DPU_DONE_L) { - SYS_LOG_DBG("DPU_DONE_L "); - } - if (flag & EXCFLAG1_DPU_DONE_H) { - SYS_LOG_DBG("DPU_DONE_H"); - } - SYS_LOG_DBG("\n"); -} - -static inline void _cc2520_print_errors(struct cc2520_context *cc2520) -{ - uint8_t flag = read_reg_excflag2(&cc2520->spi); - - SYS_LOG_DBG("EXCFLAG2: "); - if (flag & EXCFLAG2_MEMADDR_ERROR) { - SYS_LOG_DBG("MEMADDR_ERROR "); - } - if (flag & EXCFLAG2_USAGE_ERROR) { - SYS_LOG_DBG("USAGE_ERROR "); - } - if (flag & EXCFLAG2_OPERAND_ERROR) { - SYS_LOG_DBG("OPERAND_ERROR "); - } - if (flag & EXCFLAG2_SPI_ERROR) { - SYS_LOG_DBG("SPI_ERROR "); - } - if (flag & EXCFLAG2_RF_NO_LOCK) { - SYS_LOG_DBG("RF_NO_LOCK "); - } - if (flag & EXCFLAG2_RX_FRM_ABORTED) { - SYS_LOG_DBG("RX_FRM_ABORTED "); - } - if (flag & EXCFLAG2_RFBUFMOV_TIMEOUT) { - SYS_LOG_DBG("RFBUFMOV_TIMEOUT"); - } - SYS_LOG_DBG("\n"); -} -#endif - - -/********************* - * Generic functions * - ********************/ -static void _usleep(uint32_t usec) -{ - static void (*func[3])(int32_t timeout_in_ticks) = { - NULL, - fiber_sleep, - task_sleep, - }; - - if (sys_execution_context_type_get() == 0) { - sys_thread_busy_wait(usec); - return; - } - - /* Timeout in ticks: */ - usec = USEC(usec); - /** Most likely usec will generate 0 ticks, - * so setting at least to 1 - */ - if (!usec) { - usec = 1; - } - - func[sys_execution_context_type_get()](usec); -} - -uint8_t _cc2520_read_reg(struct cc2520_spi *spi, - bool freg, uint8_t addr) -{ - uint8_t len = freg ? 2 : 3; - - spi->cmd_buf[0] = freg ? CC2520_INS_REGRD | addr : CC2520_INS_MEMRD; - spi->cmd_buf[1] = freg ? 0 : addr; - spi->cmd_buf[2] = 0; - - spi_slave_select(spi->dev, spi->slave); - - if (spi_transceive(spi->dev, spi->cmd_buf, len, - spi->cmd_buf, len) == 0) { - return spi->cmd_buf[len - 1]; - } - - return 0; -} - -bool _cc2520_write_reg(struct cc2520_spi *spi, bool freg, - uint8_t addr, uint8_t value) -{ - uint8_t len = freg ? 2 : 3; - - spi->cmd_buf[0] = freg ? CC2520_INS_REGWR | addr : CC2520_INS_MEMWR; - spi->cmd_buf[1] = freg ? value : addr; - spi->cmd_buf[2] = freg ? 0 : value; - - spi_slave_select(spi->dev, spi->slave); - - return (spi_write(spi->dev, spi->cmd_buf, len) == 0); -} - -bool _cc2520_write_ram(struct cc2520_spi *spi, uint16_t addr, - uint8_t *data_buf, uint8_t len) -{ - spi->cmd_buf[0] = CC2520_INS_MEMWR | (addr >> 8); - spi->cmd_buf[1] = addr; - - memcpy(&spi->cmd_buf[2], data_buf, len); - - spi_slave_select(spi->dev, spi->slave); - - return (spi_write(spi->dev, spi->cmd_buf, len + 2) == 0); -} - -static uint8_t _cc2520_status(struct cc2520_spi *spi) -{ - spi->cmd_buf[0] = CC2520_INS_SNOP; - - spi_slave_select(spi->dev, spi->slave); - - if (spi_transceive(spi->dev, spi->cmd_buf, 1, - spi->cmd_buf, 1) == 0) { - return spi->cmd_buf[0]; - } - - return 0; -} - -static bool verify_osc_stabilization(struct cc2520_context *cc2520) -{ - uint8_t timeout = 100; - uint8_t status; - - do { - status = _cc2520_status(&cc2520->spi); - _usleep(1); - timeout--; - } while (!(status & CC2520_STATUS_XOSC_STABLE_N_RUNNING) && timeout); - - return !!(status & CC2520_STATUS_XOSC_STABLE_N_RUNNING); -} - - -/****************** - * GPIO functions * - *****************/ -static inline void set_reset(struct device *dev, uint32_t value) -{ - struct cc2520_context *cc2520 = dev->driver_data; - - gpio_pin_write(cc2520->gpios[CC2520_GPIO_IDX_RESET], - CONFIG_CC2520_GPIO_RESET, value); -} - -static inline void set_vreg_en(struct device *dev, uint32_t value) -{ - struct cc2520_context *cc2520 = dev->driver_data; - - gpio_pin_write(cc2520->gpios[CC2520_GPIO_IDX_VREG_EN], - CONFIG_CC2520_GPIO_VREG_EN, value); -} - -static inline uint32_t get_fifo(struct cc2520_context *cc2520) -{ - uint32_t pin_value; - - gpio_pin_read(cc2520->gpios[CC2520_GPIO_IDX_FIFO], - CONFIG_CC2520_GPIO_FIFO, &pin_value); - - return pin_value; -} - -static inline uint32_t get_fifop(struct cc2520_context *cc2520) -{ - uint32_t pin_value; - - gpio_pin_read(cc2520->gpios[CC2520_GPIO_IDX_FIFOP], - CONFIG_CC2520_GPIO_FIFOP, &pin_value); - - return pin_value; -} - -static inline uint32_t get_cca(struct cc2520_context *cc2520) -{ - uint32_t pin_value; - - gpio_pin_read(cc2520->gpios[CC2520_GPIO_IDX_CCA], - CONFIG_CC2520_GPIO_CCA, &pin_value); - - return pin_value; -} - -static inline void sfd_int_handler(struct device *port, - struct gpio_callback *cb, uint32_t pins) -{ - struct cc2520_context *cc2520 = - CONTAINER_OF(cb, struct cc2520_context, sfd_cb); - - if (atomic_get(&cc2520->tx) == 1) { - atomic_set(&cc2520->tx, 0); - nano_isr_sem_give(&cc2520->tx_sync); - } -} - -static inline void fifop_int_handler(struct device *port, - struct gpio_callback *cb, uint32_t pins) -{ - struct cc2520_context *cc2520 = - CONTAINER_OF(cb, struct cc2520_context, fifop_cb); - - /* Note: Errata document - 1.2 */ - if (!get_fifop(cc2520) && !get_fifop(cc2520)) { - return; - } - - if (!get_fifo(cc2520)) { - cc2520->overflow = true; - } - - nano_isr_sem_give(&cc2520->rx_lock); -} - -static void enable_fifop_interrupt(struct cc2520_context *cc2520, - bool enable) -{ - if (enable) { - gpio_pin_enable_callback(cc2520->gpios[CC2520_GPIO_IDX_FIFOP], - CONFIG_CC2520_GPIO_FIFOP); - } else { - gpio_pin_disable_callback(cc2520->gpios[CC2520_GPIO_IDX_FIFOP], - CONFIG_CC2520_GPIO_FIFOP); - } -} - -static void enable_sfd_interrupt(struct cc2520_context *cc2520, - bool enable) -{ - if (enable) { - gpio_pin_enable_callback(cc2520->gpios[CC2520_GPIO_IDX_SFD], - CONFIG_CC2520_GPIO_SFD); - } else { - gpio_pin_disable_callback(cc2520->gpios[CC2520_GPIO_IDX_SFD], - CONFIG_CC2520_GPIO_SFD); - } -} - -static inline void setup_gpio_callbacks(struct device *dev) -{ - struct cc2520_context *cc2520 = dev->driver_data; - - gpio_init_callback(&cc2520->sfd_cb, - sfd_int_handler, BIT(CONFIG_CC2520_GPIO_SFD)); - gpio_add_callback(cc2520->gpios[CC2520_GPIO_IDX_SFD], - &cc2520->sfd_cb); - - gpio_init_callback(&cc2520->fifop_cb, - fifop_int_handler, BIT(CONFIG_CC2520_GPIO_FIFOP)); - gpio_add_callback(cc2520->gpios[CC2520_GPIO_IDX_FIFOP], - &cc2520->fifop_cb); -} - - -/**************** - * TX functions * - ***************/ -static inline bool write_txfifo_length(struct cc2520_spi *spi, - struct net_buf *buf) -{ - spi->cmd_buf[0] = CC2520_INS_TXBUF; - spi->cmd_buf[1] = packetbuf_totlen(buf) + CC2520_FCS_LENGTH; - - spi_slave_select(spi->dev, spi->slave); - - return (spi_write(spi->dev, spi->cmd_buf, 2) == 0); -} - -static inline bool write_txfifo_content(struct cc2520_spi *spi, - struct net_buf *buf) -{ - uint8_t cmd[128 + 1]; - - cmd[0] = CC2520_INS_TXBUF; - memcpy(&cmd[1], packetbuf_hdrptr(buf), packetbuf_totlen(buf)); - - spi_slave_select(spi->dev, spi->slave); - - return (spi_write(spi->dev, cmd, packetbuf_totlen(buf) + 1) == 0); -} - -static inline bool verify_txfifo_status(struct cc2520_context *cc2520, - struct net_buf *buf) -{ - if (read_reg_txfifocnt(&cc2520->spi) < (packetbuf_totlen(buf) + 1) || - (read_reg_excflag0(&cc2520->spi) & EXCFLAG0_TX_UNDERFLOW)) { - return false; - } - - return true; -} - -static inline bool verify_tx_done(struct cc2520_context *cc2520) -{ - uint8_t timeout = 10; - uint8_t status; - - do { - _usleep(1); - timeout--; - status = read_reg_excflag0(&cc2520->spi); - } while (!(status & EXCFLAG0_TX_FRM_DONE) && timeout); - - return !!(status & EXCFLAG0_TX_FRM_DONE); -} - -static inline void enable_reception(struct cc2520_context *cc2520) -{ - /* Note: Errata document - 1.1 */ - enable_fifop_interrupt(cc2520, false); - - instruct_srxon(&cc2520->spi); - instruct_sflushrx(&cc2520->spi); - instruct_sflushrx(&cc2520->spi); - - enable_fifop_interrupt(cc2520, true); - - write_reg_excflag0(&cc2520->spi, EXCFLAG0_RESET_RX_FLAGS); -} - -/**************** - * RX functions * - ***************/ - -static inline void flush_rxfifo(struct cc2520_context *cc2520) -{ - /* Note: Errata document - 1.1 */ - enable_fifop_interrupt(cc2520, false); - - instruct_sflushrx(&cc2520->spi); - instruct_sflushrx(&cc2520->spi); - - enable_fifop_interrupt(cc2520, true); - - write_reg_excflag0(&cc2520->spi, EXCFLAG0_RESET_RX_FLAGS); -} - -#ifdef CONFIG_SPI_QMSI -/** This is a workaround, for SPI QMSI drivers as current QMSI API does not - * support asymmetric tx/rx buffer lengths. - * (i.e.: it's up to the user to handle tx dummy bytes in tx buffer) - */ -static inline uint8_t read_rxfifo_length(struct cc2520_spi *spi) -{ - spi->cmd_buf[0] = CC2520_INS_RXBUF; - spi->cmd_buf[1] = 0; - - spi_slave_select(spi->dev, spi->slave); - - if (spi_transceive(spi->dev, spi->cmd_buf, 2, - spi->cmd_buf, 2) == 0) { - return spi->cmd_buf[1]; - } - - return 0; -} - -static inline bool read_rxfifo_content(struct cc2520_spi *spi, - struct net_buf *buf, uint8_t len) -{ - uint8_t data[128+1]; - - data[0] = CC2520_INS_RXBUF; - memset(&data[1], 0, len); - - spi_slave_select(spi->dev, spi->slave); - - if (spi_transceive(spi->dev, data, len+1, data, len+1) != 0) { - return false; - } - - if (read_reg_excflag0(spi) & EXCFLAG0_RX_UNDERFLOW) { - return false; - } - - memcpy(packetbuf_dataptr(buf), &data[1], len); - packetbuf_set_datalen(buf, len); - - return true; -} - -static inline bool read_rxfifo_footer(struct cc2520_spi *spi, uint8_t *buf) -{ - spi->cmd_buf[0] = CC2520_INS_RXBUF; - memset(&spi->cmd_buf[1], 0, CC2520_FCS_LENGTH); - - spi_slave_select(spi->dev, spi->slave); - - if (spi_transceive(spi->dev, spi->cmd_buf, CC2520_FCS_LENGTH+1, - spi->cmd_buf, CC2520_FCS_LENGTH+1) != 0) { - return false; - } - - memcpy(buf, &spi->cmd_buf[1], CC2520_FCS_LENGTH); - - return true; -} -#else /* CONFIG_SPI_QMSI */ -static inline uint8_t read_rxfifo_length(struct cc2520_spi *spi) -{ - spi->cmd_buf[0] = CC2520_INS_RXBUF; - - spi_slave_select(spi->dev, spi->slave); - - if (spi_transceive(spi->dev, spi->cmd_buf, 1, - spi->cmd_buf, 2) == 0) { - return spi->cmd_buf[1]; - } - - return 0; -} - -static inline bool read_rxfifo_content(struct cc2520_spi *spi, - struct net_buf *buf, uint8_t len) -{ - uint8_t data[128+1]; - - spi->cmd_buf[0] = CC2520_INS_RXBUF; - - spi_slave_select(spi->dev, spi->slave); - - if (spi_transceive(spi->dev, spi->cmd_buf, 1, data, len+1) != 0) { - return false; - } - - if (read_reg_excflag0(spi) & EXCFLAG0_RX_UNDERFLOW) { - return false; - } - - memcpy(packetbuf_dataptr(buf), &data[1], len); - packetbuf_set_datalen(buf, len); - - return true; -} - -static inline bool read_rxfifo_footer(struct cc2520_spi *spi, uint8_t *buf) -{ - spi->cmd_buf[0] = CC2520_INS_RXBUF; - - spi_slave_select(spi->dev, spi->slave); - - if (spi_transceive(spi->dev, spi->cmd_buf, 1, - spi->cmd_buf, CC2520_FCS_LENGTH+1) != 0) { - return false; - } - - memcpy(buf, &spi->cmd_buf[1], CC2520_FCS_LENGTH); - - return true; -} -#endif /* CONFIG_SPI_QMSI */ - -static inline bool verify_rxfifo_validity(struct cc2520_spi *spi, - uint8_t pkt_len) -{ - if (pkt_len < 2 || read_reg_rxfifocnt(spi) != pkt_len) { - return false; - } - - return true; -} - -static void cc2520_rx(int arg, int unused2) -{ - struct device *dev = INT_TO_POINTER(arg); - struct cc2520_context *cc2520 = dev->driver_data; - struct net_buf *pkt_buf = NULL; - uint8_t pkt_len; -#ifdef CONFIG_TI_CC2520_AUTO_CRC - uint8_t buf[CC2520_FCS_LENGTH]; -#endif - - ARG_UNUSED(unused2); - - while (1) { - nano_fiber_sem_take(&cc2520->rx_lock, TICKS_UNLIMITED); - - if (cc2520->overflow) { - SYS_LOG_DBG("RX overflow!\n"); - cc2520->overflow = false; - goto flush; - } - - pkt_len = read_rxfifo_length(&cc2520->spi) & 0x7f; - if (!verify_rxfifo_validity(&cc2520->spi, pkt_len)) { - SYS_LOG_DBG("Invalid content\n"); - goto flush; - } - - pkt_buf = l2_buf_get_reserve(0); - if (!pkt_buf) { - SYS_LOG_DBG("No pkt buf available\n"); - goto flush; - } - - if (!read_rxfifo_content(&cc2520->spi, pkt_buf, - pkt_len - CC2520_FCS_LENGTH)) { - SYS_LOG_DBG("No content read\n"); - goto error; - } -#ifdef CONFIG_TI_CC2520_AUTO_CRC - if (!read_rxfifo_footer(&cc2520->spi, buf)) { - SYS_LOG_DBG("No footer read\n"); - goto error; - } - - if (!(buf[1] & CC2520_FCS_CRC_OK)) { - SYS_LOG_DBG("Bad packet CRC\n"); - goto error; - } -#ifdef CONFIG_TI_CC2520_LINK_DETAILS - packetbuf_set_attr(pkt_buf, PACKETBUF_ATTR_RSSI, - buf[0]); - packetbuf_set_attr(pkt_buf, PACKETBUF_ATTR_LINK_QUALITY, - buf[1] & CC2520_FCS_CORRELATION); -#endif /* CONFIG_TI_CC2520_LINK_DETAILS */ -#endif /* CONFIG_TI_CC2520_AUTO_CRC */ - - SYS_LOG_DBG("Caught a packet (%u)\n", pkt_len - CC2520_FCS_LENGTH); - - if (net_driver_15_4_recv_from_hw(pkt_buf) < 0) { - SYS_LOG_DBG("Packet dropped by NET stack\n"); - goto error; - } - - net_analyze_stack("CC2520 Rx Fiber stack", - cc2520->cc2520_rx_stack, - CONFIG_CC2520_RX_STACK_SIZE); - goto flush; -error: - l2_buf_unref(pkt_buf); -flush: - flush_rxfifo(cc2520); - } -} - - -/******************** - * Radio device API * - *******************/ -static inline int cc2520_set_channel(struct device *dev, uint16_t channel) -{ - struct cc2520_context *cc2520 = dev->driver_data; - - SYS_LOG_DBG("%s: %u\n", __func__, channel); - - if (channel < 11 || channel > 26) { - return -EINVAL; - } - - /* See chapter 16 */ - channel = 11 + 5 * (channel - 11); - - if (!write_reg_freqctrl(&cc2520->spi, FREQCTRL_FREQ(channel))) { - SYS_LOG_DBG("%s: FAILED\n", __func__); - return -EIO; - } - - return 0; -} - -static inline int cc2520_set_pan_id(struct device *dev, uint16_t pan_id) -{ - struct cc2520_context *cc2520 = dev->driver_data; - - SYS_LOG_DBG("%s: 0x%x\n", __func__, pan_id); - - pan_id = sys_le16_to_cpu(pan_id); - - if (!write_mem_pan_id(&cc2520->spi, (uint8_t *) &pan_id)) { - SYS_LOG_DBG("%s: FAILED\n", __func__); - return -EIO; - } - - return 0; -} - -static inline int cc2520_set_short_addr(struct device *dev, uint16_t short_addr) -{ - struct cc2520_context *cc2520 = dev->driver_data; - - SYS_LOG_DBG("%s: 0x%x\n", __func__, short_addr); - - short_addr = sys_le16_to_cpu(short_addr); - - if (!write_mem_short_addr(&cc2520->spi, (uint8_t *) &short_addr)) { - SYS_LOG_DBG("%s: FAILED\n", __func__); - return -EIO; - } - - return 0; -} - -static inline int cc2520_set_ieee_addr(struct device *dev, - const uint8_t *ieee_addr) -{ - struct cc2520_context *cc2520 = dev->driver_data; - uint8_t ext_addr[8]; - int idx; - - for (idx = 0; idx < 8; idx++) { - ext_addr[idx] = ieee_addr[7 - idx]; - } - - if (!write_mem_ext_addr(&cc2520->spi, ext_addr)) { - SYS_LOG_DBG("%s: FAILED\n", __func__); - return -EIO; - } - - SYS_LOG_DBG("%s: IEEE address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - __func__, - ieee_addr[0], ieee_addr[1], ieee_addr[2], ieee_addr[3], - ieee_addr[4], ieee_addr[5], ieee_addr[6], ieee_addr[7]); - - return 0; -} - -static inline int cc2520_tx(struct device *dev, struct net_buf *buf) -{ - struct cc2520_context *cc2520 = dev->driver_data; - uint8_t retry = 2; - bool status; - - SYS_LOG_DBG("%s: %p (%u)\n", __func__, buf, packetbuf_totlen(buf)); - - if (!write_reg_excflag0(&cc2520->spi, EXCFLAG0_RESET_TX_FLAGS) || - !write_txfifo_length(&cc2520->spi, buf) || - !write_txfifo_content(&cc2520->spi, buf)) { - SYS_LOG_DBG("%s: Cannot feed in TX fifo\n", __func__); - goto error; - } - - if (!verify_txfifo_status(cc2520, buf)) { - SYS_LOG_DBG("%s: Did not write properly into TX FIFO\n", __func__); - goto error; - } - - /* 1 retry is allowed here */ - do { - atomic_set(&cc2520->tx, 1); - nano_sem_init(&cc2520->tx_sync); - - if (!instruct_stxoncca(&cc2520->spi)) { - SYS_LOG_DBG("%s: Cannot start transmission\n", __func__); - goto error; - } - - /* _cc2520_print_exceptions(cc2520); */ - nano_sem_take(&cc2520->tx_sync, MSEC(10)); - - retry--; - status = verify_tx_done(cc2520); - } while (!status && retry); - - if (!status) { - SYS_LOG_DBG("%s: No TX_FRM_DONE\n", __func__); - goto error; - } - - enable_reception(cc2520); - - return 0; -error: - atomic_set(&cc2520->tx, 0); - instruct_sflushtx(&cc2520->spi); - enable_reception(cc2520); - - return -EIO; -} - -static inline uint8_t *cc2520_get_mac(struct device *dev) -{ - struct cc2520_context *cc2520 = dev->driver_data; - - if (cc2520->mac_addr[1] == 0x00) { - /* TI OUI */ - cc2520->mac_addr[0] = 0x00; - cc2520->mac_addr[1] = 0x12; - cc2520->mac_addr[2] = 0x4b; - - cc2520->mac_addr[3] = 0x00; - UNALIGNED_PUT(sys_cpu_to_be32(sys_rand32_get()), - (uint32_t *) ((void *)cc2520->mac_addr+4)); - - cc2520->mac_addr[7] = (cc2520->mac_addr[7] & ~0x01) | 0x02; - } - - return cc2520->mac_addr; -} - -static inline int cc2520_start(struct device *dev) -{ - struct cc2520_context *cc2520 = dev->driver_data; - - SYS_LOG_DBG("%s\n", __func__); - - if (!instruct_sxoscon(&cc2520->spi) || - !instruct_srxon(&cc2520->spi) || - !verify_osc_stabilization(cc2520)) { - return -EIO; - } - - flush_rxfifo(cc2520); - - enable_fifop_interrupt(cc2520, true); - enable_sfd_interrupt(cc2520, true); - - return 0; -} - -static inline int cc2520_stop(struct device *dev) -{ - struct cc2520_context *cc2520 = dev->driver_data; - - SYS_LOG_DBG("%s\n", __func__); - - enable_fifop_interrupt(cc2520, false); - enable_sfd_interrupt(cc2520, false); - - if (!instruct_srfoff(&cc2520->spi) || - !instruct_sxoscoff(&cc2520->spi)) { - return -EIO; - } - - flush_rxfifo(cc2520); - - return 0; -} - - -/*************************** - * Legacy Radio device API * - **************************/ -/** - * NOTE: This legacy API DOES NOT FIT within Zephyr device driver model - * and, as such, will be made obsolete soon (well, hopefully...) - */ - -static int cc2520_initialize(void) -{ - const uint8_t *mac = cc2520_get_mac(cc2520_sglt); - uint16_t short_addr; - - /** That is not great either, basically ieee802154/net stack, - * should get the mac, then set what's relevant. It's not up - * to the driver to do such thing. - */ - net_set_mac((uint8_t *)mac, 8); - - /* Setting short address... */ - short_addr = (mac[0] << 8) + mac[1]; - cc2520_set_short_addr(cc2520_sglt, short_addr); - - /* ... And ieee address */ - cc2520_set_ieee_addr(cc2520_sglt, mac); - - return 1; -} - -static int cc2520_prepare(const void *payload, unsigned short payload_len) -{ - return 0; -} - -static int cc2520_transmit(struct net_buf *buf, unsigned short transmit_len) -{ - if (cc2520_tx(cc2520_sglt, buf) != 0) { - return RADIO_TX_ERR; - } - - return RADIO_TX_OK; -} - -static int cc2520_send(struct net_buf *buf, - const void *payload, unsigned short payload_len) -{ - return cc2520_transmit(buf, payload_len); -} - -static int cc2520_read(void *buf, unsigned short buf_len) -{ - return 0; -} - -static int cc2520_channel_clear(void) -{ - struct cc2520_context *cc2520 = cc2520_sglt->driver_data; - - return get_cca(cc2520); -} - -static int cc2520_receiving_packet(void) -{ - return 0; -} - -static int cc2520_pending_packet(void) -{ - return 0; -} - -static int cc2520_on(void) -{ - return (cc2520_start(cc2520_sglt) == 0); -} - -static int cc2520_off(void) -{ - return (cc2520_stop(cc2520_sglt) == 0); -} - -static radio_result_t cc2520_get_value(radio_param_t param, - radio_value_t *value) -{ - switch (param) { - case RADIO_PARAM_POWER_MODE: - *value = RADIO_POWER_MODE_ON; - break; - case RADIO_PARAM_CHANNEL: - *value = CONFIG_TI_CC2520_CHANNEL; - break; - case RADIO_CONST_CHANNEL_MIN: - *value = 11; - break; - case RADIO_CONST_CHANNEL_MAX: - *value = 26; - break; - default: - return RADIO_RESULT_NOT_SUPPORTED; - } - - return RADIO_RESULT_OK; -} - -static radio_result_t cc2520_set_value(radio_param_t param, - radio_value_t value) -{ - switch (param) { - case RADIO_PARAM_POWER_MODE: - break; - case RADIO_PARAM_CHANNEL: - cc2520_set_channel(cc2520_sglt, value); - break; - case RADIO_PARAM_PAN_ID: - cc2520_set_pan_id(cc2520_sglt, value); - break; - case RADIO_PARAM_RX_MODE: - default: - return RADIO_RESULT_NOT_SUPPORTED; - } - - return RADIO_RESULT_OK; -} - -static radio_result_t cc2520_get_object(radio_param_t param, - void *dest, size_t size) -{ - return RADIO_RESULT_NOT_SUPPORTED; -} - -static radio_result_t cc2520_set_object(radio_param_t param, - const void *src, size_t size) -{ - return RADIO_RESULT_NOT_SUPPORTED; -} - -struct radio_driver cc2520_15_4_radio_driver = { - .init = cc2520_initialize, - .prepare = cc2520_prepare, - .transmit = cc2520_transmit, - .send = cc2520_send, - .read = cc2520_read, - .channel_clear = cc2520_channel_clear, - .receiving_packet = cc2520_receiving_packet, - .pending_packet = cc2520_pending_packet, - .on = cc2520_on, - .off = cc2520_off, - .get_value = cc2520_get_value, - .set_value = cc2520_set_value, - .get_object = cc2520_get_object, - .set_object = cc2520_set_object, -}; - -/****************** - * Initialization * - *****************/ -static int power_on_and_setup(struct device *dev) -{ - struct cc2520_context *cc2520 = dev->driver_data; - - /* Switching to LPM2 mode */ - set_reset(dev, 0); - _usleep(150); - - set_vreg_en(dev, 0); - _usleep(250); - - /* Then to ACTIVE mode */ - set_vreg_en(dev, 1); - _usleep(250); - - set_reset(dev, 1); - _usleep(150); - - if (!verify_osc_stabilization(cc2520)) { - return -EIO; - } - - /* Default settings to always write (see chapter 28 part 1) */ - if (!write_reg_txpower(&cc2520->spi, CC2520_TXPOWER_DEFAULT) || - !write_reg_ccactrl0(&cc2520->spi, CC2520_CCACTRL0_DEFAULT) || - !write_reg_mdmctrl0(&cc2520->spi, CC2520_MDMCTRL0_DEFAULT) || - !write_reg_mdmctrl1(&cc2520->spi, CC2520_MDMCTRL1_DEFAULT) || - !write_reg_rxctrl(&cc2520->spi, CC2520_RXCTRL_DEFAULT) || - !write_reg_fsctrl(&cc2520->spi, CC2520_FSCTRL_DEFAULT) || - !write_reg_fscal1(&cc2520->spi, CC2520_FSCAL1_DEFAULT) || - !write_reg_agcctrl1(&cc2520->spi, CC2520_AGCCTRL1_DEFAULT) || - !write_reg_adctest0(&cc2520->spi, CC2520_ADCTEST0_DEFAULT) || - !write_reg_adctest1(&cc2520->spi, CC2520_ADCTEST1_DEFAULT) || - !write_reg_adctest2(&cc2520->spi, CC2520_ADCTEST2_DEFAULT)) { - return -EIO; - } - - /* EXTCLOCK0: Disabling external clock - * FRMCTRL0: AUTOACK and AUTOCRC enabled - * FRMCTRL1: SET_RXENMASK_ON_TX and IGNORE_TX_UNDERF - * FRMFILT0: Frame filtering (setting CC2520_FRAME_FILTERING) - * FIFOPCTRL: Set TX threshold (setting CC2520_TX_THRESHOLD) - */ - if (!write_reg_extclock(&cc2520->spi, 0) || - !write_reg_frmctrl0(&cc2520->spi, CC2520_AUTOMATISM) || - !write_reg_frmctrl1(&cc2520->spi, FRMCTRL1_IGNORE_TX_UNDERF | - FRMCTRL1_SET_RXENMASK_ON_TX) || - !write_reg_frmfilt0(&cc2520->spi, FRMFILT0_FRAME_FILTER_EN | - FRMFILT0_MAX_FRAME_VERSION(3)) || - !write_reg_frmfilt1(&cc2520->spi, FRMFILT1_ACCEPT_ALL) || - !write_reg_srcmatch(&cc2520->spi, SRCMATCH_DEFAULTS) || - !write_reg_fifopctrl(&cc2520->spi, - FIFOPCTRL_FIFOP_THR(CC2520_TX_THRESHOLD))) { - return -EIO; - } - - /* Cleaning up TX fifo */ - instruct_sflushtx(&cc2520->spi); - - setup_gpio_callbacks(dev); - - _cc2520_print_gpio_config(dev); - - return 0; -} - -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, - }; - - cc2520->spi.dev = device_get_binding(CONFIG_TI_CC2520_SPI_DRV_NAME); - if (cc2520->spi.dev) { - cc2520->spi.slave = CONFIG_TI_CC2520_SPI_SLAVE; - - if (spi_configure(cc2520->spi.dev, &spi_conf) != 0 || - spi_slave_select(cc2520->spi.dev, - cc2520->spi.slave) != 0) { - cc2520->spi.dev = NULL; - return -EIO; - } - } - - return 0; -} - -int cc2520_init(struct device *dev) -{ - struct cc2520_context *cc2520 = dev->driver_data; - - dev->driver_api = NULL; - - atomic_set(&cc2520->tx, 0); - nano_sem_init(&cc2520->rx_lock); - - cc2520->gpios = cc2520_configure_gpios(); - if (!cc2520->gpios) { - SYS_LOG_DBG("Configuring GPIOS failed\n"); - return -EIO; - } - - if (configure_spi(dev) != 0) { - SYS_LOG_DBG("Configuring SPI failed\n"); - return -EIO; - } - - SYS_LOG_DBG("GPIO and SPI configured\n"); - - if (power_on_and_setup(dev) != 0) { - SYS_LOG_DBG("Configuring CC2520 failed\n"); - return -EIO; - } - - /* That should not be done here... */ - if (cc2520_set_pan_id(dev, 0xFFFF) != 0 || - cc2520_set_short_addr(dev, 0x0000) != 0 || - cc2520_set_channel(dev, CONFIG_TI_CC2520_CHANNEL) != 0) { - SYS_LOG_DBG("Could not initialize properly cc2520\n"); - return -EIO; - } - - task_fiber_start(cc2520->cc2520_rx_stack, - CONFIG_CC2520_RX_STACK_SIZE, - cc2520_rx, POINTER_TO_INT(dev), - 0, 0, 0); - - cc2520_sglt = dev; - - return 0; -} - -struct cc2520_context cc2520_context_data; - -DEVICE_INIT(cc2520, CONFIG_TI_CC2520_DRV_NAME, - cc2520_init, &cc2520_context_data, NULL, - APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/include/net/ip_buf.h b/include/net/ip_buf.h deleted file mode 100644 index 7ea14cedc8a6cbf5be005168dc6927885dcf1c7c..0000000000000000000000000000000000000000 --- a/include/net/ip_buf.h +++ /dev/null @@ -1,402 +0,0 @@ -/** @file - * @brief IP buffer API - * - * IP data is passed between application and IP stack via a ip_buf struct. - */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* Data buffer API - used for all data to/from net */ - -#ifndef __IP_BUF_H -#define __IP_BUF_H - -#include -#include - -#include - -#include "contiki/ip/uipopt.h" -#include "contiki/ip/uip.h" -#include "contiki/packetbuf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef CONFIG_NETWORKING_WITH_LOGGING -#undef DEBUG_IP_BUFS -#define DEBUG_IP_BUFS -#endif - -#ifdef DEBUG_IP_BUFS -#define NET_BUF_CHECK_IF_IN_USE(buf) \ - do { \ - if (buf->ref) { \ - NET_ERR("**ERROR** buf %p in use (%s:%s():%d)\n", \ - buf, __FILE__, __func__, __LINE__); \ - } \ - } while (0) - -#define NET_BUF_CHECK_IF_NOT_IN_USE(buf) \ - do { \ - if (!buf->ref) { \ - NET_ERR("**ERROR** buf %p not in use (%s:%s():%d)\n",\ - buf, __FILE__, __func__, __LINE__); \ - } \ - } while (0) -#else -#define NET_BUF_CHECK_IF_IN_USE(buf) -#define NET_BUF_CHECK_IF_NOT_IN_USE(buf) -#endif - -struct net_context; - -/** @cond ignore */ -enum ip_buf_type { - IP_BUF_RX = 0, - IP_BUF_TX = 1, -}; -/** @endcond */ - -/** The default MTU is 1280 (minimum IPv6 packet size) + LL header - * In Contiki terms this is UIP_LINK_MTU + UIP_LLH_LEN = UIP_BUFSIZE - * - * Contiki assumes that this value is UIP_BUFSIZE so do not change it - * without changing the value of UIP_BUFSIZE! - */ -#define IP_BUF_MAX_DATA UIP_BUFSIZE - -struct ip_buf { - /** @cond ignore */ - enum ip_buf_type type; - uint16_t reserve; /* length of the protocol headers */ - /* @endcond */ - - /** Network connection context */ - struct net_context *context; - - /** @cond ignore */ - /* uIP stack specific data */ - uint16_t len; /* Contiki will set this to 0 if packet is discarded */ - uint8_t uip_ext_len; - uint8_t uip_ext_bitmap; - uint8_t uip_ext_opt_offset; - uint8_t uip_flags; - uint16_t uip_slen; - uint16_t uip_appdatalen; - uint8_t *uip_next_hdr; - void *uip_appdata; /* application data */ - void *uip_sappdata; /* app data to be sent */ - void *uip_conn; - void *uip_udp_conn; - linkaddr_t dest; - linkaddr_t src; -#if defined(CONFIG_NETWORKING_WITH_TCP) - int8_t sent_status; /* tells if the TCP packet was sent ok or not */ - uint8_t tcp_retry_count; -#endif - - /* Neighbor discovery vars. Note that we are using void pointers here - * so that we do not need to include Contiki headers in this file. - */ - void *nd6_opt_prefix_info; - void *nd6_prefix; - void *nd6_nbr; - void *nd6_defrt; - void *nd6_ifaddr; - uint8_t *nd6_opt_llao; - uip_ipaddr_t ipaddr; - uint8_t nd6_opt_offset; - - /* 6lowpan specific vars */ - uint8_t compressed_hdr_len; - uint8_t uncompressed_hdr_len; - uint8_t first_frag_len; - uint8_t uncompressed; - /* @endcond */ -}; - -/** @cond ignore */ -/* Value returned by ip_buf_len() contains length of all the protocol headers, - * like IP and UDP, and the length of the user payload. - */ -#define ip_buf_len(buf) ((buf)->len) - -/* Macros to access net_buf when inside Contiki stack */ -#define uip_buf(buf) ((buf)->data) -#define uip_len(buf) (((struct ip_buf *)net_buf_user_data((buf)))->len) -#define uip_slen(buf) (((struct ip_buf *)net_buf_user_data((buf)))->uip_slen) -#define uip_ext_len(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->uip_ext_len) -#define uip_ext_bitmap(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->uip_ext_bitmap) -#define uip_ext_opt_offset(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->uip_ext_opt_offset) -#define uip_nd6_opt_offset(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->nd6_opt_offset) -#define uip_next_hdr(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->uip_next_hdr) -#define uip_appdata(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->uip_appdata) -#define uip_appdatalen(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->uip_appdatalen) -#define uip_sappdata(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->uip_sappdata) -#define uip_flags(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->uip_flags) -#define uip_conn(buf) \ - ((struct uip_conn *) \ - (((struct ip_buf *)net_buf_user_data((buf)))->uip_conn)) -#define uip_set_conn(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->uip_conn) -#define uip_udp_conn(buf) \ - ((struct uip_udp_conn *) \ - (((struct ip_buf *)net_buf_user_data((buf)))->uip_udp_conn)) -#define uip_set_udp_conn(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->uip_udp_conn) -#define uip_nd6_opt_prefix_info(buf) \ - ((uip_nd6_opt_prefix_info *) \ - (((struct ip_buf *)net_buf_user_data((buf)))->nd6_opt_prefix_info)) -#define uip_set_nd6_opt_prefix_info(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->nd6_opt_prefix_info) -#define uip_prefix(buf) \ - ((uip_ds6_prefix_t *) \ - (((struct ip_buf *)net_buf_user_data((buf)))->nd6_prefix)) -#define uip_set_prefix(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->nd6_prefix) -#define uip_nbr(buf) \ - ((uip_ds6_nbr_t *) \ - (((struct ip_buf *)net_buf_user_data((buf)))->nd6_nbr)) -#define uip_set_nbr(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->nd6_nbr) -#define uip_defrt(buf) \ - ((uip_ds6_defrt_t *) \ - (((struct ip_buf *)net_buf_user_data((buf)))->nd6_defrt)) -#define uip_set_defrt(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->nd6_defrt) -#define uip_addr(buf) \ - ((uip_ds6_addr_t *) \ - (((struct ip_buf *)net_buf_user_data((buf)))->nd6_ifaddr)) -#define uip_set_addr(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->nd6_ifaddr) -#define uip_nd6_opt_llao(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->nd6_opt_llao) -#define uip_set_nd6_opt_llao(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->nd6_opt_llao) -#define uip_nd6_ipaddr(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->ipaddr) -#define uip_compressed_hdr_len(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->compressed_hdr_len) -#define uip_uncompressed_hdr_len(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->uncompressed_hdr_len) -#define uip_first_frag_len(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->first_frag_len) -#define uip_uncompressed(buf) \ - (((struct ip_buf *)net_buf_user_data((buf)))->uncompressed) - -/* These two return only the application data and length without - * IP and UDP header length. - */ -#define ip_buf_appdata(buf) uip_appdata(buf) -#define ip_buf_appdatalen(buf) uip_appdatalen(buf) -#define ip_buf_reserve(buf) (((struct ip_buf *) \ - net_buf_user_data((buf)))->reserve) - -#define ip_buf_ll_src(buf) (((struct ip_buf *)net_buf_user_data((buf)))->src) -#define ip_buf_ll_dest(buf) (((struct ip_buf *)net_buf_user_data((buf)))->dest) -#define ip_buf_context(buf) (((struct ip_buf *)net_buf_user_data((buf)))->context) -#define ip_buf_type(ptr) (((struct ip_buf *)net_buf_user_data((ptr)))->type) -#define ip_buf_sent_status(ptr) (((struct ip_buf *)net_buf_user_data((ptr)))->sent_status) -#define ip_buf_tcp_retry_count(ptr) (((struct ip_buf *)net_buf_user_data((ptr)))->tcp_retry_count) -/* @endcond */ - -/** NET_BUF_IP - * - * @brief This macro returns IP header information struct stored in net_buf. - * - * @details The macro returns pointer to uip_ip_hdr struct which - * contains IP header information. - * - * @param buf Network buffer. - * - * @return Pointer to uip_ip_hdr. - */ -#define NET_BUF_IP(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) - -/** NET_BUF_UDP - * - * @brief This macro returns UDP header information struct stored in net_buf. - * - * @details The macro returns pointer to uip_udp_hdr struct which - * contains UDP header information. - * - * @param buf Network buffer. - * - * @return Pointer to uip_ip_hdr. - */ -#define NET_BUF_UDP(buf) ((struct uip_udp_hdr *)&uip_buf(buf)[UIP_LLIPH_LEN]) - -/** - * @brief Get buffer from the available buffers pool. - * - * @details Get network buffer from buffer pool. You must have - * network context before able to use this function. - * - * @param context Network context that will be related to - * this buffer. - * - * @return Network buffer if successful, NULL otherwise. - */ -/* Get buffer from the available buffers pool */ -#ifdef DEBUG_IP_BUFS -#define ip_buf_get_rx(context) ip_buf_get_rx_debug(context, __func__, __LINE__) -#define ip_buf_get_tx(context) ip_buf_get_tx_debug(context, __func__, __LINE__) -struct net_buf *ip_buf_get_rx_debug(struct net_context *context, - const char *caller, int line); -struct net_buf *ip_buf_get_tx_debug(struct net_context *context, - const char *caller, int line); -#else -struct net_buf *ip_buf_get_rx(struct net_context *context); -struct net_buf *ip_buf_get_tx(struct net_context *context); -#endif - -/** - * @brief Get buffer from pool but also reserve headroom for - * potential headers. - * - * @details Normally this version is not useful for applications - * but is mainly used by network fragmentation code. - * - * @param reserve_head How many bytes to reserve for headroom. - * - * @return Network buffer if successful, NULL otherwise. - */ -/* Same as net_buf_get, but also reserve headroom for potential headers */ -#ifdef DEBUG_IP_BUFS -#define ip_buf_get_reserve_rx(res) ip_buf_get_reserve_rx_debug(res, \ - __func__, \ - __LINE__) -#define ip_buf_get_reserve_tx(res) ip_buf_get_reserve_tx_debug(res, \ - __func__, \ - __LINE__) -struct net_buf *ip_buf_get_reserve_rx_debug(uint16_t reserve_head, - const char *caller, int line); -struct net_buf *ip_buf_get_reserve_tx_debug(uint16_t reserve_head, - const char *caller, int line); -#else -struct net_buf *ip_buf_get_reserve_rx(uint16_t reserve_head); -struct net_buf *ip_buf_get_reserve_tx(uint16_t reserve_head); -#endif - -/** - * @brief Place buffer back into the available buffers pool. - * - * @details Releases the buffer to other use. This needs to be - * called by application after it has finished with - * the buffer. - * - * @param buf Network buffer to release. - * - */ -#ifdef DEBUG_IP_BUFS -#define ip_buf_unref(buf) ip_buf_unref_debug(buf, __func__, __LINE__) -void ip_buf_unref_debug(struct net_buf *buf, const char *caller, int line); -#else -void ip_buf_unref(struct net_buf *buf); -#endif - -/** - * @brief Increase the ref count - * - * @details Mark the buffer to be used still. - * - * @param buf Network buffer to ref. - * - * @return Network buffer if successful, NULL otherwise. - */ -#ifdef DEBUG_IP_BUFS -#define ip_buf_ref(buf) ip_buf_ref_debug(buf, __func__, __LINE__) -struct net_buf *ip_buf_ref_debug(struct net_buf *buf, const char *caller, int line); -#else -struct net_buf *ip_buf_ref(struct net_buf *buf); -#endif - -/** @cond ignore */ -void ip_buf_init(void); -/* @endcond */ - -/** @cond ignore */ -#if defined(CONFIG_INIT_STACKS) && defined(CONFIG_PRINTK) -#include -#include - -static inline void net_analyze_stack(const char *name, - unsigned char *stack, - size_t size) -{ - unsigned i, stack_offset, pcnt, unused = 0; - - /* The TCS is always placed on a 4-byte aligned boundary - if - * the stack beginning doesn't match that there will be some - * unused bytes in the beginning. - */ - stack_offset = K_THREAD_SIZEOF + ((4 - ((unsigned)stack % 4)) % 4); - -/* TODO - * Currently all supported platforms have stack growth down and there is no - * Kconfig option to configure it so this always build "else" branch. - * When support for platform with stack direction up (or configurable direction) - * is added this check should be confirmed that correct Kconfig option is used. - */ -#if defined(CONFIG_STACK_GROWS_UP) - for (i = size - 1; i >= stack_offset; i--) { - if ((unsigned char)stack[i] == 0xaa) { - unused++; - } else { - break; - } - } -#else - for (i = stack_offset; i < size; i++) { - if ((unsigned char)stack[i] == 0xaa) { - unused++; - } else { - break; - } - } -#endif - - /* Calculate the real size reserved for the stack */ - size -= stack_offset; - pcnt = ((size - unused) * 100) / size; - - printk("net (%p): %s stack real size %zu " - "unused %u usage %zu/%zu (%u %%)\n", - sys_thread_self_get(), name, size + stack_offset, - unused, size - unused, size, pcnt); -} -#else -#define net_analyze_stack(...) -#endif -/* @endcond */ - -#ifdef __cplusplus -} -#endif - -#endif /* __IP_BUF_H */ diff --git a/include/net/l2_buf.h b/include/net/l2_buf.h deleted file mode 100644 index 8003f8471defc081b238d2afd50bfec212acf6da..0000000000000000000000000000000000000000 --- a/include/net/l2_buf.h +++ /dev/null @@ -1,166 +0,0 @@ -/** @file - * @brief L2 buffer API - * - * L2 (layer 2 or MAC layer) data is passed between application and - * IP stack via a l2_buf struct. Currently L2 buffers are only used - * in IEEE 802.15.4 code. - */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* Data buffer API - used for all data to/from net */ - -#ifndef __L2_BUF_H -#define __L2_BUF_H - -#include - -#include - -#include "contiki/ip/uipopt.h" -#include "contiki/ip/uip.h" -#include "contiki/packetbuf.h" -#include "contiki/os/lib/list.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(CONFIG_L2_BUFFERS) - -#ifdef CONFIG_NETWORKING_WITH_LOGGING -#undef DEBUG_L2_BUFS -#define DEBUG_L2_BUFS -#endif - -/** @cond ignore */ -void l2_buf_init(void); -/* @endcond */ - -/** For the MAC/L2 layer (after the IPv6 packet is fragmented to smaller - * chunks), we can use much smaller buffers (depending on used radio - * technology). For 802.15.4 we use the 128 bytes long buffers. - */ -#ifndef NET_L2_BUF_MAX_SIZE -#define NET_L2_BUF_MAX_SIZE (PACKETBUF_SIZE + PACKETBUF_HDR_SIZE) -#endif - -struct l2_buf { - /** @cond ignore */ - /* 6LoWPAN pointers */ - uint8_t *packetbuf_ptr; - uint8_t packetbuf_hdr_len; - uint8_t packetbuf_payload_len; - uint8_t uncomp_hdr_len; - int last_tx_status; -#if defined(CONFIG_NETWORKING_WITH_15_4) - LIST_STRUCT(neighbor_list); -#endif - - struct packetbuf_attr pkt_packetbuf_attrs[PACKETBUF_NUM_ATTRS]; - struct packetbuf_addr pkt_packetbuf_addrs[PACKETBUF_NUM_ADDRS]; - uint16_t pkt_buflen, pkt_bufptr; - uint8_t pkt_hdrptr; - uint8_t *pkt_packetbufptr; - /* @endcond */ -}; - -/** @cond ignore */ -#define uip_packetbuf_ptr(buf) \ - (((struct l2_buf *)net_buf_user_data((buf)))->packetbuf_ptr) -#define uip_packetbuf_hdr_len(buf) \ - (((struct l2_buf *)net_buf_user_data((buf)))->packetbuf_hdr_len) -#define uip_packetbuf_payload_len(buf) \ - (((struct l2_buf *)net_buf_user_data((buf)))->packetbuf_payload_len) -#define uip_uncomp_hdr_len(buf) \ - (((struct l2_buf *)net_buf_user_data((buf)))->uncomp_hdr_len) -#define uip_last_tx_status(buf) \ - (((struct l2_buf *)net_buf_user_data((buf)))->last_tx_status) -#if defined(CONFIG_NETWORKING_WITH_15_4) -#define uip_neighbor_list(buf) \ - (((struct l2_buf *)net_buf_user_data((buf)))->neighbor_list) -#endif -#define uip_pkt_buflen(buf) \ - (((struct l2_buf *)net_buf_user_data((buf)))->pkt_buflen) -#define uip_pkt_bufptr(buf) \ - (((struct l2_buf *)net_buf_user_data((buf)))->pkt_bufptr) -#define uip_pkt_hdrptr(buf) \ - (((struct l2_buf *)net_buf_user_data((buf)))->pkt_hdrptr) -#define uip_pkt_packetbufptr(buf) \ - (((struct l2_buf *)net_buf_user_data((buf)))->pkt_packetbufptr) -#define uip_pkt_packetbuf_attrs(buf) \ - (((struct l2_buf *)net_buf_user_data((buf)))->pkt_packetbuf_attrs) -#define uip_pkt_packetbuf_addrs(buf) \ - (((struct l2_buf *)net_buf_user_data((buf)))->pkt_packetbuf_addrs) - -/* Note that we do not reserve extra space for the header when the packetbuf - * is converted to use net_buf, so the packet starts directly from the - * data pointer. This is done in order to simplify the 802.15.4 packet - * handling. So the L2 buffer should only be allocated by calling - * reserve function like this: l2_buf_get_reserve(0); - */ -#define uip_pkt_packetbuf(ptr) ((ptr)->data) -/* @endcond */ - -/** - * @brief Get buffer from the available buffers pool - * and also reserve headroom for potential headers. - * - * @details Normally this version is not useful for applications - * but is mainly used by network fragmentation code. - * - * @param reserve How many bytes to reserve for headroom. - * - * @return Network buffer if successful, NULL otherwise. - */ -#ifdef DEBUG_L2_BUFS -#define l2_buf_get_reserve(res) l2_buf_get_reserve_debug(res, \ - __func__, __LINE__) -struct net_buf *l2_buf_get_reserve_debug(uint16_t reserve_head, - const char *caller, int line); -#else -struct net_buf *l2_buf_get_reserve(uint16_t reserve_head); -#endif - -/** - * @brief Place buffer back into the available buffers pool. - * - * @details Releases the buffer to other use. This needs to be - * called by application after it has finished with - * the buffer. - * - * @param buf Network buffer to release. - * - */ -#ifdef DEBUG_L2_BUFS -#define l2_buf_unref(buf) l2_buf_unref_debug(buf, __func__, __LINE__) -void l2_buf_unref_debug(struct net_buf *buf, const char *caller, int line); -#else -void l2_buf_unref(struct net_buf *buf); -#endif - -#else /* defined(CONFIG_L2_BUFFERS) */ - -#define l2_buf_init(...) - -#endif /* defined(CONFIG_L2_BUFFERS) */ - -#ifdef __cplusplus -} -#endif - -#endif /* __L2_BUF_H */ diff --git a/include/net/net_context.h b/include/net/net_context.h index 0f37357d6e8363f14b6686956a7db7b4cdfa6df3..2d308e721d648921f3c1b9cfa52eb6dee329269e 100644 --- a/include/net/net_context.h +++ b/include/net/net_context.h @@ -16,7 +16,4 @@ #if defined(CONFIG_NET_YAIP) #include -#else -/* For legacy stack the context API stuff is in net_socket.h */ -#include #endif diff --git a/include/net/net_core.h b/include/net/net_core.h index 940caece9db35ba50edd73a9d740f5910d04bfe7..6d66c1593826e01a9524b37e881457eea43dc97e 100644 --- a/include/net/net_core.h +++ b/include/net/net_core.h @@ -16,6 +16,4 @@ #if defined(CONFIG_NET_YAIP) #include -#else -#include #endif diff --git a/include/net/net_ip.h b/include/net/net_ip.h index 5365cbd46003b710878e78fd243228311739d3ba..75e3ae0d7e7bc53f085d893f1e8470b071ebda19 100644 --- a/include/net/net_ip.h +++ b/include/net/net_ip.h @@ -14,8 +14,4 @@ * limitations under the License. */ -#if defined(CONFIG_NET_YAIP) #include -#else -#include -#endif diff --git a/include/net/net_socket.h b/include/net/net_socket.h deleted file mode 100644 index 21b931a5dd8f61291a491c8fc922482591f30751..0000000000000000000000000000000000000000 --- a/include/net/net_socket.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined(CONFIG_NET_YAIP) -#include -#else -#include -#endif diff --git a/include/net/uip/net_core.h b/include/net/uip/net_core.h deleted file mode 100644 index da2c7edb2eefd215f7fbfd0060bb3453b0f7cb3c..0000000000000000000000000000000000000000 --- a/include/net/uip/net_core.h +++ /dev/null @@ -1,164 +0,0 @@ -/** @file - * @brief Network core definitions - * - * Definitions for networking support. - */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __NET_CORE_H -#define __NET_CORE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Network subsystem logging helpers */ - -#ifdef CONFIG_NETWORKING_WITH_LOGGING -#define NET_DBG(fmt, ...) printk("net: %s (%p): " fmt, __func__, \ - sys_thread_self_get(), ##__VA_ARGS__) -#define NET_ERR(fmt, ...) printk("net: %s: " fmt, __func__, ##__VA_ARGS__) -#define NET_INFO(fmt, ...) printk("net: " fmt, ##__VA_ARGS__) -#define NET_PRINT(fmt, ...) printk(fmt, ##__VA_ARGS__) -#else -#define NET_DBG(...) -#define NET_ERR(...) -#define NET_INFO(...) -#define NET_PRINT(...) -#endif /* CONFIG_NETWORKING_WITH_LOGGING */ - -enum net_tcp_type { - NET_TCP_TYPE_UNKNOWN = 0, - NET_TCP_TYPE_SERVER, - NET_TCP_TYPE_CLIENT, -}; - -struct net_buf; -struct net_context; - -#include -#include - -#include - -/** - * @brief Initialize network stack. This is will be automatically called - * by the OS. - * - * @details No harm will happen if application calls this multiple times. - * - * @return 0 if ok, < 0 in case of error. - */ -int net_init(void); - -struct net_driver { - /** How much headroom is needed for net transport headers */ - size_t head_reserve; - - /** Open the net transport */ - int (*open)(void); - - /** Send data to net. The send() function should return: - * 0 : If packet could not be sent. In this case buf should - * not be released. - * 1 : If the packet was sent successfully. In this case the buf - * should be released by either the send() or some other - * lower layer function. - * <0: If there is an error, the buf should not be released by - * send() function. - */ - int (*send)(struct net_buf *buf); -}; - -/** - * @brief Register a new network driver to the network stack. - * - * @details Only one network device can be registered at a time. - * - * @param drv Network driver. - * - * @return 0 if ok, < 0 in case of error. - */ -int net_register_driver(struct net_driver *drv); - -/** - * @brief Unregister a previously registered network driver. - * - * @param drv Network driver. - * - * @details Networking will be disabled if there is no driver - * available. - * - */ -void net_unregister_driver(struct net_driver *drv); - -/** - * @brief Set the MAC/EUI-64 address of the device. - * - * @details Network device driver should call this function to - * tell the used MAC or EUI-64 address to the IP stack. - * - * @param mac MAC or EUI-64 address - * @param len If len == 6, then the first parameter is interpreted - * to be the MAC address and the function sets the U/L bits etc. - * If the len == 8, then the value is used as is to generate the - * link local IPv6 address. - * - * @return 0 if ok, < 0 in case of error. - */ -int net_set_mac(uint8_t *mac, uint8_t len); - -/** - * @brief Send a reply packet to the message originator. - * - * @details Application can call this function if it has received - * a network packet from peer. The application needs to write - * reply data into net_buf. The app can use ip_buf_appdata(buf) and - * ip_buf_appdatalen(buf) to set the application data and length. - * This function will yield in thread and fiber contexts. - * - * @param context Network context - * @param buf Network buffer containing the network data. - * - * @return 0 if ok, < 0 in case of error. - */ -int net_reply(struct net_context *context, struct net_buf *buf); - -/* Called by driver when an IP packet has been received */ -int net_recv(struct net_buf *buf); - -void net_context_init(void); - -/** - * @brief Get current status of the TCP connection. - * - * @details Application can call this to get the current status - * of TCP connection. The returned value maps to errno values. - * Value 0 means ok. For UDP context 0 is always returned. - * - * @param context Network context - * - * @return 0 if ok, < 0 connection status - */ -int net_context_get_connection_status(struct net_context *context); - -#ifdef __cplusplus -} -#endif - -#endif /* __NET_CORE_H */ diff --git a/include/net/uip/net_ip.h b/include/net/uip/net_ip.h deleted file mode 100644 index 732d49a92d4c66f172fe942b96bc500e7a3632b2..0000000000000000000000000000000000000000 --- a/include/net/uip/net_ip.h +++ /dev/null @@ -1,119 +0,0 @@ -/** @file - * @brief IPv6 and IPv4 definitions - * - * Generic IPv6 and IPv4 address definitions. - */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __NET_IP_H -#define __NET_IP_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Protocol families */ -#define PF_UNSPEC 0 /* Unspecified. */ -#define PF_INET 2 /* IP protocol family. */ -#define PF_INET6 10 /* IP version 6. */ - -/** Address families. */ -#define AF_UNSPEC PF_UNSPEC -#define AF_INET PF_INET -#define AF_INET6 PF_INET6 - -/** Protocol numbers from IANA */ -enum ip_protocol { - IPPROTO_TCP = 6, - IPPROTO_UDP = 17, - IPPROTO_ICMPV6 = 58, -}; - -/** IPv6 address structure */ -struct in6_addr { - union { - uint8_t u6_addr8[16]; - uint16_t u6_addr16[8]; /* In big endian */ - uint32_t u6_addr32[4]; /* In big endian */ - } in6_u; -#define s6_addr in6_u.u6_addr8 -#define s6_addr16 in6_u.u6_addr16 -#define s6_addr32 in6_u.u6_addr32 -}; - -/** IPv4 address */ -struct in_addr { - union { - uint8_t u4_addr8[4]; - uint16_t u4_addr16[2]; /* In big endian */ - uint32_t u4_addr32[1]; /* In big endian */ - } in4_u; -#define s4_addr in4_u.u4_addr8 -#define s4_addr16 in4_u.u4_addr16 -#define s4_addr32 in4_u.u4_addr32 - -#define s_addr s4_addr32 -}; - -typedef unsigned short int sa_family_t; - -struct net_addr { - sa_family_t family; - union { - struct in6_addr in6_addr; - struct in_addr in_addr; - }; -}; - -#define IN6ADDR_ANY_INIT { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0 } } } -#define IN6ADDR_LOOPBACK_INIT { { { 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 1 } } } - -#define INET6_ADDRSTRLEN 46 - -#define INADDR_ANY 0 - -/** IPv6/IPv4 network connection tuple */ -struct net_tuple { - /** IPv6/IPv4 remote address */ - struct net_addr *remote_addr; - /** IPv6/IPv4 local address */ - struct net_addr *local_addr; - /** UDP/TCP remote port */ - uint16_t remote_port; - /** UDP/TCP local port */ - uint16_t local_port; - /** IP protocol */ - enum ip_protocol ip_proto; -}; - -#if defined(CONFIG_NETWORKING_WITH_TCP) -enum tcp_event_type { - TCP_READ_EVENT = 1, - TCP_WRITE_EVENT, -}; -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __NET_IP_H */ diff --git a/include/net/uip/net_socket.h b/include/net/uip/net_socket.h deleted file mode 100644 index 036ed942314ebdc47bab123b5eaafea89c108653..0000000000000000000000000000000000000000 --- a/include/net/uip/net_socket.h +++ /dev/null @@ -1,137 +0,0 @@ -/** @file - * @brief Simple socket API - * - * Simple socket API for applications to connection establishment and - * disconnection. - */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __NET_SOCKET_H -#define __NET_SOCKET_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Get network context. - * - * @details Network context is used to define the connection - * 5-tuple (protocol, remote address, remote port, source - * address and source port). - * - * @param ip_proto Protocol to use. Currently only UDP is supported. - * @param remote_addr Remote IPv6/IPv4 address. - * @param remote_port Remote UDP/TCP port. - * @param local_addr Local IPv6/IPv4 address. If the local address is - * set to be anyaddr (all zeros), the IP stack will use the link - * local address defined for the system. - * @param local_port Local UDP/TCP port. If the local port is 0, - * then a random port will be allocated. - * - * @return Network context if successful, NULL otherwise. - */ -struct net_context *net_context_get(enum ip_protocol ip_proto, - const struct net_addr *remote_addr, - uint16_t remote_port, - struct net_addr *local_addr, - uint16_t local_port); - -/** - * @brief Get network tuple. - * - * @details This function returns the used connection tuple. - * - * @param context Network context. - * - * @return Network tuple if successful, NULL otherwise. - */ -struct net_tuple *net_context_get_tuple(struct net_context *context); - -/** - * @brief Release network context. - * - * @details Free the resources allocated for the context. - * All network listeners tied to this context are removed. - * - * @param context Network context. - * - */ -void net_context_put(struct net_context *context); - -/** - * @brief Send data to network. - * - * @details Send user specified data to network. This - * requires that net_buf is tied to context. This means - * that the net_buf was allocated using net_buf_get(). - * This function will yield in thread and fiber contexts. - * - * @param buf Network buffer. - * - * @return 0 if ok (do not unref the buf), - * <0 if error (unref the buf). - */ -int net_send(struct net_buf *buf); - -/** - * @brief Receive data from network. - * - * @details Application uses this to get data from network - * connection. Caller can specify a timeout, if there is no - * data to return after a timeout, a NULL will be returned. - * Caller is responsible to release the returned net_buf. - * - * @param context Network context. - * @param timeout Timeout to wait. The value is in ticks. - * If TICKS_UNLIMITED (-1), wait forever. - * If TICKS_NONE (0), do not wait. - * If > 0, wait amount of ticks. - * The timeout is only available if kernel is compiled - * with CONFIG_NANO_TIMEOUTS. If CONFIG_NANO_TIMEOUT is not - * defined, then value > 0 means not to wait. - * - * @return Network buffer if successful, NULL otherwise. - */ -struct net_buf *net_receive(struct net_context *context, - int32_t timeout); - -/** - * @brief Get the UDP connection pointer from net_context. - * - * @details This is only needed in special occacions when - * there is an existing UDP connection that application - * wants to attach to. Normally the connection information - * is not needed by application. - * - * @return UDP connection if it exists, NULL otherwise. - */ -struct simple_udp_connection * - net_context_get_udp_connection(struct net_context *context); - -void *net_context_get_internal_connection(struct net_context *context); - -#ifdef __cplusplus -} -#endif - -#endif /* __NET_SOCKET_H */ diff --git a/net/Kconfig b/net/Kconfig index 402cb8c9e3c0789b8b164bfd5d5a25642595937a..3a8d82e6918a3d6fe853fb129f7bcb52d4f4bbd3 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -50,31 +50,17 @@ config NETWORKING select NANO_TIMEOUTS select NANO_TIMERS select NET_BUF + select NET_YAIP + select TEST_RANDOM_GENERATOR default n help This option enabled generic link layer and IP networking support. if NETWORKING -choice - prompt "IP stack" - default NET_UIP - help - Select what IP stack to use. The legacy stack is - Contiki based uIP stack. - -config NET_UIP - bool "uIP" - help - Choose this if unsure. - config NET_YAIP - bool "New IP stack [EXPERIMENTAL]" - help - New IP stack. -endchoice - -source "net/ip/Kconfig" + bool + default y source "net/yaip/Kconfig" diff --git a/net/Makefile b/net/Makefile index 14018204e3e6ebed97aeb9fa45758ea80db6a3dd..e40f81294362269723b09432e750a39e9c94ab1a 100644 --- a/net/Makefile +++ b/net/Makefile @@ -5,6 +5,4 @@ obj-y += yaip/nbuf.o else obj-y += yaip/ endif -else -obj-$(CONFIG_NETWORKING) += ip/ endif diff --git a/net/ip/Kconfig b/net/ip/Kconfig deleted file mode 100644 index 42eef7ed7cf6927d46c6fafddd47e919c3a42ffb..0000000000000000000000000000000000000000 --- a/net/ip/Kconfig +++ /dev/null @@ -1,582 +0,0 @@ -# networking.kconf - Generic networking configuration options - -# -# Copyright (c) 2015 Intel Corporation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# UIP options -# -menu "uIP stack" - depends on NET_UIP - -config IP_BUF_RX_SIZE - int "Number of IP net buffers to use when receiving data" - default 1 - help - Each network buffer will contain one received IPv6 or IPv4 packet. - Each buffer will occupy 1280 bytes of memory. - -config IP_BUF_TX_SIZE - int "Number of IP net buffers to use when sending data" - default 2 - help - Each network buffer will contain one sent IPv6 or IPv4 packet. - Each buffer will occupy 1280 bytes of memory. - -config IP_RX_STACK_SIZE - int "RX fiber stack size" - default 1024 - help - Set the RX fiber stack size in bytes. The RX fiber is waiting - network packets from lower level bearers. It will then run the - packet through IP stack which validates the packet and passes - it eventually to application. - -config IP_TX_STACK_SIZE - int "TX fiber stack size" - default 1024 - help - Set the TX fiber stack size in bytes. The TX fiber is waiting - data from application. It will then validate the data and push - it to network driver to be sent out. - -config IP_TIMER_STACK_SIZE - int "Timer fiber stack size" - default 1536 - help - Set the timer fiber stack size in bytes. The timer fiber is - responsible for handling re-transmissions and periodic network - packet sending like IPv6 router solicitations. - -config NET_MAX_CONTEXTS - int "How many network context to use" - default 2 - help - The network context is similar concept as network socket. - It defines a network endpoint and number of context depends - on application usage. - -config UDP_MAX_CONNECTIONS - int "How many UDP connections can be used" - default 2 - help - Amount of concurrent UDP connections. - -choice -prompt "Internet Protocol version" -depends on NETWORKING -help - The IP stack can either support IPv6 or IPv4 but - not both at the same time. The IPv6 support should - be selected by default as there is limited set of - network bearers provided that support IPv4. -default NETWORKING_WITH_IPV6 -config NETWORKING_WITH_IPV6 - bool "IPv6" - help - Choose this if unsure. -config NETWORKING_WITH_IPV4 - bool "IPv4" - help - Legacy IP. -endchoice - -config NETWORKING_STATISTICS - bool - prompt "Enable IP statistics gathering" - depends on NETWORKING - default n - help - This is only for debugging the network. Do not activate - this in live system! The option uses memory and slows - down IP packet processing. - -config NETWORKING_IPV6_NO_ND - bool - prompt "Disable IPv6 neighbor discovery" - depends on NETWORKING - depends on NETWORKING_WITH_IPV6 - default n - help - Normally ND should be enabled but in order to simplify - the network setup it can be turned off if using - slip and tun device. - -config NETWORKING_MAX_NEIGHBORS - int "Max number of neighbors" - depends on NETWORKING - depends on NETWORKING_WITH_IPV6 - default 4 - help - Specifies the maximum number of neighbors that each node will - be able to handle. - -config NETWORKING_WITH_TCP - bool - prompt "Enable TCP protocol" - depends on NETWORKING - default n - help - Enable Transmission and Control Protocol (TCP) support. - -config TCP_MAX_CONNECTIONS - int "Maximum number of connections" - depends on NETWORKING_WITH_TCP - default 2 - help - Tweak the TCP maximum segment size. Normally one should - not change this but let the IP stack to calculate a best - size for it. - -config TCP_DISABLE_ACTIVE_OPEN - bool - prompt "Disallow host to initiate connection attempt" - depends on NETWORKING_WITH_TCP - default n - help - By default application is allowed to initiate a TCP - connection attempt. If the application is only acting - as a server, then some memory can be saved by disabling - the client role. - -config TCP_MSS - int - prompt "TCP maximum segment size" - depends on NETWORKING_WITH_TCP - default 0 - help - Tweak the TCP maximum segment size. Normally one should - not change this but let the IP stack to calculate a best - size for it. - -config TCP_RECEIVE_WINDOW - int - prompt "TCP receive window size" - depends on NETWORKING_WITH_TCP - default 0 - help - Tweak the TCP receive window size. Normally one should - not change this but let the IP stack to calculate a best - size for it. - -config NETWORKING_WITH_RPL - bool - prompt "Enable RPL (ripple) IPv6 mesh routing protocol" - depends on NETWORKING && NETWORKING_WITH_IPV6 - default n - help - Enable RPL (RFC 6550) IPv6 Routing Protocol for - Low-Power and Lossy Networks. - -config RPL_STATS - bool - prompt "Enable RPL statistics" - depends on NETWORKING_WITH_RPL - select NETWORKING_STATISTICS - default n - help - Enable RPL statistics support. - -config RPL_PROBING - bool - prompt "Enable RPL probing" - depends on NETWORKING_WITH_RPL - default n - help - Enable RPL probing support. When enabled, probes will be sent - periodically to keep parent link estimates up to date. - -choice -prompt "Objective function" -depends on NETWORKING_WITH_RPL -help - The objective function to use. All RPL nodes in a DODAG - must use the same OF. - The default is MRHOF, see RFC 6719 for details. - Other alternative is OF0, see RFC 6552 for details. -default RPL_WITH_MRHOF -config RPL_WITH_MRHOF - bool "Minimum Rank with Hysteresis, RFC 6719" - help - Choose this (MRHOF) if unsure. -config RPL_WITH_OF0 - bool "OF Zero, RFC 6552" - help - Objective function zero (OF0). -endchoice - -config NETWORKING_WITH_TRICKLE - bool "Enable Trickle algorithm" - depends on NETWORKING - default n - help - Enable Trickle algorithm (RFC 6206) support. This only - includes Trickle library but IP stack does not call its - functions. - -config NETWORKING_WITH_LOOPBACK - bool - prompt "Enable loopback driver" - depends on NETWORKING - default n - help - Enable a simple loopback driver that installs - IPv6 loopback addresses into routing table and - neighbor cache. All packets transmitted are - looped back to the receiving fifo/fiber. - -config NETWORK_LOOPBACK_TEST_COUNT - int "How many packets the loopback test passes" - depends on NETWORKING_WITH_LOOPBACK - default 0 - help - If set to 0, then the loopback test runs forever. - -choice -prompt "Wired networking support" -depends on NETWORKING -default NETWORKING_NO_WIRED -config NETWORKING_NO_WIRED - bool "No wired network driver" - help - Do not enable any wired network driver. It is still - possible to select other types of network drivers if - this option is selected. -config NETWORKING_UART - bool "Network UART/slip driver" - select UART_PIPE - help - Enable UART driver for passing IPv6 packets using slip. -config ETHERNET - bool "Ethernet drivers" - help - Include Ethernet drivers in system config. This - option enables Ethernet support in the core network - subsystem, but it is necessary to also select a - specific Ethernet device driver. -endchoice - -config NETWORKING_DEBUG_UART - bool - prompt "Network UART driver debug" - depends on NETWORKING_UART && NETWORKING_WITH_LOGGING - default n - help - This option enables debug support for network UART - driver. - -config ETHERNET_DEBUG - bool - prompt "Network Ethernet driver debug" - depends on NETWORKING_WITH_LOGGING && ETHERNET - default n - help - This option enables debug support for Ethernet drivers. - -config L2_BUFFERS - bool - default n - -config NETWORKING_WITH_15_4 - bool - prompt "Enable 802.15.4 driver" - depends on NETWORKING && NETWORKING_WITH_IPV6 - select L2_BUFFERS - default n - help - Enable 802.15.4 driver that receives the IPv6 packet, - does header compression on it and writes it to the - 802.15.4 stack Tx FIFO. The 802.15.4 Tx fiber will pick up - the header compressed IPv6 6lowpan packet and fragment - it into suitable chunks ready to be sent to the 802.15.4 - hw driver - -config NETWORKING_WITH_15_4_ALWAYS_ACK - bool - prompt "Always request 802.15.4 packet acknowledgment" - depends on NETWORKING_WITH_15_4 - default n - help - This is meant to be used for testing only. Requesting an - acknowledgment on all data packet will draw power resource. - Use case for this option it for testing only. - -# Using nullmac 802.15.4 driver only. -config NETWORKING_WITH_15_4_MAC_NULL - bool - default n - -choice - prompt "802.15.4 RDC Driver" - depends on NETWORKING && NETWORKING_WITH_15_4 - help - The 802.15.4 RDC (Radio Duty Cycle) layer can use either - sicslowmac or simplerdc. -config NETWORKING_WITH_15_4_RDC_SIMPLE - bool - prompt "simplerdc driver" - help - Enable simplerdc driver. -config NETWORKING_WITH_15_4_RDC_SICSLOWMAC - bool - prompt "sicslowmac driver" - help - Enable sicslowmac driver. -endchoice - -config 15_4_RX_STACK_SIZE - int "Stack size of 802.15.4 RX fiber" - depends on NETWORKING_WITH_15_4 - default 1024 - help - Set the 802.15.4 RX fiber stack size in bytes. The RX fiber - is waiting network packets from 802.15.4 device driver. - It will then run the packet through 6LoWPAN stack which - uncompresses and de-fragments the packet and passes those to - upper layers. - -config 15_4_TX_STACK_SIZE - int "Stack size of 802.15.4 TX fiber" - depends on NETWORKING_WITH_15_4 - default 4096 - help - Set the 802.15.4 TX fiber stack size in bytes. The TX fiber - is waiting network packets from IP stack. It then feeds those - to 6LoWPAN stack which compresses and fragments packets before - passing the fragments to 802.15.4 device driver. Note that - this stack needs to be bigger that TX stack because stack is - used to store the fragmented 802.15.4 packets. - -config 15_4_BEACON_SUPPORT - bool - prompt "Enable 802.15.4 beacon support" - depends on NETWORKING_WITH_15_4 - default n - help - Enable 802.15.4 beacon support - -config 15_4_BEACON_STATS - bool - prompt "Enable 802.15.4 beacon statistics" - depends on NETWORKING_WITH_15_4 - depends on 15_4_BEACON_SUPPORT - select NETWORKING_STATISTICS - default n - help - Enable 802.15.4 beacon statistics support. - -config NETWORKING_WITH_15_4_PAN_ID - hex - prompt "IEEE 802.15.4 PAN id/address" - depends on NETWORKING_WITH_15_4 - default 0xabcd - help - All the 802.15.4 devices that want to connect to each - other need to have same PAN id (address). - Default PAN id is 0xABCD - -choice -prompt "802.15.4 Radio Driver" -depends on NETWORKING && NETWORKING_WITH_15_4 -default n -help - The 802.15.4 layer can either support loopback within - or loopback with uart but not both at the same time. - -config NETWORKING_WITH_15_4_TI_CC2520 - bool - prompt "TI CC2520" - select TEST_RANDOM_GENERATOR - select TI_CC2520_LEGACY - help - Enable Texas Instruments CC2520 802.15.4 radio driver. - -config NETWORKING_WITH_15_4_LOOPBACK - bool - prompt "Loopback" - help - Enable 802.15.4 loopback radio driver that receives - the 802.15.4 frame and put it back 802.15.4 Rx Fifo. - -config NETWORKING_WITH_15_4_LOOPBACK_UART - bool - prompt "Loopback with UART" - select UART_PIPE - help - Enable 802.15.4 loopback radio driver that sends - 802.15.4 frames out of qemu through uart and receive - frames through uart. This way one can test 802.15.4 frames - between two qemus -endchoice - -config NETWORKING_WITH_BT - bool - prompt "Enable Bluetooth driver" - depends on NETWORKING && NETWORKING_WITH_IPV6 - select L2_BUFFERS - select NETWORKING_IPV6_NO_ND - select NETWORKING_WITH_6LOWPAN - select 6LOWPAN_COMPRESSION_IPHC - select BLUETOOTH - select BLUETOOTH_PERIPHERAL - select BLUETOOTH_L2CAP_DYNAMIC_CHANNEL - select BLUETOOTH_SMP - default n - help - Enable Bluetooth driver that send and receives IPv6 packets, - does header compression on it and writes it to the - Bluetooth stack via L2CAP channel. - -config NETWORKING_WITH_6LOWPAN - bool - prompt "Enable 6LoWPAN (IPv6 compression) in the uIP stack" - depends on NETWORKING - depends on NETWORKING_WITH_15_4 || NETWORKING_WITH_BT - default n - help - Enable 6LoWPAN in uIP stack. Currently this requires 802.15.4 - stack to be enabled. - -choice -prompt "6LoWPAN compression method" -depends on NETWORKING_WITH_6LOWPAN -help - Select the compression method that is used in 6LoWPAN. -default 6LOWPAN_COMPRESSION_IPV6 -config 6LOWPAN_COMPRESSION_IPV6 - bool "No compression" - help - Choose this if unsure. -config 6LOWPAN_COMPRESSION_IPHC - bool "IP header compression" - help - IP header compression -endchoice - -config TINYDTLS - bool - prompt "Enable tinyDTLS support." - depends on NETWORKING - default n - help - Enable tinyDTLS support so that applications can use it. - This is needed at least in CoAP. - -config TINYDTLS_DEBUG - bool - prompt "Enable tinyDTLS debugging support." - depends on TINYDTLS - default n - help - Enable tinyDTLS debugging support. - -config ER_COAP - bool - prompt "Enable Erbium CoAP engine support." - depends on NETWORKING - default n - help - Enable Erbium CoAP engine support so that applications can use it. - -config ER_COAP_WITH_DTLS - bool - prompt "Use DTLS in CoAP" - depends on ER_COAP - select TINYDTLS - default n - help - Make CoAP engine use DTLS. Note that if you activate DTLS, you - are not able to send or receive non-DTLS CoAP messages, and - vice versa. - -config ER_COAP_LINK_FORMAT_FILTERING - bool "Enable link format filtering" - select MINIMAL_LIBC_EXTENDED - default n - help - Make CoAP engine support link format filters. - -config COAP_STATS - bool - prompt "Enable CoAP statistics" - depends on ER_COAP - select NETWORKING_STATISTICS - default n - help - Enable CoAP statistics support. - -config ER_COAP_CLIENT - bool - prompt "Enable CoAP client support" - depends on ER_COAP - default n - help - Compile in client CoAP support. - -config DHCP - bool - prompt "Enable DHCP support." - depends on NETWORKING && NETWORKING_WITH_IPV4 - default n - help - Enable DHCP support so that applications can use it. -choice -prompt "DHCP message type" -depends on DHCP -help - Select the DHCP message type broadcast or unicast. -default DHCP_BROADCAST -config DHCP_BROADCAST - bool "Broadcast message" - help - Choose this if unsure. -config DHCP_UNICAST - bool "Unicast message" - help - DHCP message type -endchoice - -config NET_SANITY_TEST - bool - prompt "Enable networking sanity test" - depends on NETWORKING - default n - help - Enable networking sanity tests. Network sanity test - verification and test report submission will fall under - this config. - -config NET_15_4_LOOPBACK_NUM - int - prompt "Number of times loopback test runs" - depends on (NETWORKING_WITH_15_4_LOOPBACK || NETWORKING_WITH_15_4_LOOPBACK_UART) && NET_SANITY_TEST - default 0 - help - Number of times loopback test runs, 0 means infinite. - -config NET_TESTING - bool - prompt "Enable network Qemu-to-Qemu testing setup" - depends on NETWORKING - default n - help - Setup the network stack such a way that it is suitable for - testing with Qemu-to-Qemu and slip. Note that this setting should - not be used for Qemu-to-Host communication. - -source "net/ip/Kconfig.debug" - -endmenu diff --git a/net/ip/Kconfig.debug b/net/ip/Kconfig.debug deleted file mode 100644 index a0ff8b1eb3528fb6a910813d22ea1c57b0837a25..0000000000000000000000000000000000000000 --- a/net/ip/Kconfig.debug +++ /dev/null @@ -1,274 +0,0 @@ -# Kconfig.debug - IP stack debugging configuration options - -# -# Copyright (c) 2016 Intel Corporation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -menuconfig NETWORKING_WITH_LOGGING - bool "Enable network stack logging" - depends on NET_UIP - select STDOUT_CONSOLE - default n - help - Enable logging in various parts of the network stack. - -choice - prompt "General debug level" - default NETWORK_IP_STACK_DEBUG_PRINT - depends on NETWORKING_WITH_LOGGING - help - Set the level of debugging you want. This will be generalized, - whatever the part you will be debugging. - -config NETWORK_IP_STACK_DEBUG_PRINT - bool "Print only debug messages" - -config NETWORK_IP_STACK_DEBUG_ANNOTATE - bool "Print only annotations" - -config NETWORK_IP_STACK_DEBUG_FULL - bool "Print both messages and annotations" - -endchoice - -if NETWORKING_WITH_LOGGING - -config NETWORK_IP_STACK_DEBUG_CONTEXT - bool "Debug network context allocation" - default n - help - Enables printing of network context allocations and frees. - -config NETWORK_IP_STACK_DEBUG_NET_BUF - bool "Debug network buffer allocation" - default n - help - Enables printing of network buffer allocations and frees. - -config NETWORK_IP_STACK_DEBUG_RECV_SEND - bool "Debug network generic receive and send functions" - default n - help - Enables generic debug printing when receiving and sending data. - -config NETWORK_IP_STACK_DEBUG_TCP_PSOCK - bool "Debug network TCP protosockets" - depends on NETWORKING_WITH_TCP - default n - help - Enables debugging the protosockets used in TCP engine. - -config NETWORK_IP_STACK_DEBUG_IPV6 - bool "Debug core IPv6" - depends on NETWORKING_WITH_IPV6 || NET_IPV6 - default n - help - Enables core IPv6 code part to output debug messages - -config NETWORK_IP_STACK_DEBUG_SIMPLE_UDP - bool "Debug simple udp" - default n - help - Enables network simple udp debug messages - -config NETWORK_IP_STACK_DEBUG_UDP_PACKET - bool "Debug udp packet" - default n - help - Enables network uip udp packet debug messages - -config NETWORK_IP_STACK_DEBUG_IPV6_DS - bool "Debug IPv6 Data Structures" - depends on NETWORKING_WITH_IPV6 - default n - help - Enables IPv6 Data Structures code part to output debug messages - -config NETWORK_IP_STACK_DEBUG_IPV6_ICMPV6 - bool "Debug ICMPv6" - depends on NETWORKING_WITH_IPV6 - default n - help - Enables ICMPv6 code part to output debug messages - -config NETWORK_IP_STACK_DEBUG_IPV6_ND - bool "Debug IPv6 Neighbour Discovery" - depends on NETWORKING_WITH_IPV6 || NET_IPV6 - default n - help - Enables IPv6 Neighbour Discovery code part to output debug messages - -config NETWORK_IP_STACK_DEBUG_IPV6_NBR_CACHE - bool "Debug IPv6 neighbour cache" - depends on NETWORKING_WITH_IPV6 || NET_IPV6 - default n - help - Enables Neighbour Cache code part to output debug messages - -config NETWORK_IP_STACK_DEBUG_IPV6_ROUTE - bool "Debug IPv6 route" - depends on NETWORKING_WITH_IPV6 || NET_IPV6 - default n - help - Enables IPv6 route code part to output debug messages - -config NETWORK_IP_STACK_DEBUG_15_4_NET_DRIVER - bool "Debug 802.15.4 network driver" - depends on NETWORKING_WITH_15_4 - default n - help - Enables 802.15.4 network driver output debug messages - -config NETWORK_IP_STACK_DEBUG_15_4_MAC - bool "Debug 802.15.4 MAC layer" - depends on NETWORKING_WITH_15_4 - default n - help - Enables 802.15.4 MAC layer to output debug messages - -config NETWORK_IP_STACK_DEBUG_15_4_FRAMING - bool "Debug 802.15.4 packet framing" - depends on NETWORKING_WITH_15_4 - default n - help - Enables 802.15.4 packet framing to output debug messages - -config NETWORK_IP_STACK_DEBUG_15_4_6LOWPAN_FRAG - bool "Debug 802.15.4 6LoWPAN fragmentation" - depends on NETWORKING_WITH_15_4 - default n - help - Enables 802.15.4 6LoWPAN fragmentation to output debug messages - -config NETWORK_IP_STACK_DEBUG_6LOWPAN_COMPRESSION - bool "Debug generic 6LoWPAN compression" - depends on NETWORKING_WITH_IPV6 - default n - help - Enables generic (802.15.4 or Bluetooth) 6LoWPAN compression - to output debug messages - -config NETWORK_IP_STACK_DEBUG_PACKET_QUEUE - bool "Debug uip packet queue" - depends on NETWORKING_WITH_IPV6 - default n - help - Enables uip packet queue output debug messages - -config NETWORK_IP_STACK_DEBUG_RPL - bool "Debug RPL messages" - depends on NETWORKING_WITH_RPL - default n - help - Enables RPL debug messages - -config NETWORK_IP_STACK_DEBUG_RPL_ICMPV6 - bool "Debug RPL ICMPv6 messages" - depends on NETWORKING_WITH_RPL - default n - help - Enables RPL ICMPv6 debug messages - -config NETWORK_IP_STACK_DEBUG_RPL_OF - bool "Debug RPL objective function messages" - depends on NETWORKING_WITH_RPL - default n - help - Enables RPL Objective Function related debug messages - -config NETWORK_IP_STACK_DEBUG_RPL_TIMERS - bool "Debug RPL timer functionality" - depends on NETWORKING_WITH_RPL - default n - help - Enables RPL timers related debug messages - -config NETWORK_IP_STACK_DEBUG_IPV4 - bool "Debug core IPv4" - depends on NETWORKING_WITH_IPV4 || NET_IPV4 - default n - help - Enables core IPv4 code part to output debug messages - -config NETWORK_IP_STACK_DEBUG_IPV4_ARP - bool "Debug IPv4 ARP" - depends on NETWORKING_WITH_IPV4 || NET_IPV4 - default n - help - Enables core ARP code part to output debug messages - -config NETWORK_IP_STACK_DEBUG_COAP_CONTEXT - bool "Debug CoAP context" - depends on ER_COAP - default n - help - Enables CoAP context output debug messages - -config NETWORK_IP_STACK_DEBUG_COAP_ENGINE - bool "Debug CoAP engine" - depends on ER_COAP - default n - help - Enables CoAP engine output debug messages - -config NETWORK_IP_STACK_DEBUG_COAP_TRANSACTION - bool "Debug CoAP transaction" - depends on ER_COAP - default n - help - Enables CoAP transaction output debug messages - -config NETWORK_IP_STACK_DEBUG_COAP_INTERNAL - bool "Debug CoAP internals" - depends on ER_COAP - default n - help - Enables CoAP internals output debug messages - -config NETWORK_IP_STACK_DEBUG_COAP_OBSERVE - bool "Debug CoAP observe" - depends on ER_COAP - default n - help - Enables CoAP observe output debug messages - -config NETWORK_IP_STACK_DEBUG_COAP_WELL_KNOWN - bool "Debug CoAP well known core" - depends on ER_COAP - default n - help - Enables CoAP resource well known core ouput debug messages - -config NETWORK_IP_STACK_DEBUG_REST_ENGINE - bool "Debug REST engine" - depends on ER_COAP - default n - help - Enables REST engine output debug messages - -config NETWORK_IP_STACK_DEBUG_DHCP - bool "Debug DHCP" - depends on DHCP - default n - help - Enables DHCP output debug messages - -config NETWORK_IP_STACK_DEBUG_TRICKLE - bool "Debug Trickle algorithm" - default n - help - Enables Trickle library output debug messages - -endif diff --git a/net/ip/Makefile b/net/ip/Makefile deleted file mode 100644 index 6fdfb76b3c111b87b8a3ccada90cd3d3bf244ac8..0000000000000000000000000000000000000000 --- a/net/ip/Makefile +++ /dev/null @@ -1,184 +0,0 @@ -ccflags-y += -I${srctree}/net/ip/contiki -ccflags-y += -I${srctree}/net/ip/contiki/os/lib -ccflags-y += -I${srctree}/net/ip/contiki/os -ccflags-y += -I${srctree}/net/ip -ccflags-y += -I${srctree}/include/drivers - -# Zephyr specific files -obj-y = net_core.o \ - ip_buf.o \ - net_context.o - -obj-$(CONFIG_L2_BUFFERS) += l2_buf.o - -# Contiki IP stack files -obj-y += contiki/netstack.o \ - contiki/nbr-table.o \ - contiki/linkaddr.o \ - contiki/ip/uip-debug.o \ - contiki/ip/uip-packetqueue.o \ - contiki/ip/uip-udp-packet.o \ - contiki/ip/udp-socket.o \ - contiki/ip/simple-udp.o \ - contiki/ip/uiplib.o \ - contiki/ip/uip-nameserver.o \ - contiki/ip/tcpip.o \ - contiki/os/sys/process.o \ - contiki/os/sys/stimer.o \ - contiki/os/sys/etimer.o \ - contiki/os/sys/timer.o \ - contiki/os/sys/arg.o \ - contiki/os/sys/ctimer.o \ - contiki/os/sys/rtimer.o \ - contiki/os/sys/clock.o \ - contiki/os/dev/nullradio.o \ - contiki/os/lib/mmem.o \ - contiki/os/lib/memb.o \ - contiki/os/lib/list.o \ - contiki/os/lib/random.o \ - contiki/os/lib/aes-128.o \ - contiki/llsec/nullsec.o - -obj-$(CONFIG_NETWORKING_WITH_IPV6) += \ - contiki/ipv6/uip6.o \ - contiki/ipv6/uip-icmp6.o \ - contiki/ipv6/uip-ds6.o \ - contiki/ipv6/uip-nd6.o \ - contiki/ipv6/uip-ds6-route.o \ - contiki/ipv6/uip-ds6-nbr.o - -obj-$(CONFIG_NETWORKING_WITH_IPV4) += \ - contiki/ipv4/uip_arp.o \ - contiki/ipv4/uip.o \ - contiki/ipv4/uip-neighbor.o - -obj-$(CONFIG_NETWORKING_WITH_TCP) += contiki/ip/psock.o - -# RPL (RFC 6550) support -ifeq ($(CONFIG_NETWORKING_WITH_RPL),y) - ccflags-y += -DUIP_CONF_IPV6_RPL=1 - obj-y += contiki/rpl/rpl-dag.o \ - contiki/rpl/rpl-timers.o \ - contiki/rpl/rpl.o \ - contiki/rpl/rpl-ext-header.o \ - contiki/rpl/rpl-icmp6.o \ - contiki/ipv6/multicast/uip-mcast6-route.o \ - contiki/ipv6/multicast/smrf.o \ - contiki/ipv6/multicast/uip-mcast6-stats.o - - obj-$(CONFIG_RPL_WITH_OF0) += contiki/rpl/rpl-of0.o - obj-$(CONFIG_RPL_WITH_MRHOF) += contiki/rpl/rpl-mrhof.o -else - ccflags-y += -DUIP_CONF_IPV6_RPL=0 -endif - -# 6LoWPAN support -ifeq ($(CONFIG_NETWORKING_WITH_6LOWPAN),y) - ccflags-y += -DSICSLOWPAN_CONF_ENABLE - obj-y += contiki/sicslowpan/sicslowpan_compression.o - obj-$(CONFIG_NETWORKING_WITH_15_4) += contiki/sicslowpan/sicslowpan_fragmentation.o -else - obj-$(CONFIG_NETWORKING_WITH_15_4) += contiki/mac/framer-nullmac.o \ - contiki/mac/simplerdc.o \ - contiki/sicslowpan/null_compression.o \ - contiki/sicslowpan/null_fragmentation.o -endif - -# RDC driver -ifeq ($(CONFIG_NETWORKING_WITH_15_4_RDC_SICSLOWMAC),y) - obj-$(CONFIG_NETWORKING_WITH_15_4) += contiki/mac/sicslowmac/sicslowmac.o -else - ifeq ($(CONFIG_NETWORKING_WITH_15_4_RDC_SIMPLE),y) - obj-$(CONFIG_NETWORKING_WITH_15_4) += contiki/mac/simplerdc.o - endif -endif - -ccflags-$(CONFIG_NETWORKING_WITH_LOGGING) += -DUIP_CONF_LOGGING=1 - -obj-$(CONFIG_NETWORKING_WITH_LOGGING) += contiki/uip-log.o - -obj-$(CONFIG_NETWORKING_WITH_LOOPBACK) += net_driver_loopback.o -obj-$(CONFIG_NETWORKING_WITH_15_4_LOOPBACK) += dummy_15_4_radio.o -obj-$(CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART) += dummy_15_4_radio.o -obj-$(CONFIG_NETWORKING_WITH_15_4) += net_driver_15_4.o \ - contiki/packetbuf.o \ - contiki/queuebuf.o \ - contiki/mac/mac.o \ - contiki/mac/framer.o \ - contiki/mac/frame802154.o \ - contiki/mac/framer-802154.o \ - contiki/mac/mac-sequence.o - -obj-$(CONFIG_NETWORKING_WITH_15_4_MAC_NULL) += contiki/mac/nullmac.o -obj-$(CONFIG_NETWORKING_WITH_15_4_MAC_CSMA) += contiki/mac/csma.o - -obj-$(CONFIG_15_4_BEACON_SUPPORT) += contiki/mac/handler-802154.o - -obj-$(CONFIG_NETWORKING_WITH_BT) += net_driver_bt.o \ - contiki/packetbuf.o \ - contiki/queuebuf.o \ - contiki/mac/mac.o \ - contiki/mac/framer.o \ - contiki/mac/framer-nullmac.o \ - contiki/sicslowpan/null_fragmentation.o - -# At the moment we only need nullsec driver for 802.15.4 -#obj-$(CONFIG_NETWORKING_WITH_15_4) += contiki/llsec/ccm-star.o \ -# contiki/llsec/ccm-star.o \ -# contiki/llsec/anti-replay.o - -ifeq ($(CONFIG_NETWORKING_WITH_15_4),y) - obj-y += contiki/mac/nullmac.o \ - contiki/mac/framer-nullmac.o \ - contiki/mac/simplerdc.o -endif - -obj-$(CONFIG_NETWORKING_UART) += contiki/os/dev/slip.o \ - contiki/os/dev/slip-arch.o \ - net_driver_slip.o - -obj-$(CONFIG_ETHERNET) += net_driver_ethernet.o - -ccflags-$(CONFIG_TINYDTLS) += -DCONTIKI_TARGET_ZEPHYR=1 -ccflags-$(CONFIG_TINYDTLS) += -DWITH_SHA256=1 -ccflags-$(CONFIG_TINYDTLS) += -DDTLS_TICKS_PER_SECOND=sys_clock_ticks_per_sec -ccflags-$(CONFIG_TINYDTLS) += -I${srctree}/net/ip/contiki/os/sys -ccflags-$(CONFIG_TINYDTLS) += -I${srctree}/net/ip/tinydtls - -obj-$(CONFIG_TINYDTLS) += tinydtls/dtls.o \ - tinydtls/crypto.o \ - tinydtls/hmac.o \ - tinydtls/aes/rijndael.o \ - tinydtls/sha2/sha2.o \ - tinydtls/ccm.o \ - tinydtls/netq.o \ - tinydtls/dtls_time.o \ - tinydtls/peer.o \ - tinydtls/session.o \ - tinydtls/ecc/ecc.o - - -ifeq ($(CONFIG_TINYDTLS_DEBUG),) - ccflags-y += -DNDEBUG -endif -obj-$(CONFIG_TINYDTLS_DEBUG) += tinydtls/debug.o - -ccflags-$(CONFIG_ER_COAP) += -I${srctree}/net/ip/rest-engine -ccflags-$(CONFIG_ER_COAP) += -I${srctree}/net/ip/er-coap - -obj-$(CONFIG_ER_COAP) += er-coap/er-coap.o \ - er-coap/er-coap-engine.o \ - er-coap/er-coap-transactions.o \ - er-coap/er-coap-observe.o \ - er-coap/er-coap-separate.o \ - er-coap/er-coap-res-well-known-core.o \ - er-coap/er-coap-block1.o \ - er-coap/er-coap-context.o \ - rest-engine/rest-engine.o - -obj-$(CONFIG_ER_COAP_CLIENT) += er-coap/er-coap-observe-client.o - -obj-$(CONFIG_DHCP) += contiki/ip/dhcpc.o - -obj-$(CONFIG_NETWORKING_WITH_TRICKLE) += \ - contiki/trickle/trickle-timer.o diff --git a/net/ip/cc2520_15_4_radio.h b/net/ip/cc2520_15_4_radio.h deleted file mode 100644 index b980e0ef4830e0dafce16865ff9444103db24ebd..0000000000000000000000000000000000000000 --- a/net/ip/cc2520_15_4_radio.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef CC2520154RADIO_H -#define CC2520154RADIO_H - -#include "dev/radio.h" - -extern const struct radio_driver cc2520_15_4_radio_driver; - -#endif /* CC2520154RADIO_H */ diff --git a/net/ip/contiki/contiki-conf.h b/net/ip/contiki/contiki-conf.h deleted file mode 100644 index 6fc5ac63872ef206db2753dd3b83b002709a4c38..0000000000000000000000000000000000000000 --- a/net/ip/contiki/contiki-conf.h +++ /dev/null @@ -1,254 +0,0 @@ -/* contiki-conf.h - These settings override the default configuration */ - -/* - * Copyright (c) 2016 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#ifndef __CONTIKI_CONF_H__ -#define __CONTIKI_CONF_H__ - -#define PACK_ALIAS_STRUCT __attribute__((__packed__,__may_alias__)) - -#define CCIF -#define CLIF - -typedef uint32_t clock_time_t; -typedef unsigned int uip_stats_t; - -#define CLOCK_CONF_SECOND sys_clock_ticks_per_sec - -/* It is either IPv6 or IPv4 but not both at the same time. */ -#ifdef CONFIG_NETWORKING_WITH_IPV6 -#define NETSTACK_CONF_WITH_IPV6 1 -#define UIP_CONF_ICMP6 1 -#elif CONFIG_NETWORKING_WITH_IPV4 -#define NETSTACK_CONF_WITH_IPV6 0 -#else -#error "Either IPv6 or IPv4 needs to be supported." -#endif - -/* The actual MTU size is defined in uipopt.h */ -#define UIP_CONF_BUFFER_SIZE UIP_LINK_MTU - -#ifdef CONFIG_NETWORKING_WITH_TCP -#define UIP_CONF_TCP 1 - -#ifdef CONFIG_TCP_DISABLE_ACTIVE_OPEN -#define UIP_CONF_ACTIVE_OPEN 0 -#else /* CONFIG_TCP_DISABLE_ACTIVE_OPEN */ -#define UIP_CONF_ACTIVE_OPEN 1 -#endif /* CONFIG_TCP_DISABLE_ACTIVE_OPEN */ - -#if CONFIG_TCP_MSS > 0 -#define UIP_CONF_TCP_MSS CONFIG_TCP_MSS -#endif /* CONFIG_TCP_MSS */ - -#if CONFIG_TCP_RECEIVE_WINDOW > 0 -#define UIP_CONF_RECEIVE_WINDOW CONFIG_TCP_RECEIVE_WINDOW -#endif /* CONFIG_TCP_RECEIVE_WINDOW */ - -#else -#define UIP_CONF_TCP 0 -#endif - -/* We do not want to be a router */ -#define UIP_CONF_ROUTER 0 - -/* No Rime */ -#define NETSTACK_CONF_WITH_RIME 0 - -/* How many IPv6 addresses will be allocated for the user (default is 2). - * Increased this setting so that user can specify multicast addresses. - */ -#define UIP_CONF_DS6_ADDR_NBU 4 - -/* The queuebuf count defines how many fragments we are able to - * receive. Value 13 means that we can receive full IPv6 data - * (1280 bytes), we need also some extra buffers for temp use. - */ -#define QUEUEBUF_CONF_NUM (13 + 5) - -/* Do not just drop packets because of some other packet is sent. - * So queue the packet and send it later. - */ -#define UIP_CONF_IPV6_QUEUE_PKT 1 - -#ifdef SICSLOWPAN_CONF_ENABLE -/* Min and Max compressible UDP ports */ -#define SICSLOWPAN_UDP_PORT_MIN 0xF0B0 -#define SICSLOWPAN_UDP_PORT_MAX 0xF0BF /* F0B0 + 15 */ -#define NETSTACK_CONF_COMPRESS sicslowpan_compression -#ifdef CONFIG_NETWORKING_WITH_BT -#define NETSTACK_CONF_FRAGMENT null_fragmentation -#else -#define NETSTACK_CONF_FRAGMENT sicslowpan_fragmentation -#endif -#else -#define NETSTACK_CONF_COMPRESS null_compression -#define NETSTACK_CONF_FRAGMENT null_fragmentation -#endif /* SICSLOWPAN_CONF_ENABLE */ - -#ifdef CONFIG_NETWORKING_WITH_15_4 -#ifdef CONFIG_NETWORKING_WITH_15_4_PAN_ID -#define IEEE802154_CONF_PANID CONFIG_NETWORKING_WITH_15_4_PAN_ID -#endif /* CONFIG_NETWORKING_WITH_15_4_PAN_ID */ -#define NETSTACK_CONF_FRAMER framer_802154 -#ifdef CONFIG_NETWORKING_WITH_6LOWPAN -#if defined(CONFIG_NETWORKING_WITH_15_4_RDC_SICSLOWMAC) -#define NETSTACK_CONF_RDC sicslowmac_driver -#elif defined(CONFIG_NETWORKING_WITH_15_4_RDC_SIMPLE) -#define NETSTACK_CONF_RDC simplerdc_driver - -/* Simple RDC config*/ -#ifdef CONFIG_TI_CC2520_AUTO_ACK -#define SIMPLERDC_802154_AUTOACK 1 -#else -#define SIMPLERDC_802154_SEND_ACK 1 -#endif - -#ifdef CONFIG_NETWORKING_WITH_15_4_ALWAYS_ACK -#define SIMPLERDC_802154_ACK_REQ 1 -#endif -#define SIMPLERDC_MAX_RETRANSMISSIONS 3 - -#endif /* RDC driver */ -#endif /* CONFIG_NETWORKING_WITH_6LOWPAN */ -#ifdef CONFIG_NETWORKING_WITH_15_4_MAC_NULL -#define NETSTACK_CONF_MAC nullmac_driver -#endif -#ifdef CONFIG_NETWORKING_WITH_15_4_MAC_CSMA -#define NETSTACK_CONF_MAC csma_driver -#endif -#define LINKADDR_CONF_SIZE 8 -#define UIP_CONF_LL_802154 1 -#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 -#ifdef CONFIG_6LOWPAN_COMPRESSION_IPHC -#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_IPHC -#else /* 6lowpan compression method */ -#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_IPV6 -#endif /* 6lowpan compression method */ -#ifdef CONFIG_15_4_BEACON_SUPPORT -#define FRAMER_802154_HANDLER handler_802154_frame_received -#endif /* CONFIG_15_4_BEACON_SUPPORT */ -#ifdef CONFIG_15_4_BEACON_STATS -#define HANDLER_802154_CONF_STATS 1 -#endif /* CONFIG_15_4_BEACON_STATS */ -#else /* CONFIG_NETWORKING_WITH_15_4 */ -#define NETSTACK_CONF_FRAMER framer_nullmac -#define NETSTACK_CONF_RDC simplerdc_driver -#define NETSTACK_CONF_MAC nullmac_driver -#define LINKADDR_CONF_SIZE 6 -#ifdef CONFIG_NETWORKING_WITH_BT -#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_IPHC -#endif /* CONFIG_NETWORKING_WITH_BT */ -#endif /* CONFIG_NETWORKING_WITH_15_4 */ - -#define NETSTACK_CONF_LLSEC nullsec_driver - -#ifdef CONFIG_NETWORKING_WITH_15_4_TI_CC2520 -#define NETSTACK_CONF_RADIO cc2520_15_4_radio_driver -#endif - -#ifdef CONFIG_NETWORKING_WITH_RPL -#define UIP_MCAST6_CONF_ENGINE UIP_MCAST6_ENGINE_SMRF -#define UIP_CONF_IPV6_MULTICAST 1 -#ifdef CONFIG_RPL_WITH_MRHOF -#define RPL_CONF_OF rpl_mrhof -#else -#define RPL_CONF_OF rpl_of0 -#endif /* CONFIG_RPL_WITH_MRHOF */ -#ifdef CONFIG_RPL_PROBING -#define RPL_CONF_WITH_PROBING 1 -#else -#define RPL_CONF_WITH_PROBING 0 -#endif /* CONFIG_RPL_PROBING */ -#ifdef CONFIG_RPL_STATS -#define RPL_CONF_STATS 1 -#else -#define RPL_CONF_STATS 0 -#endif /* CONFIG_RPL_STATS */ -#else /* CONFIG_NETWORKING_WITH_RPL */ -#define RPL_CONF_STATS 0 -#endif - -#if defined(CONFIG_NETWORKING_STATISTICS) && defined(CONFIG_L2_BUFFERS) -#define NET_MAC_CONF_STATS 1 -#else -#define NET_MAC_CONF_STATS 0 -#endif - -#if defined(CONFIG_COAP_STATS) -#define NET_COAP_CONF_STATS 1 -#define NET_COAP_STAT(code) (net_coap_stats.code) -#else -#define NET_COAP_CONF_STATS 0 -#define NET_COAP_STAT(code) -#endif - -#ifdef CONFIG_NETWORKING_IPV6_NO_ND -/* Disabling ND will simplify the IPv6 address assignment. - * This should only be done in testing phase. - */ -#define UIP_CONF_ND6_SEND_NA 0 -#else -#define UIP_CONF_ND6_SEND_NA 1 -#endif - -#ifndef NETSTACK_CONF_RADIO -/* #error "No radio configured, cannot continue!" */ -#endif - -#ifdef CONFIG_ER_COAP -#ifndef REST -#define REST REGISTERED_ENGINE_ERBIUM -#endif -#endif - -#ifdef CONFIG_ER_COAP_WITH_DTLS -#define ER_COAP_WITH_DTLS 1 -#else -#define ER_COAP_WITH_DTLS 0 -#endif - -#ifdef CONFIG_ER_COAP_CLIENT -#define COAP_OBSERVE_CLIENT 1 -#else -#undef COAP_OBSERVE_CLIENT -#endif - -#ifdef CONFIG_NETWORKING_STATISTICS -#define UIP_CONF_STATISTICS 1 -#endif - -#ifdef CONFIG_ETHERNET -#define UIP_CONF_LLH_LEN 14 -#endif - -#if defined(CONFIG_UDP_MAX_CONNECTIONS) -#define UIP_CONF_UDP_CONNS CONFIG_UDP_MAX_CONNECTIONS -#endif - -#if defined(CONFIG_TCP_MAX_CONNECTIONS) -#define UIP_CONF_MAX_CONNECTIONS CONFIG_TCP_MAX_CONNECTIONS -#endif - -#if defined(CONFIG_NETWORKING_MAX_NEIGHBORS) -#define NBR_TABLE_CONF_MAX_NEIGHBORS CONFIG_NETWORKING_MAX_NEIGHBORS -#endif - -#endif /* __CONTIKI_CONF_H__ */ diff --git a/net/ip/contiki/contiki-default-conf.h b/net/ip/contiki/contiki-default-conf.h deleted file mode 100644 index 10c2fe27f1d5330502669b97d594271c1951a5dc..0000000000000000000000000000000000000000 --- a/net/ip/contiki/contiki-default-conf.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef CONTIKI_DEFAULT_CONF_H -#define CONTIKI_DEFAULT_CONF_H - -/*---------------------------------------------------------------------------*/ -/* Netstack configuration - * - * The netstack configuration is typically overridden by the platform - * configuration, as defined in contiki-conf.h - */ - -/* NETSTACK_CONF_RADIO specifies the radio driver. The radio driver - typically depends on the radio used on the target hardware. */ -#ifndef NETSTACK_CONF_RADIO -#if defined (CONFIG_NETWORKING_WITH_15_4_LOOPBACK) -#define NETSTACK_CONF_RADIO dummy154radio_driver -#elif defined (CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART) -#define NETSTACK_CONF_RADIO dummy154radio_driver -#else -#define NETSTACK_CONF_RADIO nullradio_driver -#endif /* CONFIG_NETWORKING_WITH_15_4_LOOPBACK */ -/* #define NETSTACK_CONF_RADIO cc2420_driver */ -#endif /* NETSTACK_CONF_RADIO */ - -/* NETSTACK_CONF_FRAMER specifies the over-the-air frame format used - by Contiki radio packets. For IEEE 802.15.4 radios, use the - framer_802154 driver. */ -#ifndef NETSTACK_CONF_FRAMER -#define NETSTACK_CONF_FRAMER framer_nullmac -/* #define NETSTACK_CONF_FRAMER framer_802154 */ -#endif /* NETSTACK_CONF_FRAMER */ - -/* NETSTACK_CONF_RDC specifies the Radio Duty Cycling (RDC) layer. The - simplerdc_driver never turns the radio off and is compatible with all - radios, but consumes a lot of power. The contikimac_driver is - highly power-efficent and allows sleepy routers, but is not - compatible with all radios. */ -#ifndef NETSTACK_CONF_RDC -#define NETSTACK_CONF_RDC simplerdc_driver -/* #define NETSTACK_CONF_RDC contikimac_driver */ -#endif /* NETSTACK_CONF_RDC */ - -/* NETSTACK_CONF_MAC specifies the Medium Access Control (MAC) - layer. The nullmac_driver does not provide any MAC - functionality. The csma_driver is the default CSMA MAC layer, but - is not compatible with all radios. */ -#ifndef NETSTACK_CONF_MAC -#define NETSTACK_CONF_MAC nullmac_driver -/* #define NETSTACK_CONF_MAC csma_driver */ -#endif /* NETSTACK_CONF_MAC */ - -/* NETSTACK_CONF_LLSEC specifies the link layer security driver. */ -#ifndef NETSTACK_CONF_LLSEC -#define NETSTACK_CONF_LLSEC nullsec_driver -#endif /* NETSTACK_CONF_LLSEC */ - -#ifndef NETSTACK_CONF_FRAGMENT -#define NETSTACK_CONF_FRAGMENT null_fragmentation -#endif /* NETSTACK_CONF_FRAGMENT */ - -#ifndef NETSTACK_CONF_COMPRESS -#define NETSTACK_CONF_COMPRESS null_compression -#endif /* NETSTACK_CONF_COMPRESS */ - -/* To avoid unnecessary complexity, we assume the common case of - a constant LoWPAN-wide IEEE 802.15.4 security level, which - can be specified by defining LLSEC802154_CONF_SECURITY_LEVEL. */ -#ifndef LLSEC802154_CONF_SECURITY_LEVEL -#define LLSEC802154_CONF_SECURITY_LEVEL 0 -#endif /* LLSEC802154_CONF_SECURITY_LEVEL */ - -/* NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE specifies the channel check - rate of the RDC layer. This defines how often the RDC will wake up - and check for radio channel activity. A higher check rate results - in higher communication performance at the cost of a higher power - consumption. */ -#ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE -#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 -#endif /* NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE */ - -/*---------------------------------------------------------------------------*/ -/* Packet buffer size options. - * - * The packet buffer size options can be tweaked on a per-project - * basis to reduce memory consumption. - */ - -/* QUEUEBUF_CONF_NUM specifies the number of queue buffers. Queue - buffers are used throughout the Contiki netstack but the - configuration option can be tweaked to save memory. Performance can - suffer with a too low number of queue buffers though. */ -#ifndef QUEUEBUF_CONF_NUM -#define QUEUEBUF_CONF_NUM 8 -#endif /* QUEUEBUF_CONF_NUM */ -/*---------------------------------------------------------------------------*/ -/* uIPv6 configuration options. - * - * Many of the uIPv6 configuration options can be overriden by a - * project-specific configuration to save memory. - */ - -/* NETSTACK_CONF_WITH_IPV6 specifies whether or not IPv6 should be used. If IPv6 - is not used, IPv4 is used instead. */ -#ifndef NETSTACK_CONF_WITH_IPV6 -#define NETSTACK_CONF_WITH_IPV6 0 -#endif /* NETSTACK_CONF_WITH_IPV6 */ - -/* UIP_CONF_BUFFER_SIZE specifies how much memory should be reserved - for the uIP packet buffer. This sets an upper bound on the largest - IP packet that can be received by the system. */ -#ifndef UIP_CONF_BUFFER_SIZE -#define UIP_CONF_BUFFER_SIZE 128 -#endif /* UIP_CONF_BUFFER_SIZE */ - -/* UIP_CONF_ROUTER specifies if the IPv6 node should be a router or - not. By default, all Contiki nodes are routers. */ -#ifndef UIP_CONF_ROUTER -#define UIP_CONF_ROUTER 1 -#endif /* UIP_CONF_ROUTER */ - -/* UIP_CONF_IPV6_RPL specifies if RPL is to be used for IPv6 - routing. */ -#ifndef UIP_CONF_IPV6_RPL -#define UIP_CONF_IPV6_RPL 1 -#endif /* UIP_CONF_IPV6_RPL */ - -/* UIP_CONF_MAX_ROUTES specifies the maximum number of routes that each - node will be able to handle. */ -#ifndef UIP_CONF_MAX_ROUTES -#define UIP_CONF_MAX_ROUTES 20 -#endif /* UIP_CONF_MAX_ROUTES */ - -/* UIP_CONF_UDP specifies if UDP support should be included or - not. Disabling UDP saves memory but breaks a lot of stuff. */ -#ifndef UIP_CONF_UDP -#define UIP_CONF_UDP 1 -#endif /* UIP_CONF_UDP */ - -/* UIP_CONF_MAX_CONNECTIONS specifies the maximum number of - simultaneous TCP connections. */ -#ifndef UIP_CONF_MAX_CONNECTIONS -#define UIP_CONF_MAX_CONNECTIONS 8 -#endif /* UIP_CONF_MAX_CONNECTIONS */ - -/* UIP_CONF_TCP specifies if TCP support should be included or - not. Disabling TCP saves memory. */ -#ifndef UIP_CONF_TCP -#define UIP_CONF_TCP 1 -#endif /* UIP_CONF_TCP */ - -/* UIP_CONF_MAX_CONNECTIONS specifies the maximum number of - simultaneous TCP connections. */ -#ifndef UIP_CONF_MAX_CONNECTIONS -#define UIP_CONF_MAX_CONNECTIONS 8 -#endif /* UIP_CONF_MAX_CONNECTIONS */ - - -/* UIP_CONF_TCP_SPLIT enables a performance optimization hack, where - each maximum-sized TCP segment is split into two, to avoid the - performance degradation that is caused by delayed ACKs. */ -#ifndef UIP_CONF_TCP_SPLIT -#define UIP_CONF_TCP_SPLIT 0 -#endif /* UIP_CONF_TCP_SPLIT */ - -/* NBR_TABLE_CONF_MAX_NEIGHBORS specifies the maximum number of neighbors - that each node will be able to handle. */ -#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS -#define NBR_TABLE_CONF_MAX_NEIGHBORS 8 -#endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */ - -/* UIP_CONF_ND6_SEND_NA enables standard IPv6 Neighbor Discovery Protocol. - This is unneeded when RPL is used. Disable to save ROM and a little RAM. */ -#ifndef UIP_CONF_ND6_SEND_NA -#define UIP_CONF_ND6_SEND_NA 1 -#endif /* UIP_CONF_ND6_SEND_NA */ - -/*---------------------------------------------------------------------------*/ -/* 6lowpan configuration options. - * - * These options change the behavior of the 6lowpan header compression - * code (sicslowpan). They typically depend on the type of radio used - * on the target platform, and are therefore platform-specific. - */ - -/* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS specifies how many times the - MAC layer should resend packets if no link-layer ACK was - received. This only makes sense with the csma_driver - NETSTACK_CONF_MAC. */ -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 4 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ - -/* SICSLOWPAN_CONF_FRAG specifies if 6lowpan fragmentation should be - used or not. Fragmentation is on by default. */ -#ifndef SICSLOWPAN_CONF_FRAG -#define SICSLOWPAN_CONF_FRAG 1 -#endif /* SICSLOWPAN_CONF_FRAG */ - -/* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD is the maximum available size for - frame headers, link layer security-related overhead, as well as - 6LoWPAN payload. By default, SICSLOWPAN_CONF_MAC_MAX_PAYLOAD is - 127 bytes (MTU of 802.15.4) - 2 bytes (Footer of 802.15.4). */ -#ifndef SICSLOWPAN_CONF_MAC_MAX_PAYLOAD -#define SICSLOWPAN_CONF_MAC_MAX_PAYLOAD (127 - 2) -#endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */ - -/* SICSLOWPAN_CONF_COMPRESSION_THRESHOLD sets a lower threshold for - when packets should not be compressed. This is used by ContikiMAC, - which requires packets to be larger than a given minimum size. */ -#ifndef SICSLOWPAN_CONF_COMPRESSION_THRESHOLD -#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 0 -/* #define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63 */ -#endif /* SICSLOWPAN_CONF_COMPRESSION_THRESHOLD */ - -/* SICSLOWPAN_CONF_COMPRESSION specifies what 6lowpan compression - mechanism to be used. 6lowpan hc06 is the default in Contiki. */ -#ifndef SICSLOWPAN_CONF_COMPRESSION -#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 -#endif /* SICSLOWPAN_CONF_COMPRESSION */ - -/*---------------------------------------------------------------------------*/ -/* ContikiMAC configuration options. - * - * These are typically configured on a per-platform basis. - */ - -/* CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION specifies if ContikiMAC - should optimize for the phase of neighbors. The phase optimization - may reduce power consumption but is not compatible with all timer - settings and is therefore off by default. */ -#ifndef CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION -#define CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION 0 -#endif /* CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION */ - - -#endif /* CONTIKI_DEFAULT_CONF_H */ diff --git a/net/ip/contiki/contiki-lib.h b/net/ip/contiki/contiki-lib.h deleted file mode 100644 index 7ff67fbb02b56fc6ef43fbbdc0bd96f7d76cf3ff..0000000000000000000000000000000000000000 --- a/net/ip/contiki/contiki-lib.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ -#ifndef CONTIKI_LIB_H_ -#define CONTIKI_LIB_H_ - -#include "contiki.h" -#include "lib/list.h" -#include "lib/memb.h" -#include "lib/mmem.h" -#include "lib/random.h" - -#endif /* CONTIKI_LIB_H_ */ diff --git a/net/ip/contiki/contiki-net.h b/net/ip/contiki/contiki-net.h deleted file mode 100644 index a596cbfe7db109bf0ec6b4f795ef33d64f7b39bf..0000000000000000000000000000000000000000 --- a/net/ip/contiki/contiki-net.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ -#ifndef CONTIKI_NET_H_ -#define CONTIKI_NET_H_ - -#include "contiki.h" - -#include "contiki/ip/uip.h" -#include "contiki/ip/uiplib.h" -#include "contiki/ip/uip-udp-packet.h" -#include "contiki/ip/simple-udp.h" -#include "contiki/ip/uip-nameserver.h" - -#if NETSTACK_CONF_WITH_IPV6 -#include "contiki/ipv6/uip-icmp6.h" -#include "contiki/ipv6/uip-ds6.h" -#endif /* NETSTACK_CONF_WITH_IPV6 */ - -#if UIP_TCP -/* psock.h is only needed for TCP */ -#include "contiki/ip/psock.h" -#endif - -#include "contiki/ip/udp-socket.h" - -#include "contiki/packetbuf.h" - -#endif /* CONTIKI_NET_H_ */ diff --git a/net/ip/contiki/contiki-version.h b/net/ip/contiki/contiki-version.h deleted file mode 100644 index 35b61a9ea7015b0c475cee587c79baa045460cfd..0000000000000000000000000000000000000000 --- a/net/ip/contiki/contiki-version.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ -#ifndef __CONTIKI_VERSION__ -#define __CONTIKI_VERSION__ - -#ifndef CONTIKI_VERSION_STRING -#define CONTIKI_VERSION_STRING "Contiki 3.x" -#endif /* CONTIKI_VERSION_STRING */ - -#endif /* __CONTIKI_VERSION__ */ diff --git a/net/ip/contiki/contiki.h b/net/ip/contiki/contiki.h deleted file mode 100644 index a0580f875999fe66f707858c8e4b887e02893c7f..0000000000000000000000000000000000000000 --- a/net/ip/contiki/contiki.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ - -#ifndef CONTIKI_H_ -#define CONTIKI_H_ - -#include "contiki-version.h" -#include "contiki-conf.h" -#include "contiki-default-conf.h" - -#include "sys/process.h" -#include "sys/autostart.h" - -#include "sys/timer.h" -#include "sys/ctimer.h" -#include "sys/etimer.h" -#include "sys/rtimer.h" - -#include "sys/pt.h" - -#include "sys/procinit.h" - -#include "sys/loader.h" -#include "sys/clock.h" - -#include "sys/energest.h" - -#include - -#endif /* CONTIKI_H_ */ diff --git a/net/ip/contiki/ip/dhcpc.c b/net/ip/contiki/ip/dhcpc.c deleted file mode 100644 index d2a8f8add4737e1ff6061cd6a649bbb5c9f17110..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/dhcpc.c +++ /dev/null @@ -1,495 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#include -#include - -#include - -#include "contiki.h" -#include "contiki-net.h" -#include "contiki/ip/dhcpc.h" - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_DHCP -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#define STATE_INITIAL 0 -#define STATE_SENDING 1 -#define STATE_OFFER_RECEIVED 2 -#define STATE_CONFIG_RECEIVED 3 - -static struct dhcpc_state s; -dhcpc_configured configure_cb = NULL; -dhcpc_unconfigured unconfigure_cb = NULL; - -struct dhcp_msg { - uint8_t op, htype, hlen, hops; - uint8_t xid[4]; - uint16_t secs, flags; - uint8_t ciaddr[4]; - uint8_t yiaddr[4]; - uint8_t siaddr[4]; - uint8_t giaddr[4]; - uint8_t chaddr[16]; -#ifndef UIP_CONF_DHCP_LIGHT - uint8_t sname[64]; - uint8_t file[128]; -#endif - uint8_t options[312]; -} __packed; - -#ifdef CONFIG_DHCP_BROADCAST -#define BOOTP_BROADCAST 0x8000 -#elif CONFIG_DHCP_UNICAST -#define BOOTP_UNICAST 0x0000 -#endif - -#define DHCP_REQUEST 1 -#define DHCP_REPLY 2 -#define DHCP_HTYPE_ETHERNET 1 -#define DHCP_HLEN_ETHERNET 6 -#define DHCP_MSG_LEN 236 - -#define DHCPC_SERVER_PORT 67 -#define DHCPC_CLIENT_PORT 68 - -#define DHCPDISCOVER 1 -#define DHCPOFFER 2 -#define DHCPREQUEST 3 -#define DHCPDECLINE 4 -#define DHCPACK 5 -#define DHCPNAK 6 -#define DHCPRELEASE 7 - -#define DHCP_OPTION_SUBNET_MASK 1 -#define DHCP_OPTION_ROUTER 3 -#define DHCP_OPTION_DNS_SERVER 6 -#define DHCP_OPTION_REQ_IPADDR 50 -#define DHCP_OPTION_LEASE_TIME 51 -#define DHCP_OPTION_MSG_TYPE 53 -#define DHCP_OPTION_SERVER_ID 54 -#define DHCP_OPTION_REQ_LIST 55 -#define DHCP_OPTION_END 255 - -static uint32_t xid; -static const uint8_t magic_cookie[4] = {99, 130, 83, 99}; - -/*---------------------------------------------------------------------------*/ -static void -configure_dhcpc(struct dhcpc_state *s) -{ - uip_sethostaddr(&s->ipaddr); - uip_setnetmask(&s->netmask); - uip_setdraddr(&s->default_router); - uip_nameserver_update(&s->dnsaddr, UIP_NAMESERVER_INFINITE_LIFETIME); - - if(configure_cb) - configure_cb(); -} -/*---------------------------------------------------------------------------*/ -static void -unconfigure_dhcpc(struct dhcpc_state *s) -{ - if(unconfigure_cb) - unconfigure_cb(); -} -/*---------------------------------------------------------------------------*/ -static uint8_t * -add_msg_type(uint8_t *optptr, uint8_t type) -{ - *optptr++ = DHCP_OPTION_MSG_TYPE; - *optptr++ = 1; - *optptr++ = type; - return optptr; -} -/*---------------------------------------------------------------------------*/ -static uint8_t * -add_server_id(uint8_t *optptr) -{ - *optptr++ = DHCP_OPTION_SERVER_ID; - *optptr++ = 4; - memcpy(optptr, s.serverid, 4); - return optptr + 4; -} -/*---------------------------------------------------------------------------*/ -static uint8_t * -add_req_ipaddr(uint8_t *optptr) -{ - *optptr++ = DHCP_OPTION_REQ_IPADDR; - *optptr++ = 4; - memcpy(optptr, s.ipaddr.u16, 4); - return optptr + 4; -} -/*---------------------------------------------------------------------------*/ -static uint8_t * -add_req_options(uint8_t *optptr) -{ - *optptr++ = DHCP_OPTION_REQ_LIST; - *optptr++ = 3; - *optptr++ = DHCP_OPTION_SUBNET_MASK; - *optptr++ = DHCP_OPTION_ROUTER; - *optptr++ = DHCP_OPTION_DNS_SERVER; - return optptr; -} -/*---------------------------------------------------------------------------*/ -static uint8_t * -add_end(uint8_t *optptr) -{ - *optptr++ = DHCP_OPTION_END; - return optptr; -} -/*---------------------------------------------------------------------------*/ -static void -create_msg(struct dhcp_msg *m) -{ - m->op = DHCP_REQUEST; - m->htype = DHCP_HTYPE_ETHERNET; - m->hlen = s.mac_len; - m->hops = 0; - memcpy(m->xid, &xid, sizeof(m->xid)); - m->secs = 0; -#ifdef CONFIG_DHCP_BROADCAST - m->flags = UIP_HTONS(BOOTP_BROADCAST); /* Broadcast bit. */ -#elif CONFIG_DHCP_UNICAST - m->flags = UIP_HTONS(BOOTP_UNICAST); /* Unicast bit. */ -#endif - - /* uip_ipaddr_copy(m->ciaddr, uip_hostaddr);*/ - memcpy(m->ciaddr, uip_hostaddr.u16, sizeof(m->ciaddr)); - memset(m->yiaddr, 0, sizeof(m->yiaddr)); - memset(m->siaddr, 0, sizeof(m->siaddr)); - memset(m->giaddr, 0, sizeof(m->giaddr)); - memcpy(m->chaddr, s.mac_addr, s.mac_len); - memset(&m->chaddr[s.mac_len], 0, sizeof(m->chaddr) - s.mac_len); -#ifndef UIP_CONF_DHCP_LIGHT - memset(m->sname, 0, sizeof(m->sname)); - memset(m->file, 0, sizeof(m->file)); -#endif - - memcpy(m->options, magic_cookie, sizeof(magic_cookie)); -} -/*---------------------------------------------------------------------------*/ -static void -send_discover(void) -{ - uint8_t *end; - struct dhcp_msg *m; - struct net_buf *buf; - int len; - - buf = ip_buf_get_reserve_tx(UIP_LLH_LEN + UIP_IPUDPH_LEN); - if(!buf) { - PRINTF("dhcp: failed to get buffer\n"); - return; - } - - uip_set_udp_conn(buf) = s.conn; - m = (struct dhcp_msg *)uip_appdata(buf); - - create_msg(m); - - end = add_msg_type(&m->options[4], DHCPDISCOVER); - end = add_req_options(end); - end = add_end(end); - len = (int)(end - (uint8_t *)uip_appdata(buf)); - uip_appdatalen(buf) = len; - - uip_send_udp(buf, uip_appdata(buf), len); -} -/*---------------------------------------------------------------------------*/ -static void -send_request(void) -{ - uint8_t *end; - struct dhcp_msg *m; - struct net_buf *buf; - int len; - - buf = ip_buf_get_reserve_tx(UIP_LLH_LEN + UIP_IPUDPH_LEN); - if(!buf) { - PRINTF("dhcp: failed to get buffer\n"); - return; - } - - uip_set_udp_conn(buf) = s.conn; - m = (struct dhcp_msg *)uip_appdata(buf); - - create_msg(m); - - end = add_msg_type(&m->options[4], DHCPREQUEST); - end = add_server_id(end); - end = add_req_ipaddr(end); - end = add_end(end); - len = (int)(end - (uint8_t *)uip_appdata(buf)); - uip_appdatalen(buf) = len; - - uip_send_udp(buf, uip_appdata(buf), len); -} -/*---------------------------------------------------------------------------*/ -static uint8_t -parse_options(uint8_t *optptr, int len) -{ - uint8_t *end = optptr + len; - uint8_t type = 0; - - while(optptr < end) { - switch(*optptr) { - case DHCP_OPTION_SUBNET_MASK: - memcpy(s.netmask.u16, optptr + 2, 4); - break; - case DHCP_OPTION_ROUTER: - memcpy(s.default_router.u16, optptr + 2, 4); - break; - case DHCP_OPTION_DNS_SERVER: - memcpy(s.dnsaddr.u16, optptr + 2, 4); - break; - case DHCP_OPTION_MSG_TYPE: - type = *(optptr + 2); - break; - case DHCP_OPTION_SERVER_ID: - memcpy(s.serverid, optptr + 2, 4); - break; - case DHCP_OPTION_LEASE_TIME: - memcpy(s.lease_time, optptr + 2, 4); - break; - case DHCP_OPTION_END: - return type; - } - - optptr += optptr[1] + 2; - } - return type; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -parse_msg(struct net_buf *buf) -{ - struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata(buf); - uint8_t ret = 0; - - if(m->op == DHCP_REPLY && - memcmp(m->xid, &xid, sizeof(xid)) == 0 && - memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) { - memcpy(s.ipaddr.u16, m->yiaddr, 4); - ret = parse_options(&m->options[4], uip_datalen(buf)); - } - - ip_buf_unref(buf); - return ret; -} -/*---------------------------------------------------------------------------*/ -/* - * Is this a "fresh" reply for me? If it is, return the type. - */ -static int -msg_for_me(struct net_buf *buf) -{ - struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata(buf); - uint8_t *optptr = &m->options[4]; - uint8_t *end = (uint8_t*)uip_appdata(buf) + uip_datalen(buf); - - if(m->op == DHCP_REPLY && - memcmp(m->xid, &xid, sizeof(xid)) == 0 && - memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) { - while(optptr < end) { - if(*optptr == DHCP_OPTION_MSG_TYPE) { - return *(optptr + 2); - } else if (*optptr == DHCP_OPTION_END) { - return -1; - } - optptr += optptr[1] + 2; - } - } - return -1; -} -/*---------------------------------------------------------------------------*/ -PROCESS(dhcp_process, "DHCP process"); -PROCESS_THREAD(dhcp_process, ev, data, buf, user_data) -{ - clock_time_t ticks; - PROCESS_BEGIN(); - - init: - xid++; - s.state = STATE_SENDING; - s.ticks = CLOCK_SECOND * 8; - while (1) { - send_discover(); - etimer_set(&s.etimer, s.ticks, &dhcp_process); - do { - PROCESS_YIELD(); - if(ev == tcpip_event && uip_newdata(buf) && msg_for_me(buf) == DHCPOFFER) { - parse_msg(buf); - s.state = STATE_OFFER_RECEIVED; - goto selecting; - } - } while (!etimer_expired(&s.etimer)); - - if(s.ticks < CLOCK_SECOND * 60) { - s.ticks *= 2; - } - } - - selecting: - s.ticks = CLOCK_SECOND; - do { - send_request(); - etimer_set(&s.etimer, s.ticks, &dhcp_process); - do { - PROCESS_YIELD(); - if(ev == tcpip_event && uip_newdata(buf) && msg_for_me(buf) == DHCPACK) { - parse_msg(buf); - s.state = STATE_CONFIG_RECEIVED; - goto bound; - } - } while (!etimer_expired(&s.etimer)); - - if(s.ticks <= CLOCK_SECOND * 10) { - s.ticks += CLOCK_SECOND; - } else { - goto init; - } - } while(s.state != STATE_CONFIG_RECEIVED); - - bound: - - PRINTF("Got IP address %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.ipaddr)); - PRINTF("Got netmask %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.netmask)); - PRINTF("Got DNS server %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.dnsaddr)); - PRINTF("Got default router %d.%d.%d.%d\n", - uip_ipaddr_to_quad(&s.default_router)); - PRINTF("Lease expires in %ld seconds\n", - uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1])); - - configure_dhcpc(&s); - -#define MAX_TICKS (~((clock_time_t)0) / 2) -#define MAX_TICKS32 (~((uint32_t)0)) -#define IMIN(a, b) ((a) < (b) ? (a) : (b)) - - if((uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]))*CLOCK_SECOND/2 - <= MAX_TICKS32) { - s.ticks = (uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]) - )*CLOCK_SECOND/2; - } else { - s.ticks = MAX_TICKS32; - } - - while(s.ticks > 0) { - ticks = IMIN(s.ticks, MAX_TICKS); - s.ticks -= ticks; - etimer_set(&s.etimer, ticks, &dhcp_process); - PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_TIMER); - } - - if((uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]))*CLOCK_SECOND/2 - <= MAX_TICKS32) { - s.ticks = (uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]) - )*CLOCK_SECOND/2; - } else { - s.ticks = MAX_TICKS32; - } - - /* renewing: */ - do { - send_request(); - ticks = IMIN(s.ticks / 2, MAX_TICKS); - s.ticks -= ticks; - etimer_set(&s.etimer, ticks, &dhcp_process); - do { - PROCESS_YIELD(); - if(ev == tcpip_event && uip_newdata(buf) && msg_for_me(buf) == DHCPACK) { - parse_msg(buf); - goto bound; - } - } while(!etimer_expired(&s.etimer)); - } while(s.ticks >= CLOCK_SECOND*3); - - /* rebinding: */ - - /* lease_expired: */ - unconfigure_dhcpc(&s); - goto init; - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ -void -dhcpc_init(const void *mac_addr, int mac_len) -{ - uip_ipaddr_t addr; - uip_ipaddr_t ipaddr; - - s.mac_addr = mac_addr; - s.mac_len = mac_len; - - s.state = STATE_INITIAL; - - uip_ipaddr(&ipaddr, 0,0,0,0); - uip_sethostaddr(&ipaddr); - - uip_ipaddr(&addr, 255,255,255,255); - s.conn = udp_new(&addr, UIP_HTONS(DHCPC_SERVER_PORT), NULL); - if(s.conn != NULL) { - udp_bind(s.conn, UIP_HTONS(DHCPC_CLIENT_PORT)); - } - process_start(&dhcp_process, NULL, NULL); -} - -/*---------------------------------------------------------------------------*/ -void -dhcpc_appcall(process_event_t ev, struct net_buf *buf) -{ - if(ev == tcpip_event || ev == PROCESS_EVENT_TIMER) { - process_post_synch(&dhcp_process, ev, NULL, buf); - } -} -/*---------------------------------------------------------------------------*/ -int msg_for_dhcpc(struct net_buf *buf) -{ - int msg; - - msg = msg_for_me(buf); - if(msg == DHCPOFFER || msg == DHCPACK) - return 1; - - return 0; -} -/*---------------------------------------------------------------------------*/ -void dhcpc_set_callbacks(dhcpc_configured conf, dhcpc_unconfigured unconf) -{ - configure_cb = conf; - unconfigure_cb = unconf; -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/ip/dhcpc.h b/net/ip/contiki/ip/dhcpc.h deleted file mode 100644 index a34e691fbb9add78c684198b636032e95e8f7085..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/dhcpc.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ -#ifndef DHCPC_H_ -#define DHCPC_H_ -typedef void (*dhcpc_configured)(void); -typedef void (*dhcpc_unconfigured)(void); - -struct dhcpc_state { - struct pt pt; - char state; - struct uip_udp_conn *conn; - struct etimer etimer; - uint32_t ticks; - const void *mac_addr; - int mac_len; - - uint8_t serverid[4]; - - uint16_t lease_time[2]; - uip_ipaddr_t ipaddr; - uip_ipaddr_t netmask; - uip_ipaddr_t dnsaddr; - uip_ipaddr_t default_router; -}; - -void dhcpc_init(const void *mac_addr, int mac_len); -void dhcpc_appcall(process_event_t ev, struct net_buf *buf); -int msg_for_dhcpc(struct net_buf *buf); - -void dhcpc_set_callbacks(dhcpc_configured conf, dhcpc_unconfigured unconf); - -#endif /* DHCPC_H_ */ diff --git a/net/ip/contiki/ip/psock.c b/net/ip/contiki/ip/psock.c deleted file mode 100644 index 1ae215ac46729a74a2d8aa6bc592664f06efe3b4..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/psock.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ - -#include - -#include - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_TCP_PSOCK -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#include "contiki/ip/psock.h" - -#define STATE_NONE 0 -#define STATE_ACKED 1 -#define STATE_READ 2 -#define STATE_BLOCKED_NEWDATA 3 -#define STATE_BLOCKED_CLOSE 4 -#define STATE_BLOCKED_SEND 5 -#define STATE_DATA_SENT 6 - -/* - * Return value of the buffering functions that indicates that a - * buffer was not filled by incoming data. - * - */ -#define BUF_NOT_FULL 0 -#define BUF_NOT_FOUND 0 - -/* - * Return value of the buffering functions that indicates that a - * buffer was completely filled by incoming data. - * - */ -#define BUF_FULL 1 - -/* - * Return value of the buffering functions that indicates that an - * end-marker byte was found. - * - */ -#define BUF_FOUND 2 - -/*---------------------------------------------------------------------------*/ -static void -buf_setup(struct psock_buf *buf, - uint8_t *bufptr, uint16_t bufsize) -{ - buf->ptr = bufptr; - buf->left = bufsize; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -buf_bufdata(struct psock_buf *buf, uint16_t len, - uint8_t **dataptr, uint16_t *datalen) -{ - if(*datalen < buf->left) { - PRINTF("%d: *datalen(%d) < left(%d), copy buf->ptr(%p) <- *dataptr(%p)\n", - __LINE__, *datalen, buf->left, buf->ptr, *dataptr); - memcpy(buf->ptr, *dataptr, *datalen); - buf->ptr += *datalen; - buf->left -= *datalen; - *dataptr += *datalen; - *datalen = 0; - return BUF_NOT_FULL; - } else if(*datalen == buf->left) { - PRINTF("%d: *datalen(%d) == left(%d), copy buf->ptr(%p) <- *dataptr(%p)\n", - __LINE__, *datalen, buf->left, buf->ptr, *dataptr); - memcpy(buf->ptr, *dataptr, *datalen); - buf->ptr += *datalen; - buf->left = 0; - *dataptr += *datalen; - *datalen = 0; - return BUF_FULL; - } else { - PRINTF("%d: *datalen(%d) > left(%d), copy buf->ptr(%p) <- buf->left(%p)\n", - __LINE__, *datalen, buf->left, buf->ptr, buf->left); - memcpy(buf->ptr, *dataptr, buf->left); - buf->ptr += buf->left; - *datalen -= buf->left; - *dataptr += buf->left; - buf->left = 0; - return BUF_FULL; - } -} -/*---------------------------------------------------------------------------*/ -static uint8_t -buf_bufto(CC_REGISTER_ARG struct psock_buf *buf, uint8_t endmarker, - CC_REGISTER_ARG uint8_t **dataptr, CC_REGISTER_ARG uint16_t *datalen) -{ - uint8_t c; - while(buf->left > 0 && *datalen > 0) { - c = *buf->ptr = **dataptr; - ++*dataptr; - ++buf->ptr; - --*datalen; - --buf->left; - - if(c == endmarker) { - return BUF_FOUND; - } - } - - if(*datalen == 0) { - return BUF_NOT_FOUND; - } - - return BUF_FULL; -} -/*---------------------------------------------------------------------------*/ -static char -data_is_sent_and_acked(CC_REGISTER_ARG struct psock *s) -{ - /* If data has previously been sent, and the data has been acked, we - increase the send pointer and call send_data() to send more - data. */ - PRINTF("%s: psock %p buf %p data[%p..%p] sendptr %p sendlen %d mss %d\n", - __func__, s, s->net_buf, ip_buf_appdata(s->net_buf), - ip_buf_appdata(s->net_buf) + ip_buf_appdatalen(s->net_buf), - s->sendptr, s->sendlen, - uip_mss(s->net_buf)); - - if(s->state != STATE_DATA_SENT || uip_rexmit(s->net_buf)) { - if(s->sendlen > uip_mss(s->net_buf)) { - uip_send(s->net_buf, s->sendptr, uip_mss(s->net_buf)); - } else { - uip_send(s->net_buf, s->sendptr, s->sendlen); - } - s->state = STATE_DATA_SENT; - return 0; - } else if(s->state == STATE_DATA_SENT && uip_acked(s->net_buf)) { - if(s->sendlen > uip_mss(s->net_buf)) { - s->sendlen -= uip_mss(s->net_buf); - s->sendptr += uip_mss(s->net_buf); - } else { - s->sendptr += s->sendlen; - s->sendlen = 0; - } - s->state = STATE_ACKED; - return 1; - } - return 0; -} -/*---------------------------------------------------------------------------*/ -PT_THREAD(psock_send(CC_REGISTER_ARG struct psock *s, struct net_buf *net_buf)) -{ - PT_BEGIN(&s->psockpt); - - PRINTF("%s: psock %p buf %p len %d\n", __func__, s, net_buf, - ip_buf_appdatalen(net_buf)); - - /* If there is no data to send, we exit immediately. */ - if(ip_buf_appdatalen(net_buf) == 0) { - PT_EXIT(&s->psockpt); - } - - /* Save the length of and a pointer to the data that is to be - sent. */ - s->sendptr = ip_buf_appdata(net_buf); - s->sendlen = ip_buf_appdatalen(net_buf); - s->net_buf = net_buf; - - s->state = STATE_NONE; - - /* We loop here until all data is sent. The s->sendlen variable is - updated by the data_sent() function. */ - while(s->sendlen > 0) { - - /* - * The protothread will wait here until all data has been - * acknowledged and sent (data_is_acked_and_send() returns 1). - */ - PT_WAIT_UNTIL(&s->psockpt, data_is_sent_and_acked(s)); - } - - s->state = STATE_NONE; - - PT_END(&s->psockpt); -} -/*---------------------------------------------------------------------------*/ -PT_THREAD(psock_generator_send(CC_REGISTER_ARG struct psock *s, - unsigned short (*generate)(void *), void *arg)) -{ - PT_BEGIN(&s->psockpt); - - /* Ensure that there is a generator function to call. */ - if(generate == NULL) { - PT_EXIT(&s->psockpt); - } - - s->state = STATE_NONE; - do { - /* Call the generator function to generate the data in the - uip_appdata buffer. */ - s->sendlen = generate(arg); - s->sendptr = uip_appdata(s->net_buf); - - if(s->sendlen > uip_mss(s->net_buf)) { - uip_send(s->net_buf, s->sendptr, uip_mss(s->net_buf)); - } else { - uip_send(s->net_buf, s->sendptr, s->sendlen); - } - s->state = STATE_DATA_SENT; - - /* Wait until all data is sent and acknowledged. */ - // if (!s->sendlen) break; //useful debugging aid - PT_YIELD_UNTIL(&s->psockpt, uip_acked(s->net_buf) || \ - uip_rexmit(s->net_buf)); - } while(!uip_acked(s->net_buf)); - - s->state = STATE_NONE; - - PT_END(&s->psockpt); -} -/*---------------------------------------------------------------------------*/ -uint16_t -psock_datalen(struct psock *psock) -{ - return psock->bufsize - psock->buf.left; -} -/*---------------------------------------------------------------------------*/ -char -psock_newdata(struct psock *s) -{ - if(s->readlen > 0) { - /* There is data in the uip_appdata buffer that has not yet been - read with the PSOCK_READ functions. */ - return 1; - } else if(s->state == STATE_READ) { - /* All data in uip_appdata buffer already consumed. */ - s->state = STATE_BLOCKED_NEWDATA; - return 0; - } else if(uip_newdata(s->net_buf)) { - /* There is new data that has not been consumed. */ - return 1; - } else { - /* There is no new data. */ - return 0; - } -} -/*---------------------------------------------------------------------------*/ -PT_THREAD(psock_readto(CC_REGISTER_ARG struct psock *psock, unsigned char c)) -{ - PT_BEGIN(&psock->psockpt); - - buf_setup(&psock->buf, psock->bufptr, psock->bufsize); - - /* XXX: Should add buf_checkmarker() before do{} loop, if - incoming data has been handled while waiting for a write. */ - - do { - if(psock->readlen == 0) { - PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); - psock->state = STATE_READ; - psock->readptr = (uint8_t *)uip_appdata(psock->net_buf); - psock->readlen = uip_datalen(psock->net_buf); - } - } while(buf_bufto(&psock->buf, c, - &psock->readptr, - &psock->readlen) == BUF_NOT_FOUND); - - if(psock_datalen(psock) == 0) { - psock->state = STATE_NONE; - PT_RESTART(&psock->psockpt); - } - PT_END(&psock->psockpt); -} -/*---------------------------------------------------------------------------*/ -PT_THREAD(psock_readbuf_len(CC_REGISTER_ARG struct psock *psock, uint16_t len)) -{ - PT_BEGIN(&psock->psockpt); - - buf_setup(&psock->buf, psock->bufptr, psock->bufsize); - - /* XXX: Should add buf_checkmarker() before do{} loop, if - incoming data has been handled while waiting for a write. */ - - /* read len bytes or to end of data */ - do { - if(psock->readlen == 0) { - PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); - psock->state = STATE_READ; - psock->readptr = (uint8_t *)uip_appdata(psock->net_buf); - psock->readlen = uip_datalen(psock->net_buf); - } - } while(buf_bufdata(&psock->buf, psock->bufsize, - &psock->readptr, &psock->readlen) == BUF_NOT_FULL && - psock_datalen(psock) < len); - - if(psock_datalen(psock) == 0) { - psock->state = STATE_NONE; - PT_RESTART(&psock->psockpt); - } - PT_END(&psock->psockpt); -} - -/*---------------------------------------------------------------------------*/ -void -psock_init(CC_REGISTER_ARG struct psock *psock, struct net_buf *net_buf) -{ - psock->state = STATE_NONE; - psock->readlen = 0; - psock->bufptr = ip_buf_appdata(net_buf); - psock->bufsize = ip_buf_appdatalen(net_buf); - psock->net_buf = net_buf; - buf_setup(&psock->buf, psock->bufptr, psock->bufsize); - PT_INIT(&psock->pt); - PT_INIT(&psock->psockpt); -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/ip/psock.h b/net/ip/contiki/ip/psock.h deleted file mode 100644 index d75cd59b52d444621b7d8ece7534965f88a0b03d..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/psock.h +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ - -/** - * \addtogroup uip - * @{ - */ - -/** - * \defgroup psock Protosockets library - * @{ - * - * The protosocket library provides an interface to the uIP stack that is - * similar to the traditional BSD socket interface. Unlike programs - * written for the ordinary uIP event-driven interface, programs - * written with the protosocket library are executed in a sequential - * fashion and does not have to be implemented as explicit state - * machines. - * - * Protosockets only work with TCP connections. - * - * The protosocket library uses \ref pt protothreads to provide - * sequential control flow. This makes the protosockets lightweight in - * terms of memory, but also means that protosockets inherits the - * functional limitations of protothreads. Each protosocket lives only - * within a single function block. Automatic variables (stack - * variables) are not necessarily retained across a protosocket - * library function call. - * - * \note Because the protosocket library uses protothreads, local variables - * will not always be saved across a call to a protosocket library - * function. It is therefore advised that local variables are used - * with extreme care. - * - * The protosocket library provides functions for sending data without - * having to deal with retransmissions and acknowledgements, as well - * as functions for reading data without having to deal with data - * being split across more than one TCP segment. - * - * Because each protosocket runs as a protothread, the protosocket has to be - * started with a call to PSOCK_BEGIN() at the start of the function - * in which the protosocket is used. Similarly, the protosocket protothread can - * be terminated by a call to PSOCK_EXIT(). - * - */ - -/** - * \file - * Protosocket library header file - * \author - * Adam Dunkels - * - */ - -#ifndef PSOCK_H_ -#define PSOCK_H_ - -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" - - /* - * The structure that holds the state of a buffer. - * - * This structure holds the state of a uIP buffer. The structure has - * no user-visible elements, but is used through the functions - * provided by the library. - * - */ -struct psock_buf { - uint8_t *ptr; - unsigned short left; -}; - -/** - * The representation of a protosocket. - * - * The protosocket structrure is an opaque structure with no user-visible - * elements. - */ -struct psock { - struct pt pt, psockpt; /* Protothreads - one that's using the psock - functions, and one that runs inside the - psock functions. */ - const uint8_t *sendptr; /* Pointer to the next data to be sent. */ - uint8_t *readptr; /* Pointer to the next data to be read. */ - - uint8_t *bufptr; /* Pointer to the buffer used for buffering - incoming data. */ - - uint16_t sendlen; /* The number of bytes left to be sent. */ - uint16_t readlen; /* The number of bytes left to be read. */ - - struct psock_buf buf; /* The structure holding the state of the - input buffer. */ - unsigned int bufsize; /* The size of the input buffer. */ - - unsigned char state; /* The state of the protosocket. */ - - struct net_buf *net_buf; /* contains conn state etc. */ -}; - -void psock_init(struct psock *psock, struct net_buf *net_buf); -/** - * Initialize a protosocket. - * - * This macro initializes a protosocket and must be called before the - * protosocket is used. The initialization also specifies the input buffer - * for the protosocket. - * - * \param psock (struct psock *) A pointer to the protosocket to be - * initialized - * - * \param buffer (struct net_buf *) A Pointer to network buffer to send. - * - * \hideinitializer - */ -#define PSOCK_INIT(psock, net_buf) \ - psock_init(psock, net_buf) - -/** - * Start the protosocket protothread in a function. - * - * This macro starts the protothread associated with the protosocket and - * must come before other protosocket calls in the function it is used. - * - * \param psock (struct psock *) A pointer to the protosocket to be - * started. - * - * \hideinitializer - */ -#define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt)) - -PT_THREAD(psock_send(struct psock *psock, struct net_buf *buf)); -/** - * Send data. - * - * This macro sends data over a protosocket. The protosocket protothread blocks - * until all data has been sent and is known to have been received by - * the remote end of the TCP connection. - * - * \param psock (struct psock *) A pointer to the protosocket over which - * data is to be sent. - * - * \param buf (struct net_buf *) A pointer to the buffer that is to be sent. - * - * \hideinitializer - */ -#define PSOCK_SEND(psock, buf) \ - PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, buf)) - -/** - * \brief Send a null-terminated string. - * \param psock Pointer to the protosocket. - * \param str The string to be sent. - * - * This function sends a null-terminated string over the - * protosocket. - * - * \hideinitializer - */ -#define PSOCK_SEND_STR(psock, str) \ - PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, (uint8_t *)str, strlen(str))) - -PT_THREAD(psock_generator_send(struct psock *psock, - unsigned short (*f)(void *), void *arg)); - -/** - * \brief Generate data with a function and send it - * \param psock Pointer to the protosocket. - * \param generator Pointer to the generator function - * \param arg Argument to the generator function - * - * This function generates data and sends it over the - * protosocket. This can be used to dynamically generate - * data for a transmission, instead of generating the data - * in a buffer beforehand. This function reduces the need for - * buffer memory. The generator function is implemented by - * the application, and a pointer to the function is given - * as an argument with the call to PSOCK_GENERATOR_SEND(). - * - * The generator function should place the generated data - * directly in the uip_appdata buffer, and return the - * length of the generated data. The generator function is - * called by the protosocket layer when the data first is - * sent, and once for every retransmission that is needed. - * - * \hideinitializer - */ -#define PSOCK_GENERATOR_SEND(psock, generator, arg) \ - PT_WAIT_THREAD(&((psock)->pt), \ - psock_generator_send(psock, generator, arg)) - - -/** - * Close a protosocket. - * - * This macro closes a protosocket and can only be called from within the - * protothread in which the protosocket lives. - * - * \param psock (struct psock *) A pointer to the protosocket that is to - * be closed. - * - * \hideinitializer - */ -#define PSOCK_CLOSE(psock) uip_close() - -PT_THREAD(psock_readbuf_len(struct psock *psock, uint16_t len)); -/** - * Read data until the buffer is full. - * - * This macro will block waiting for data and read the data into the - * input buffer specified with the call to PSOCK_INIT(). Data is read - * until the buffer is full.. - * - * \param psock (struct psock *) A pointer to the protosocket from which - * data should be read. - * - * \hideinitializer - */ -#define PSOCK_READBUF(psock) \ - PT_WAIT_THREAD(&((psock)->pt), psock_readbuf_len(psock, 1)) - - -/** - * Read data until at least len bytes have been read. - * - * This macro will block waiting for data and read the data into the - * input buffer specified with the call to PSOCK_INIT(). Data is read - * until the buffer is full or len bytes have been read. - * - * \param psock (struct psock *) A pointer to the protosocket from which - * data should be read. - * \param len (uint16_t) The minimum number of bytes to read. - * - * \hideinitializer - */ -#define PSOCK_READBUF_LEN(psock, len) \ - PT_WAIT_THREAD(&((psock)->pt), psock_readbuf_len(psock, len)) - -PT_THREAD(psock_readto(struct psock *psock, unsigned char c)); -/** - * Read data up to a specified character. - * - * This macro will block waiting for data and read the data into the - * input buffer specified with the call to PSOCK_INIT(). Data is only - * read until the specified character appears in the data stream. - * - * \param psock (struct psock *) A pointer to the protosocket from which - * data should be read. - * - * \param c (char) The character at which to stop reading. - * - * \hideinitializer - */ -#define PSOCK_READTO(psock, c) \ - PT_WAIT_THREAD(&((psock)->pt), psock_readto(psock, c)) - -/** - * The length of the data that was previously read. - * - * This macro returns the length of the data that was previously read - * using PSOCK_READTO() or PSOCK_READ(). - * - * \param psock (struct psock *) A pointer to the protosocket holding the data. - * - * \hideinitializer - */ -#define PSOCK_DATALEN(psock) psock_datalen(psock) - -uint16_t psock_datalen(struct psock *psock); - -/** - * Exit the protosocket's protothread. - * - * This macro terminates the protothread of the protosocket and should - * almost always be used in conjunction with PSOCK_CLOSE(). - * - * \sa PSOCK_CLOSE_EXIT() - * - * \param psock (struct psock *) A pointer to the protosocket. - * - * \hideinitializer - */ -#define PSOCK_EXIT(psock) PT_EXIT(&((psock)->pt)) - -/** - * Close a protosocket and exit the protosocket's protothread. - * - * This macro closes a protosocket and exits the protosocket's protothread. - * - * \param psock (struct psock *) A pointer to the protosocket. - * - * \hideinitializer - */ -#define PSOCK_CLOSE_EXIT(psock) \ - do { \ - PSOCK_CLOSE(psock); \ - PSOCK_EXIT(psock); \ - } while(0) - -/** - * Declare the end of a protosocket's protothread. - * - * This macro is used for declaring that the protosocket's protothread - * ends. It must always be used together with a matching PSOCK_BEGIN() - * macro. - * - * \param psock (struct psock *) A pointer to the protosocket. - * - * \hideinitializer - */ -#define PSOCK_END(psock) PT_END(&((psock)->pt)) - -char psock_newdata(struct psock *s); - -/** - * Check if new data has arrived on a protosocket. - * - * This macro is used in conjunction with the PSOCK_WAIT_UNTIL() - * macro to check if data has arrived on a protosocket. - * - * \param psock (struct psock *) A pointer to the protosocket. - * - * \hideinitializer - */ -#define PSOCK_NEWDATA(psock) psock_newdata(psock) - -/** - * Wait until a condition is true. - * - * This macro blocks the protothread until the specified condition is - * true. The macro PSOCK_NEWDATA() can be used to check if new data - * arrives when the protosocket is waiting. - * - * Typically, this macro is used as follows: - * - \code - PT_THREAD(thread(struct psock *s, struct timer *t)) - { - PSOCK_BEGIN(s); - - PSOCK_WAIT_UNTIL(s, PSOCK_NEWDATA(s) || timer_expired(t)); - - if(PSOCK_NEWDATA(s)) { - PSOCK_READTO(s, '\n'); - } else { - handle_timed_out(s); - } - - PSOCK_END(s); - } - \endcode - * - * \param psock (struct psock *) A pointer to the protosocket. - * \param condition The condition to wait for. - * - * \hideinitializer - */ -#define PSOCK_WAIT_UNTIL(psock, condition) \ - PT_WAIT_UNTIL(&((psock)->pt), (condition)); - -#define PSOCK_WAIT_THREAD(psock, condition) \ - PT_WAIT_THREAD(&((psock)->pt), (condition)) - -#endif /* PSOCK_H_ */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/ip/simple-udp.c b/net/ip/contiki/ip/simple-udp.c deleted file mode 100644 index 9353fd0d90bca13f78b1bae127add84ecfb47ebc..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/simple-udp.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2011, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Code for the simple-udp module. - * \author - * Adam Dunkels - * - */ - -/** - * \addtogroup simple-udp - * @{ - */ - -#include - -#include "contiki-net.h" -#include "contiki/ip/simple-udp.h" - -#include - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_SIMPLE_UDP -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif - -PROCESS(simple_udp_process, "Simple UDP process"); -static uint8_t started = 0; -#if 0 -/* Moved to net_buf */ -static uint8_t databuffer[UIP_BUFSIZE]; -#endif -#define UIP_IP_BUF(buf) ((struct uip_udpip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) - -/*---------------------------------------------------------------------------*/ -static void -init_simple_udp(void) -{ - if(started == 0) { - process_start(&simple_udp_process, NULL, NULL); - started = 1; - } -} -/*---------------------------------------------------------------------------*/ -int -simple_udp_send(struct net_buf *buf, struct simple_udp_connection *c, - const void *data, uint16_t datalen) -{ - if(c->udp_conn != NULL) { - return uip_udp_packet_sendto(buf, c->udp_conn, data, datalen, - &c->remote_addr, UIP_HTONS(c->remote_port)); - } - return 0; -} -/*---------------------------------------------------------------------------*/ -int -simple_udp_sendto(struct net_buf *buf, struct simple_udp_connection *c, - const void *data, uint16_t datalen, - const uip_ipaddr_t *to) -{ - if(c->udp_conn != NULL) { - return uip_udp_packet_sendto(buf, c->udp_conn, data, datalen, - to, UIP_HTONS(c->remote_port)); - } - return 0; -} -/*---------------------------------------------------------------------------*/ -int -simple_udp_sendto_port(struct net_buf *buf, struct simple_udp_connection *c, - const void *data, uint16_t datalen, - const uip_ipaddr_t *to, - uint16_t port) -{ - if(c->udp_conn != NULL) { - return uip_udp_packet_sendto(buf, c->udp_conn, data, datalen, - to, UIP_HTONS(port)); - } - return 0; -} -/*---------------------------------------------------------------------------*/ -int -simple_udp_register(struct simple_udp_connection *c, - uint16_t local_port, - uip_ipaddr_t *remote_addr, - uint16_t remote_port, - simple_udp_callback receive_callback, - void *user_data) -{ - - init_simple_udp(); - - c->local_port = local_port; - c->remote_port = remote_port; - if(remote_addr != NULL) { - uip_ipaddr_copy(&c->remote_addr, remote_addr); - } - c->receive_callback = receive_callback; - c->user_data = user_data; - - PROCESS_CONTEXT_BEGIN(&simple_udp_process); - c->udp_conn = udp_new(remote_addr, UIP_HTONS(remote_port), c); - if(c->udp_conn != NULL) { - udp_bind(c->udp_conn, UIP_HTONS(local_port)); - } - PROCESS_CONTEXT_END(); - - if(c->udp_conn == NULL) { - return 0; - } - return 1; -} -/*---------------------------------------------------------------------------*/ -int -simple_udp_unregister(struct simple_udp_connection *c) -{ - if (c) { - c->local_port = 0; - if (c->udp_conn) { - udp_unbind(c->udp_conn); - } - return 0; - } - return 1; -} - -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(simple_udp_process, ev, data, buf, user_data) -{ - struct simple_udp_connection *c; - PROCESS_BEGIN(); - - while(1) { - PROCESS_WAIT_EVENT(); - if(ev == tcpip_event) { - - /* An appstate pointer is passed to use from the IP stack - through the 'data' pointer. We registered this appstate when - we did the udp_new() call in simple_udp_register() as the - struct simple_udp_connection pointer. So we extract this - pointer and use it when calling the reception callback. */ - c = (struct simple_udp_connection *)data; - - /* Defensive coding: although the appstate *should* be non-null - here, we make sure to avoid the program crashing on us. */ - if(c != NULL) { - - /* If we were called because of incoming data, we should call - the reception callback. */ - if(uip_newdata(buf)) { -#if 0 - /* Copy the data from the uIP data buffer into our own - buffer to avoid the uIP buffer being messed with by the - callee. */ - memcpy(databuffer, uip_appdata, uip_datalen()); -#endif - /* Call the client process. We use the PROCESS_CONTEXT - mechanism to temporarily switch process context to the - client process. */ - if(c->receive_callback != NULL) { - PROCESS_CONTEXT_BEGIN(c->client_process); - PRINTF("simple_udp_process(%p): calling cb %p " - "appdata %p datalen %d\n", buf, - c->receive_callback, uip_appdata(buf), - uip_datalen(buf)); - c->receive_callback(c, - &(UIP_IP_BUF(buf)->srcipaddr), - UIP_HTONS(UIP_IP_BUF(buf)->srcport), - &(UIP_IP_BUF(buf)->destipaddr), - UIP_HTONS(UIP_IP_BUF(buf)->destport), - uip_appdata(buf), uip_datalen(buf), - c->user_data, buf); - PROCESS_CONTEXT_END(); - } - } - } - } - - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/ip/simple-udp.h b/net/ip/contiki/ip/simple-udp.h deleted file mode 100644 index 96488ef8099605e95602af0830ea4b6a65e779e0..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/simple-udp.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2011, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Header file for the simple-udp module. - * \author - * Adam Dunkels - * - */ - -/** - * \addtogroup uip - * @{ - */ - - -/** - * \defgroup simple-udp A simple UDP API - * - * The default Contiki UDP API is difficult to use. The simple-udp - * module provides a significantly simpler API. - * - * @{ - */ - -#ifndef SIMPLE_UDP_H -#define SIMPLE_UDP_H - -#include "contiki/ip/uip.h" - -struct simple_udp_connection; - -/** Simple UDP Callback function type. */ -typedef void (* simple_udp_callback)(struct simple_udp_connection *c, - const uip_ipaddr_t *source_addr, - uint16_t source_port, - const uip_ipaddr_t *dest_addr, - uint16_t dest_port, - const uint8_t *data, uint16_t datalen, - void *user_data, - struct net_buf *buf); - -/** Simple UDP connection */ -struct simple_udp_connection { - struct simple_udp_connection *next; - uip_ipaddr_t remote_addr; - uint16_t remote_port, local_port; - simple_udp_callback receive_callback; - struct uip_udp_conn *udp_conn; - struct process *client_process; - void *user_data; -}; - -/** - * \brief Register a UDP connection - * \param c A pointer to a struct simple_udp_connection - * \param local_port The local UDP port in host byte order - * \param remote_addr The remote IP address - * \param remote_port The remote UDP port in host byte order - * \param receive_callback A pointer to a function of to be called for incoming packets - * \retval 0 If no UDP connection could be allocated - * \retval 1 If the connection was successfully allocated - * - * This function registers a UDP connection and attaches a - * callback function to it. The callback function will be - * called for incoming packets. The local UDP port can be - * set to 0 to indicate that an ephemeral UDP port should - * be allocated. The remote IP address can be NULL, to - * indicate that packets from any IP address should be - * accepted. - * - */ -int simple_udp_register(struct simple_udp_connection *c, - uint16_t local_port, - uip_ipaddr_t *remote_addr, - uint16_t remote_port, - simple_udp_callback receive_callback, - void *user_data); - -/** - * \brief Unregister a UDP connection - * \param c A pointer to a struct simple_udp_connection - * \retval 0 If UDP connection parameter is invalid - * \retval 1 If the connection was successfully unregistered - * - * This function unregisters a UDP connection. - */ -int simple_udp_unregister(struct simple_udp_connection *c); - -/** - * \brief Send a UDP packet - * \param buf Buffer to send - * \param c A pointer to a struct simple_udp_connection - * \param data A pointer to the data to be sent - * \param datalen The length of the data - * - * This function sends a UDP packet. The packet will be - * sent to the IP address and with the UDP ports that were - * specified when the connection was registered with - * simple_udp_register(). - * - * \sa simple_udp_sendto() - */ -int simple_udp_send(struct net_buf *buf, struct simple_udp_connection *c, - const void *data, uint16_t datalen); - -/** - * \brief Send a UDP packet to a specified IP address - * \param buf Buffer to send - * \param c A pointer to a struct simple_udp_connection - * \param data A pointer to the data to be sent - * \param datalen The length of the data - * \param to The IP address of the receiver - * - * This function sends a UDP packet to a specified IP - * address. The packet will be sent with the UDP ports - * that were specified when the connection was registered - * with simple_udp_register(). - * - * \sa simple_udp_send() - */ -int simple_udp_sendto(struct net_buf *buf, struct simple_udp_connection *c, - const void *data, uint16_t datalen, - const uip_ipaddr_t *to); - -/** - * \brief Send a UDP packet to a specified IP address and UDP port - * \param buf Buffer to send - * \param c A pointer to a struct simple_udp_connection - * \param data A pointer to the data to be sent - * \param datalen The length of the data - * \param to The IP address of the receiver - * \param to_port The UDP port of the receiver, in host byte order - * - * This function sends a UDP packet to a specified IP - * address and UDP port. The packet will be sent with the - * UDP ports that were specified when the connection was - * registered with simple_udp_register(). - * - * \sa simple_udp_sendto() - */ -int simple_udp_sendto_port(struct net_buf *buf, struct simple_udp_connection *c, - const void *data, uint16_t datalen, - const uip_ipaddr_t *to, uint16_t to_port); - -void simple_udp_init(void); - -PROCESS_NAME(simple_udp_process); - -#endif /* SIMPLE_UDP_H */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/ip/tcpip.c b/net/ip/contiki/ip/tcpip.c deleted file mode 100644 index d3a8c448138800fb810e1c9381710bd971688412..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/tcpip.c +++ /dev/null @@ -1,956 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Code for tunnelling uIP packets over the Rime mesh routing module - * - * \author Adam Dunkels \author - * \author Mathilde Durvy (IPv6 related code) - * \author Julien Abeille (IPv6 related code) - */ - -#include - -#include "contiki-net.h" -#include "contiki/ip/uip-split.h" -#include "contiki/ip/uip-packetqueue.h" - -#if NETSTACK_CONF_WITH_IPV6 -#include "contiki/ipv6/uip-nd6.h" -#include "contiki/ipv6/uip-ds6.h" -#endif - -#include - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_RECV_SEND -#define TCPIP_CONF_ANNOTATE_TRANSMISSIONS 1 -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#ifdef CONFIG_DHCP -#include "contiki/ip/dhcpc.h" -#endif - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif - -#define UIP_ICMP_BUF(buf) ((struct uip_icmp_hdr *)&uip_buf(buf)[UIP_LLIPH_LEN + uip_ext_len(buf)]) -#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) -#define UIP_TCP_BUF(buf) ((struct uip_tcpip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) - -#ifdef UIP_FALLBACK_INTERFACE -extern struct uip_fallback_interface UIP_FALLBACK_INTERFACE; -#endif - -#if UIP_CONF_IPV6_RPL -#include "rpl/rpl.h" -#endif - -process_event_t tcpip_event; -#if UIP_CONF_ICMP6 -process_event_t tcpip_icmp6_event; -#endif /* UIP_CONF_ICMP6 */ - -/* Periodic check of active connections. */ -static struct etimer periodic; - -#if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_REASSEMBLY -/* Timer for reassembly. */ -extern struct etimer uip_reass_timer; -#endif - -#if UIP_TCP -/** - * \internal Structure for holding a TCP port and a process ID. - */ -struct listenport { - uint16_t port; - struct process *p; -}; - -static struct internal_state { - struct listenport listenports[UIP_LISTENPORTS]; - struct process *p; -} s; -#endif - -enum { - TCP_POLL, - UDP_POLL, - PACKET_INPUT -}; - -/* Called on IP packet output. */ - -static uint8_t (* outputfunc)(struct net_buf *buf, const uip_lladdr_t *a); - -uint8_t -tcpip_output(struct net_buf *buf, const uip_lladdr_t *a) -{ - if(outputfunc != NULL) { - return outputfunc(buf, a); - } - UIP_LOG("tcpip_output: Use tcpip_set_outputfunc() to set an output function"); - return 0; -} - -void -tcpip_set_outputfunc(uint8_t (*f)(struct net_buf *buf, const uip_lladdr_t *)) -{ - outputfunc = f; -} - -#if UIP_CONF_IP_FORWARD -unsigned char tcpip_is_forwarding; /* Forwarding right now? */ -#endif /* UIP_CONF_IP_FORWARD */ - -struct net_buf; - -PROCESS(tcpip_process, "TCP/IP stack"); - -/*---------------------------------------------------------------------------*/ -#if UIP_TCP || UIP_CONF_IP_FORWARD -static void -start_periodic_tcp_timer(void) -{ - if(etimer_expired(&periodic)) { - etimer_restart(&periodic); - } -} -#endif /* UIP_TCP || UIP_CONF_IP_FORWARD */ - -/*---------------------------------------------------------------------------*/ -static void -check_for_tcp_syn(struct net_buf *buf) -{ -#if UIP_TCP || UIP_CONF_IP_FORWARD - /* This is a hack that is needed to start the periodic TCP timer if - an incoming packet contains a SYN: since uIP does not inform the - application if a SYN arrives, we have no other way of starting - this timer. This function is called for every incoming IP packet - to check for such SYNs. */ -#define TCP_SYN 0x02 - if(UIP_IP_BUF(buf)->proto == UIP_PROTO_TCP && - (UIP_TCP_BUF(buf)->flags & TCP_SYN) == TCP_SYN) { - start_periodic_tcp_timer(); - } -#endif /* UIP_TCP || UIP_CONF_IP_FORWARD */ -} -/*---------------------------------------------------------------------------*/ -static uint8_t -packet_input(struct net_buf *buf) -{ - uint8_t ret = 0; -#if UIP_CONF_IP_FORWARD - if(uip_len > 0) { - tcpip_is_forwarding = 1; - if(uip_fw_forward() == UIP_FW_LOCAL) { - tcpip_is_forwarding = 0; - check_for_tcp_syn(); - uip_input(); - if(uip_len > 0) { -#if UIP_CONF_TCP_SPLIT - uip_split_output(); -#else /* UIP_CONF_TCP_SPLIT */ -#if NETSTACK_CONF_WITH_IPV6 - tcpip_ipv6_output(); -#else - PRINTF("tcpip packet_input forward output len %d\n", uip_len); - tcpip_output(); -#endif -#endif /* UIP_CONF_TCP_SPLIT */ - } - } - tcpip_is_forwarding = 0; - } -#else /* UIP_CONF_IP_FORWARD */ - if(uip_len(buf) > 0) { - check_for_tcp_syn(buf); - ret = uip_input(buf); - if(ret && uip_len(buf) > 0) { -#if UIP_CONF_TCP_SPLIT - uip_split_output(buf); -#else /* UIP_CONF_TCP_SPLIT */ -#if NETSTACK_CONF_WITH_IPV6 - PRINTF("tcpip packet_input output len %d\n", uip_len(buf)); - ret = tcpip_ipv6_output(buf); -#else - PRINTF("tcpip packet_input output len %d\n", uip_len(buf)); - ret = tcpip_output(buf, NULL); -#endif -#endif /* UIP_CONF_TCP_SPLIT */ - } - } -#endif /* UIP_CONF_IP_FORWARD */ - return ret; -} -/*---------------------------------------------------------------------------*/ -#if UIP_TCP -#if UIP_ACTIVE_OPEN -struct uip_conn * -tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate, - struct process *process) -{ - struct uip_conn *c; - - c = uip_connect(ripaddr, port); - if(c == NULL) { - return NULL; - } - - c->appstate.p = process; - c->appstate.state = appstate; - - tcpip_poll_tcp(c); - - return c; -} -#endif /* UIP_ACTIVE_OPEN */ -/*---------------------------------------------------------------------------*/ -void -tcp_unlisten(uint16_t port, struct process *handler) -{ - static unsigned char i; - struct listenport *l; - - l = s.listenports; - for(i = 0; i < UIP_LISTENPORTS; ++i) { - if(l->port == port && - l->p == handler) { - l->port = 0; - uip_unlisten(port); - break; - } - ++l; - } -} -/*---------------------------------------------------------------------------*/ -void -tcp_listen(uint16_t port, struct process *handler) -{ - static unsigned char i; - struct listenport *l; - - l = s.listenports; - for(i = 0; i < UIP_LISTENPORTS; ++i) { - if(l->port == 0) { - l->port = port; - l->p = handler; - uip_listen(port); - break; - } - ++l; - } -} -/*---------------------------------------------------------------------------*/ -void -tcp_attach(struct uip_conn *conn, - void *appstate) -{ - uip_tcp_appstate_t *s; - - s = &conn->appstate; - s->p = PROCESS_CURRENT(); - s->state = appstate; -} - -#endif /* UIP_TCP */ -/*---------------------------------------------------------------------------*/ -#if UIP_UDP -void -udp_attach(struct uip_udp_conn *conn, - void *appstate) -{ - uip_udp_appstate_t *s; - - s = &conn->appstate; - s->p = PROCESS_CURRENT(); - s->state = appstate; -} -/*---------------------------------------------------------------------------*/ -struct uip_udp_conn * -udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate) -{ - struct uip_udp_conn *c; - uip_udp_appstate_t *s; - - c = uip_udp_new(ripaddr, port); - if(c == NULL) { - return NULL; - } - - s = &c->appstate; - s->p = PROCESS_CURRENT(); - s->state = appstate; - - return c; -} -/*---------------------------------------------------------------------------*/ -struct uip_udp_conn * -udp_broadcast_new(uint16_t port, void *appstate) -{ - uip_ipaddr_t addr; - struct uip_udp_conn *conn; - -#if NETSTACK_CONF_WITH_IPV6 - uip_create_linklocal_allnodes_mcast(&addr); -#else - uip_ipaddr(&addr, 255,255,255,255); -#endif /* NETSTACK_CONF_WITH_IPV6 */ - conn = udp_new(&addr, port, appstate); - if(conn != NULL) { - udp_bind(conn, port); - } - return conn; -} -#endif /* UIP_UDP */ -/*---------------------------------------------------------------------------*/ -#if UIP_CONF_ICMP6 -uint8_t -icmp6_new(void *appstate) { - if(uip_icmp6_conns.appstate.p == PROCESS_NONE) { - uip_icmp6_conns.appstate.p = PROCESS_CURRENT(); - uip_icmp6_conns.appstate.state = appstate; - return 0; - } - return 1; -} - -void -tcpip_icmp6_call(uint8_t type) -{ - if(uip_icmp6_conns.appstate.p != PROCESS_NONE) { - /* XXX: This is a hack that needs to be updated. Passing a pointer (&type) - like this only works with process_post_synch. */ - process_post_synch(uip_icmp6_conns.appstate.p, tcpip_icmp6_event, &type, - NULL); - } - return; -} -#endif /* UIP_CONF_ICMP6 */ -/*---------------------------------------------------------------------------*/ -static void -eventhandler(process_event_t ev, process_data_t data, struct net_buf *buf) -{ -#if UIP_TCP - static unsigned char i; - register struct listenport *l; -#endif /*UIP_TCP*/ - struct process *p; - - switch(ev) { - case PROCESS_EVENT_EXITED: - /* This is the event we get if a process has exited. We go through - the TCP/IP tables to see if this process had any open - connections or listening TCP ports. If so, we'll close those - connections. */ - - p = (struct process *)data; -#if UIP_TCP - l = s.listenports; - for(i = 0; i < UIP_LISTENPORTS; ++i) { - if(l->p == p) { - uip_unlisten(l->port); - l->port = 0; - l->p = PROCESS_NONE; - } - ++l; - } - - { - struct uip_conn *cptr; - - for(cptr = &uip_conns[0]; cptr < &uip_conns[UIP_CONNS]; ++cptr) { - if(cptr->appstate.p == p) { - cptr->appstate.p = PROCESS_NONE; - cptr->tcpstateflags = UIP_CLOSED; - } - } - } -#endif /* UIP_TCP */ -#if UIP_UDP - { - struct uip_udp_conn *cptr; - - for(cptr = &uip_udp_conns[0]; - cptr < &uip_udp_conns[UIP_UDP_CONNS]; ++cptr) { - if(cptr->appstate.p == p) { - cptr->lport = 0; - } - } - } -#endif /* UIP_UDP */ - break; - - case PROCESS_EVENT_TIMER: - /* We get this event if one of our timers have expired. */ - { - if(!buf) - break; - /* Check the clock to see if we should call the periodic uIP - processing. */ - if(data == &periodic && - !etimer_is_triggered(&periodic)) { - etimer_set_triggered(&periodic); -#if UIP_TCP - for(i = 0; i < UIP_CONNS; ++i) { - if(uip_conn_active(i)) { - /* Only restart the timer if there are active - connections. */ - etimer_restart(&periodic); - uip_periodic(buf, i); -#if NETSTACK_CONF_WITH_IPV6 - tcpip_ipv6_output(buf); -#else - if(uip_len(buf) > 0) { - PRINTF("tcpip_output from periodic len %d\n", uip_len(buf)); - tcpip_output(buf, NULL); - PRINTF("tcpip_output after periodic len %d\n", uip_len(buf)); - } -#endif /* NETSTACK_CONF_WITH_IPV6 */ - } - } -#endif /* UIP_TCP */ -#if UIP_CONF_IP_FORWARD - uip_fw_periodic(); -#endif /* UIP_CONF_IP_FORWARD */ - } - -#if NETSTACK_CONF_WITH_IPV6 -#if UIP_CONF_IPV6_REASSEMBLY - /* - * check the timer for reassembly - */ - if(data == &uip_reass_timer && - !etimer_is_triggered(&uip_reass_timer)) { - etimer_set_triggered(&uip_reass_timer); - uip_reass_over(); - tcpip_ipv6_output(buf); - } -#endif /* UIP_CONF_IPV6_REASSEMBLY */ - /* - * check the different timers for neighbor discovery and - * stateless autoconfiguration - */ - /*if(data == &uip_ds6_timer_periodic && - etimer_expired(&uip_ds6_timer_periodic)) { - uip_ds6_periodic(); - tcpip_ipv6_output(); - }*/ -#if !UIP_CONF_ROUTER - if(data == &uip_ds6_timer_rs && - !etimer_is_triggered(&uip_ds6_timer_rs)) { - etimer_set_triggered(&uip_ds6_timer_rs); - uip_ds6_send_rs(buf); - tcpip_ipv6_output(buf); - } -#endif /* !UIP_CONF_ROUTER */ - if(data == &uip_ds6_timer_periodic && - !etimer_is_triggered(&uip_ds6_timer_periodic)) { - etimer_set_triggered(&uip_ds6_timer_periodic); - uip_ds6_periodic(buf); - tcpip_ipv6_output(buf); - } -#endif /* NETSTACK_CONF_WITH_IPV6 */ - } - break; - -#if UIP_TCP - case TCP_POLL: - if(data != NULL) { - uint8_t ret = 0; - uip_poll_conn(buf, data); -#if NETSTACK_CONF_WITH_IPV6 - if (!uip_len(buf) && buf->len) { - /* Make sure we are sending something if needed. */ - uip_len(buf) = buf->len; - } - ret = tcpip_ipv6_output(buf); -#else /* NETSTACK_CONF_WITH_IPV6 */ - if(uip_len(buf) > 0) { - PRINTF("tcpip_output from tcp poll len %d\n", uip_len(buf)); - ret = tcpip_output(buf, NULL); - } -#endif /* NETSTACK_CONF_WITH_IPV6 */ - /* Start the periodic polling, if it isn't already active. */ - start_periodic_tcp_timer(); - - if (!ret) { - /* Packet was not sent properly */ - ip_buf_unref(buf); - } - } - break; -#endif /* UIP_TCP */ -#if UIP_UDP - case UDP_POLL: - if(data != NULL) { - uip_udp_periodic_conn(buf, data); -#if NETSTACK_CONF_WITH_IPV6 - tcpip_ipv6_output(buf); -#else - if(uip_len(buf) > 0) { - tcpip_output(buf, NULL); - } -#endif /* UIP_UDP */ - } - break; -#endif /* UIP_UDP */ - - case PACKET_INPUT: - if (!packet_input(buf)) { - PRINTF("Packet %p was not sent and must be discarded by caller\n", buf); - } else { - PRINTF("Packet %p was sent ok\n", buf); - } - break; - }; -} -/*---------------------------------------------------------------------------*/ -uint8_t -tcpip_input(struct net_buf *buf) -{ - process_post_synch(&tcpip_process, PACKET_INPUT, NULL, buf); - if (uip_len(buf) == 0) { - /* This indicates that there was a parsing/other error - * in packet. - */ - return 0; - } - - uip_len(buf) = 0; -#if NETSTACK_CONF_WITH_IPV6 - uip_ext_len(buf) = 0; -#endif /*NETSTACK_CONF_WITH_IPV6*/ - - return 1; -} -/*---------------------------------------------------------------------------*/ -#if NETSTACK_CONF_WITH_IPV6 -uint8_t -tcpip_ipv6_output(struct net_buf *buf) -{ - uip_ds6_nbr_t *nbr = NULL; - uip_ipaddr_t *nexthop; - uint8_t ret = 0; /* return value 0 == failed, 1 == ok */ - - if(!buf || uip_len(buf) == 0) { - return 0; - } - - PRINTF("%s(): buf %p len %d\n", __FUNCTION__, buf, uip_len(buf)); - - if(uip_len(buf) > UIP_LINK_MTU) { - UIP_LOG("tcpip_ipv6_output: Packet too big"); - uip_len(buf) = 0; - uip_ext_len(buf) = 0; - return 0; - } - - if(uip_is_addr_unspecified(&UIP_IP_BUF(buf)->destipaddr)){ - UIP_LOG("tcpip_ipv6_output: Destination address unspecified"); - uip_len(buf) = 0; - uip_ext_len(buf) = 0; - return 0; - } - - if(!uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr)) { - /* Next hop determination */ - nbr = NULL; - - /* We first check if the destination address is on our immediate - link. If so, we simply use the destination address as our - nexthop address. */ - if(uip_ds6_is_addr_onlink(&UIP_IP_BUF(buf)->destipaddr)){ - nexthop = &UIP_IP_BUF(buf)->destipaddr; - } else { - uip_ds6_route_t *route; - /* Check if we have a route to the destination address. */ - route = uip_ds6_route_lookup(&UIP_IP_BUF(buf)->destipaddr); - - /* No route was found - we send to the default route instead. */ - if(route == NULL) { - PRINTF("tcpip_ipv6_output: no route found, using default route\n"); - nexthop = uip_ds6_defrt_choose(); - if(nexthop == NULL) { -#ifdef UIP_FALLBACK_INTERFACE - PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n", - uip_ext_len(buf), *((uint8_t *)UIP_IP_BUF(buf) + 40)); - if(uip_ext_len(buf) > 0) { - extern void remove_ext_hdr(void); - uint8_t proto = *((uint8_t *)UIP_IP_BUF(buf) + 40); - remove_ext_hdr(); - /* This should be copied from the ext header... */ - UIP_IP_BUF(buf)->proto = proto; - } - UIP_FALLBACK_INTERFACE.output(); -#else - PRINTF("tcpip_ipv6_output: Destination off-link but no route\n"); -#endif /* !UIP_FALLBACK_INTERFACE */ - uip_len(buf) = 0; - uip_ext_len(buf) = 0; - return 0; - } - - } else { - /* A route was found, so we look up the nexthop neighbor for - the route. */ - nexthop = uip_ds6_route_nexthop(route); - - /* If the nexthop is dead, for example because the neighbor - never responded to link-layer acks, we drop its route. */ - if(nexthop == NULL) { -#if UIP_CONF_IPV6_RPL - /* If we are running RPL, and if we are the root of the - network, we'll trigger a global repair berfore we remove - the route. */ - rpl_dag_t *dag; - rpl_instance_t *instance; - - dag = (rpl_dag_t *)route->state.dag; - if(dag != NULL) { - instance = dag->instance; - - rpl_repair_root(instance->instance_id); - } -#endif /* UIP_CONF_IPV6_RPL */ - uip_ds6_route_rm(route); - - /* We don't have a nexthop to send the packet to, so we drop - it. */ - return 0; - } - } -#if TCPIP_CONF_ANNOTATE_TRANSMISSIONS - if(nexthop != NULL) { - static uint8_t annotate_last; - static uint8_t annotate_has_last = 0; - - if(annotate_has_last) { - printf("#L %u 0; red\n", annotate_last); - } - printf("#L %u 1; red\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]); - annotate_last = nexthop->u8[sizeof(uip_ipaddr_t) - 1]; - annotate_has_last = 1; - } -#endif /* TCPIP_CONF_ANNOTATE_TRANSMISSIONS */ - } - - /* End of next hop determination */ - -#if UIP_CONF_IPV6_RPL - if(rpl_update_header_final(buf, nexthop)) { - uip_len(buf) = 0; - uip_ext_len(buf) = 0; - return 0; - } -#endif /* UIP_CONF_IPV6_RPL */ - nbr = uip_ds6_nbr_lookup(nexthop); - if(nbr == NULL) { -#if UIP_ND6_SEND_NA - if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE)) == NULL) { - PRINTF("IP packet buf %p len %d discarded because cannot " - "add neighbor\n", buf, uip_len(buf)); - uip_len(buf) = 0; - uip_ext_len(buf) = 0; - return 0; - } else { -#if UIP_CONF_IPV6_QUEUE_PKT - /* Copy outgoing pkt in the queuing buffer for later transmit. */ - if(uip_packetqueue_alloc(buf, &nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) { - memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF(buf), uip_len(buf)); - uip_packetqueue_set_buflen(&nbr->packethandle, uip_len(buf)); - } -#else - PRINTF("IP packet buf %p len %d discarded because NS is " - "being sent\n", buf, uip_len(buf)); -#endif - /* RFC4861, 7.2.2: - * "If the source address of the packet prompting the solicitation is the - * same as one of the addresses assigned to the outgoing interface, that - * address SHOULD be placed in the IP Source Address of the outgoing - * solicitation. Otherwise, any one of the addresses assigned to the - * interface should be used."*/ - if(uip_ds6_is_my_addr(&UIP_IP_BUF(buf)->srcipaddr)){ - uip_nd6_ns_output(NULL, &UIP_IP_BUF(buf)->srcipaddr, NULL, &nbr->ipaddr); - } else { - uip_nd6_ns_output(NULL, NULL, NULL, &nbr->ipaddr); - } - - stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000); - nbr->nscount = 1; - } - - uip_len(buf) = 0; - uip_ext_len(buf) = 0; - return 0; /* packet was discarded */ -#else /* UIP_ND6_SEND_NA */ - int uiplen = uip_len(buf); - int extlen = uip_ext_len(buf); - - /* Neighbor discovery is not there. Just try to send the packet. */ - ret = tcpip_output(buf, NULL); - if (ret) { - /* We must set the length back as these were overwritten - * by other part of the stack. If we do not do this then - * there will be a double memory free in the caller. - * FIXME properly later! - */ - uip_len(buf) = uiplen; - uip_ext_len(buf) = extlen; - } else { - uip_len(buf) = 0; - uip_ext_len(buf) = 0; - } - return ret; - -#endif /* UIP_ND6_SEND_NA */ - } else { -#if UIP_ND6_SEND_NA - if(nbr->state == NBR_INCOMPLETE) { - PRINTF("tcpip_ipv6_output: nbr cache entry incomplete\n"); -#if UIP_CONF_IPV6_QUEUE_PKT - /* Copy outgoing pkt in the queuing buffer for later transmit and set - the destination nbr to nbr. */ - if(uip_packetqueue_alloc(buf, &nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) { - memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF(buf), uip_len(buf)); - uip_packetqueue_set_buflen(&nbr->packethandle, uip_len(buf)); - } else { - PRINTF("IP packet buf %p len %d discarded because no space " - "in the queue\n", buf, uip_len(buf)); - } -#else - PRINTF("IP packet buf %p len %d discarded because neighbor info is " - "not yet received\n", buf, uip_len(buf)); -#endif /*UIP_CONF_IPV6_QUEUE_PKT*/ - uip_len(buf) = 0; - uip_ext_len(buf) = 0; - return 0; - } - /* Send in parallel if we are running NUD (nbc state is either STALE, - DELAY, or PROBE). See RFC 4861, section 7.3.3 on node behavior. */ - if(nbr->state == NBR_STALE) { - nbr->state = NBR_DELAY; - stimer_set(&nbr->reachable, UIP_ND6_DELAY_FIRST_PROBE_TIME); - nbr->nscount = 0; - PRINTF("tcpip_ipv6_output: nbr cache entry stale moving to delay\n"); - } -#endif /* UIP_ND6_SEND_NA */ - - ret = tcpip_output(buf, uip_ds6_nbr_get_ll(nbr)); - -#if UIP_CONF_IPV6_QUEUE_PKT - /* - * Send the queued packets from here, may not be 100% perfect though. - * This happens in a few cases, for example when instead of receiving a - * NA after sendiong a NS, you receive a NS with SLLAO: the entry moves - * to STALE, and you must both send a NA and the queued packet. - */ - if(uip_packetqueue_buflen(&nbr->packethandle) != 0) { - bool allocated_here = false; - if (ret != 0) { - /* The IP buf was freed because the send succeed so we need to - * allocate a new one here. - */ - buf = ip_buf_get_reserve_tx(0); - if (!buf) { - PRINTF("%s(): Cannot send queued packet, no net buffers\n", __FUNCTION__); - uip_packetqueue_free(&nbr->packethandle); - goto no_buf; - } - allocated_here = true; - } - - uip_len(buf) = buf->len = uip_packetqueue_buflen(&nbr->packethandle); - memcpy(UIP_IP_BUF(buf), uip_packetqueue_buf(&nbr->packethandle), - uip_len(buf)); - uip_packetqueue_free(&nbr->packethandle); - ret = tcpip_output(buf, uip_ds6_nbr_get_ll(nbr)); - if (allocated_here && !ret) { - /* There was a sending error and the buffer was not released. - * We cannot return the buffer to upper layers so just release - * it here. - */ - ip_buf_unref(buf); - ret = 1; /* This will tell caller that buf is released. */ - } - } - no_buf: -#endif /*UIP_CONF_IPV6_QUEUE_PKT*/ - - if (ret == 0) { - uip_len(buf) = 0; - uip_ext_len(buf) = 0; - } - - return ret; - } - return 0; /* discard packet */ - } - /* Multicast IP destination address. */ - ret = tcpip_output(buf, NULL); - uip_len(buf) = 0; - uip_ext_len(buf) = 0; - return ret; -} -#endif /* NETSTACK_CONF_WITH_IPV6 */ -/*---------------------------------------------------------------------------*/ -#if UIP_UDP -void -tcpip_poll_udp(struct uip_udp_conn *conn) -{ - process_post(&tcpip_process, UDP_POLL, conn); -} -#endif /* UIP_UDP */ -/*---------------------------------------------------------------------------*/ -#if UIP_TCP -void -tcpip_poll_tcp(struct uip_conn *conn) -{ - /* We are sending here the initial SYN */ - struct net_buf *buf = ip_buf_get_tx(conn->appstate.state); - uip_set_conn(buf) = conn; - conn->buf = ip_buf_ref(buf); - process_post_synch(&tcpip_process, TCP_POLL, conn, buf); -} - -#if UIP_ACTIVE_OPEN -void tcpip_resend_syn(struct uip_conn *conn, struct net_buf *buf) -{ - /* The network driver will unref the buf so in order not to loose the - * buffer, we need to ref it here. - */ - ip_buf_ref(buf); - - /* We are re-sending here the SYN */ - process_post_synch(&tcpip_process, TCP_POLL, conn, buf); -} -#endif /* UIP_ACTIVE_OPEN */ -#endif /* UIP_TCP */ -/*---------------------------------------------------------------------------*/ -void -tcpip_uipcall(struct net_buf *buf) -{ - struct tcpip_uipstate *ts; - -#if UIP_UDP - if(uip_conn(buf) != NULL) { - ts = &uip_conn(buf)->appstate; - } else { - ts = &uip_udp_conn(buf)->appstate; - } -#else /* UIP_UDP */ - ts = &uip_conn(buf)->appstate; -#endif /* UIP_UDP */ - -#if UIP_TCP - { - static unsigned char i; - struct listenport *l; - - /* If this is a connection request for a listening port, we must - mark the connection with the right process ID. */ - if(uip_connected(buf)) { - l = &s.listenports[0]; - for(i = 0; i < UIP_LISTENPORTS; ++i) { - if(l->port == uip_conn(buf)->lport && - l->p != PROCESS_NONE) { - ts->p = l->p; - ts->state = NULL; - break; - } - ++l; - } - - /* Start the periodic polling, if it isn't already active. */ - start_periodic_tcp_timer(); - } - } -#endif /* UIP_TCP */ - -#ifdef CONFIG_DHCP - if(msg_for_dhcpc(buf)) { - PRINTF("msg for dhcpc\n"); - dhcpc_appcall(tcpip_event, buf); - return; - } -#endif - - if(ts->p != NULL) { - process_post_synch(ts->p, tcpip_event, ts->state, buf); - } -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(tcpip_process, ev, data, buf, user_data) -{ - PROCESS_BEGIN(); - -#if UIP_TCP - { - static unsigned char i; - - for(i = 0; i < UIP_LISTENPORTS; ++i) { - s.listenports[i].port = 0; - } - s.p = PROCESS_CURRENT(); - } -#endif - - tcpip_event = process_alloc_event(); -#if UIP_CONF_ICMP6 - tcpip_icmp6_event = process_alloc_event(); -#endif /* UIP_CONF_ICMP6 */ - etimer_set(&periodic, CLOCK_SECOND / 2, &tcpip_process); - - uip_init(); -#ifdef UIP_FALLBACK_INTERFACE - UIP_FALLBACK_INTERFACE.init(); -#endif -/* initialize RPL if configured for using RPL */ -#if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_RPL - rpl_init(); -#endif /* UIP_CONF_IPV6_RPL */ - - while(1) { - PROCESS_YIELD(); - eventhandler(ev, data, buf); - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/ip/tcpip.h b/net/ip/contiki/ip/tcpip.h deleted file mode 100644 index 7967c1389b6ddf53587bf4a3873b92f391785206..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/tcpip.h +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ - -/** - * \file - * Header for the Contiki/uIP interface. - * \author Adam Dunkels - * \author Mathilde Durvy (IPv6 related code) - * \author Julien Abeille (IPv6 related code) - */ - -/** - * \addtogroup uip - * @{ - */ - -/** - * \defgroup tcpip The Contiki/uIP interface - * @{ - * - * TCP/IP support in Contiki is implemented using the uIP TCP/IP - * stack. For sending and receiving data, Contiki uses the functions - * provided by the uIP module, but Contiki adds a set of functions for - * connection management. The connection management functions make - * sure that the uIP TCP/IP connections are connected to the correct - * process. - * - * Contiki also includes an optional protosocket library that provides - * an API similar to the BSD socket API. - * - * \sa \ref uip "The uIP TCP/IP stack" - * \sa \ref psock "Protosockets library" - * - */ - -#ifndef TCPIP_H_ -#define TCPIP_H_ - -#include "contiki.h" -#include "contiki/ip/uipaddr.h" - -struct uip_conn; - -struct tcpip_uipstate { - struct process *p; - void *state; -}; - -#define UIP_APPCALL(buf) tcpip_uipcall(buf) -#define UIP_UDP_APPCALL(buf) tcpip_uipcall(buf) -#define UIP_ICMP6_APPCALL tcpip_icmp6_call - -/*#define UIP_APPSTATE_SIZE sizeof(struct tcpip_uipstate)*/ - -typedef struct tcpip_uipstate uip_udp_appstate_t; -typedef struct tcpip_uipstate uip_tcp_appstate_t; -typedef struct tcpip_uipstate uip_icmp6_appstate_t; -#include "contiki/ip/uip.h" -void tcpip_uipcall(struct net_buf *buf); - -/** - * \name TCP functions - * @{ - */ - -/** - * Attach a TCP connection to the current process - * - * This function attaches the current process to a TCP - * connection. Each TCP connection must be attached to a process in - * order for the process to be able to receive and send - * data. Additionally, this function can add a pointer with connection - * state to the connection. - * - * \param conn A pointer to the TCP connection. - * - * \param appstate An opaque pointer that will be passed to the - * process whenever an event occurs on the connection. - * - */ -CCIF void tcp_attach(struct uip_conn *conn, - void *appstate); -#define tcp_markconn(conn, appstate) tcp_attach(conn, appstate) - -/** - * Open a TCP port. - * - * This function opens a TCP port for listening. When a TCP connection - * request occurs for the port, the process will be sent a tcpip_event - * with the new connection request. - * - * \note Port numbers must always be given in network byte order. The - * functions UIP_HTONS() and uip_htons() can be used to convert port numbers - * from host byte order to network byte order. - * - * \param port The port number in network byte order. - * - */ -CCIF void tcp_listen(uint16_t port, struct process *handler); - -/** - * Close a listening TCP port. - * - * This function closes a listening TCP port. - * - * \note Port numbers must always be given in network byte order. The - * functions UIP_HTONS() and uip_htons() can be used to convert port numbers - * from host byte order to network byte order. - * - * \param port The port number in network byte order. - * - */ -CCIF void tcp_unlisten(uint16_t port, struct process *handler); - -/** - * Open a TCP connection to the specified IP address and port. - * - * This function opens a TCP connection to the specified port at the - * host specified with an IP address. Additionally, an opaque pointer - * can be attached to the connection. This pointer will be sent - * together with uIP events to the process. - * - * \note The port number must be provided in network byte order so a - * conversion with UIP_HTONS() usually is necessary. - * - * \note This function will only create the connection. The connection - * is not opened directly. uIP will try to open the connection the - * next time the uIP stack is scheduled by Contiki. - * - * \param ripaddr Pointer to the IP address of the remote host. - * \param port Port number in network byte order. - * \param appstate Pointer to application defined data. - * - * \return A pointer to the newly created connection, or NULL if - * memory could not be allocated for the connection. - * - */ -CCIF struct uip_conn *tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port, - void *appstate, struct process *process); - -/** - * Cause a specified TCP connection to be polled. - * - * This function causes uIP to poll the specified TCP connection. The - * function is used when the application has data that is to be sent - * immediately and do not wish to wait for the periodic uIP polling - * mechanism. - * - * \param conn A pointer to the TCP connection that should be polled. - * - */ -void tcpip_poll_tcp(struct uip_conn *conn); - -void tcpip_resend_syn(struct uip_conn *conn, struct net_buf *buf); - -/** @} */ - -/** - * \name UDP functions - * @{ - */ - -struct uip_udp_conn; -/** - * Attach the current process to a UDP connection - * - * This function attaches the current process to a UDP - * connection. Each UDP connection must have a process attached to it - * in order for the process to be able to receive and send data over - * the connection. Additionally, this function can add a pointer with - * connection state to the connection. - * - * \param conn A pointer to the UDP connection. - * - * \param appstate An opaque pointer that will be passed to the - * process whenever an event occurs on the connection. - * - */ -void udp_attach(struct uip_udp_conn *conn, - void *appstate); -#define udp_markconn(conn, appstate) udp_attach(conn, appstate) - -/** - * Create a new UDP connection. - * - * This function creates a new UDP connection with the specified - * remote endpoint. - * - * \note The port number must be provided in network byte order so a - * conversion with UIP_HTONS() usually is necessary. - * - * \sa udp_bind() - * - * \param ripaddr Pointer to the IP address of the remote host. - * \param port Port number in network byte order. - * \param appstate Pointer to application defined data. - * - * \return A pointer to the newly created connection, or NULL if - * memory could not be allocated for the connection. - */ -CCIF struct uip_udp_conn *udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, - void *appstate); - -/** - * Create a new UDP broadcast connection. - * - * This function creates a new (link-local) broadcast UDP connection - * to a specified port. - * - * \param port Port number in network byte order. - * \param appstate Pointer to application defined data. - * - * \return A pointer to the newly created connection, or NULL if - * memory could not be allocated for the connection. - */ -struct uip_udp_conn *udp_broadcast_new(uint16_t port, void *appstate); - -/** - * Bind a UDP connection to a local port. - * - * This function binds a UDP connection to a specified local port. - * - * When a connection is created with udp_new(), it gets a local port - * number assigned automatically. If the application needs to bind the - * connection to a specified local port, this function should be used. - * - * \note The port number must be provided in network byte order so a - * conversion with UIP_HTONS() usually is necessary. - * - * \param conn A pointer to the UDP connection that is to be bound. - * \param port The port number in network byte order to which to bind - * the connection. - */ -#define udp_bind(conn, port) uip_udp_bind(conn, port) - -/** - * Unbind a UDP connection. - * - * This function unbinds a UDP connection. - * - * When a connection is created with udp_new(), it gets a local port - * number assigned automatically. If the application needs to unbind the - * connection from local port, this function should be used. - * - * \param conn A pointer to the UDP connection that is to be bound. - */ -#define udp_unbind(conn) uip_udp_remove(conn) - -/** - * Cause a specified UDP connection to be polled. - * - * This function causes uIP to poll the specified UDP connection. The - * function is used when the application has data that is to be sent - * immediately and do not wish to wait for the periodic uIP polling - * mechanism. - * - * \param conn A pointer to the UDP connection that should be polled. - * - */ -CCIF void tcpip_poll_udp(struct uip_udp_conn *conn); - -/** @} */ - -/** - * \name ICMPv6 functions - * @{ - */ - -#if UIP_CONF_ICMP6 - -/** - * The ICMP6 event. - * - * This event is posted to a process whenever a uIP ICMP event has occurred. - */ -CCIF extern process_event_t tcpip_icmp6_event; - -/** - * \brief register an ICMPv6 callback - * \return 0 if success, 1 if failure (one application already registered) - * - * This function just registers a process to be polled when - * an ICMPv6 message is received. - * If no application registers, some ICMPv6 packets will be - * processed by the "kernel" as usual (NS, NA, RS, RA, Echo request), - * others will be dropped. - * If an application registers here, it will be polled with a - * process_post_synch every time an ICMPv6 packet is received. - */ -uint8_t icmp6_new(void *appstate); - -/** - * This function is called at reception of an ICMPv6 packet - * If an application registered as an ICMPv6 listener (with - * icmp6_new), it will be called through a process_post_synch() - */ -void tcpip_icmp6_call(uint8_t type); -#endif /*UIP_CONF_ICMP6*/ - -/** @} */ -/** - * The uIP event. - * - * This event is posted to a process whenever a uIP event has occurred. - */ -CCIF extern process_event_t tcpip_event; - -/** - * \name TCP/IP packet processing - * @{ - */ - -/** - * \brief Deliver an incoming packet to the TCP/IP stack - * - * This function is called by network device drivers to - * deliver an incoming packet to the TCP/IP stack. The - * incoming packet must be present in the uip_buf buffer, - * and the length of the packet must be in the global - * uip_len variable. If 0 is returned, then there was - * an error in the packet and it is discarded. The caller - * can then release the net_buf - */ -CCIF uint8_t tcpip_input(struct net_buf *buf); - -/** - * \brief Output packet to layer 2 - * The eventual parameter is the MAC address of the destination. - */ -uint8_t tcpip_output(struct net_buf *buf, const uip_lladdr_t *); -void tcpip_set_outputfunc(uint8_t (* f)(struct net_buf *buf, const uip_lladdr_t *)); - -/** - * \brief This function does address resolution and then calls tcpip_output - */ -#if NETSTACK_CONF_WITH_IPV6 -uint8_t tcpip_ipv6_output(struct net_buf *buf); -#endif - -/** - * \brief Is forwarding generally enabled? - */ -extern unsigned char tcpip_do_forwarding; - -/* - * Are we at the moment forwarding the contents of uip_buf[]? - */ -extern unsigned char tcpip_is_forwarding; - - -#define tcpip_set_forwarding(forwarding) tcpip_do_forwarding = (forwarding) - -/** @} */ - -PROCESS_NAME(tcpip_process); - -#endif /* TCPIP_H_ */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/ip/udp-socket.c b/net/ip/contiki/ip/udp-socket.c deleted file mode 100644 index f1872d9465cc3faa4f9a399304339bcf738dba78..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/udp-socket.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2012-2014, Thingsquare, http://www.thingsquare.com/. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include - -#include "contiki-net.h" -#include "udp-socket.h" - -#include - -PROCESS(udp_socket_process, "UDP socket process"); - -#if 0 -/* Moved to net_buf */ -static uint8_t buf[UIP_BUFSIZE]; -#endif - -#define UIP_IP_BUF(buf) ((struct uip_udpip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) - - -/*---------------------------------------------------------------------------*/ -static void -init(void) -{ - static uint8_t inited = 0; - if(!inited) { - inited = 1; - process_start(&udp_socket_process, NULL, NULL); - } -} -/*---------------------------------------------------------------------------*/ -int -udp_socket_register(struct udp_socket *c, - void *ptr, - udp_socket_input_callback_t input_callback) -{ - init(); - - if(c == NULL) { - return -1; - } - c->ptr = ptr; - c->input_callback = input_callback; - - c->p = PROCESS_CURRENT(); - PROCESS_CONTEXT_BEGIN(&udp_socket_process); - c->udp_conn = udp_new(NULL, 0, c); - PROCESS_CONTEXT_END(); - - if(c->udp_conn == NULL) { - return -1; - } - return 1; -} -/*---------------------------------------------------------------------------*/ -int -udp_socket_close(struct udp_socket *c) -{ - if(c == NULL) { - return -1; - } - if(c->udp_conn != NULL) { - uip_udp_remove(c->udp_conn); - return 1; - } - return -1; -} -/*---------------------------------------------------------------------------*/ -int -udp_socket_bind(struct udp_socket *c, - uint16_t local_port) -{ - if(c == NULL || c->udp_conn == NULL) { - return -1; - } - udp_bind(c->udp_conn, UIP_HTONS(local_port)); - - return 1; -} -/*---------------------------------------------------------------------------*/ -int -udp_socket_connect(struct udp_socket *c, - uip_ipaddr_t *remote_addr, - uint16_t remote_port) -{ - if(c == NULL || c->udp_conn == NULL) { - return -1; - } - - if(remote_addr != NULL) { - uip_ipaddr_copy(&c->udp_conn->ripaddr, remote_addr); - } - c->udp_conn->rport = UIP_HTONS(remote_port); - return 1; -} -/*---------------------------------------------------------------------------*/ -int -udp_socket_send(struct net_buf *buf, struct udp_socket *c, - const void *data, uint16_t datalen) -{ - if(c == NULL || c->udp_conn == NULL) { - return -1; - } - - uip_udp_packet_send(buf, c->udp_conn, data, datalen); - return datalen; -} -/*---------------------------------------------------------------------------*/ -int -udp_socket_sendto(struct net_buf *buf, struct udp_socket *c, - const void *data, uint16_t datalen, - const uip_ipaddr_t *to, - uint16_t port) -{ - if(c == NULL || c->udp_conn == NULL) { - return -1; - } - - if(c->udp_conn != NULL) { - return uip_udp_packet_sendto(buf, c->udp_conn, data, datalen, - to, UIP_HTONS(port)); - } - return -1; -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(udp_socket_process, ev, data, buf, user_data) -{ - struct udp_socket *c; - PROCESS_BEGIN(); - - while(1) { - PROCESS_WAIT_EVENT(); - if(ev == tcpip_event) { - - /* An appstate pointer is passed to use from the IP stack - through the 'data' pointer. We registered this appstate when - we did the udp_new() call in udp_socket_register() as the - struct udp_socket pointer. So we extract this - pointer and use it when calling the reception callback. */ - c = (struct udp_socket *)data; - - /* Defensive coding: although the appstate *should* be non-null - here, we make sure to avoid the program crashing on us. */ - if(c != NULL) { - - /* If we were called because of incoming data, we should call - the reception callback. */ - if(uip_newdata(buf)) { - /* Copy the data from the uIP data buffer into our own - buffer to avoid the uIP buffer being messed with by the - callee. */ -#if 0 - /* Note that we cannot do this as the stack is suppose to be - * re-entrant. - */ - memcpy(bad_buf, uip_appdata(buf), uip_datalen(buf)); -#endif - /* Call the client process. We use the PROCESS_CONTEXT - mechanism to temporarily switch process context to the - client process. */ - if(c->input_callback != NULL) { - PROCESS_CONTEXT_BEGIN(c->p); - c->input_callback(c, c->ptr, - &(UIP_IP_BUF(buf)->srcipaddr), - UIP_HTONS(UIP_IP_BUF(buf)->srcport), - &(UIP_IP_BUF(buf)->destipaddr), - UIP_HTONS(UIP_IP_BUF(buf)->destport), - uip_appdata(buf), uip_datalen(buf)); - PROCESS_CONTEXT_END(); - } - } - } - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/ip/udp-socket.h b/net/ip/contiki/ip/udp-socket.h deleted file mode 100644 index ddcc45dae0059a9a3c84db57498ea60e60fec67d..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/udp-socket.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2012-2014, Thingsquare, http://www.thingsquare.com/. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef UDP_SOCKET_H -#define UDP_SOCKET_H - -#include - -#include "contiki/ip/uip.h" - -struct udp_socket; - -/** - * \brief A UDP socket callback function - * \param buf Buffer that received the data - * \param c A pointer to the struct udp_socket that received the data - * \param ptr An opaque pointer that was specified when the UDP socket was registered with udp_socket_register() - * \param source_addr The IP address from which the datagram was sent - * \param source_port The UDP port number, in host byte order, from which the datagram was sent - * \param dest_addr The IP address that this datagram was sent to - * \param dest_port The UDP port number, in host byte order, that the datagram was sent to - * \param data A pointer to the data contents of the UDP datagram - * \param datalen The length of the data being pointed to by the data pointer - * - * Each UDP socket has a callback function that is - * registered as part of the call to - * udp_socket_register(). The callback function gets - * called every time a UDP packet is received. - */ -typedef void (* udp_socket_input_callback_t)(struct udp_socket *c, - void *ptr, - const uip_ipaddr_t *source_addr, - uint16_t source_port, - const uip_ipaddr_t *dest_addr, - uint16_t dest_port, - const uint8_t *data, - uint16_t datalen); - -struct udp_socket { - udp_socket_input_callback_t input_callback; - void *ptr; - - struct process *p; - - struct uip_udp_conn *udp_conn; -}; - -/** - * \brief Register a UDP socket - * \param c A pointer to the struct udp_socket that should be registered - * \param ptr An opaque pointer that will be passed to callbacks - * \param receive_callback A function pointer to the callback function that will be called when data arrives - * \retval -1 The registration failed - * \retval 1 The registration succeeded - * - * This function registers the UDP socket with the - * system. A UDP socket must be registered before any data - * can be sent or received over the socket. - * - * The caller must allocate memory for the struct - * udp_socket that is to be registered. - * - * A UDP socket can begin to receive data by calling - * udp_socket_bind(). - * - */ -int udp_socket_register(struct udp_socket *c, - void *ptr, - udp_socket_input_callback_t receive_callback); - -/** - * \brief Bind a UDP socket to a local port - * \param c A pointer to the struct udp_socket that should be bound to a local port - * \param local_port The UDP port number, in host byte order, to bind the UDP socket to - * \retval -1 Binding the UDP socket to the local port failed - * \retval 1 Binding the UDP socket to the local port succeeded - * - * This function binds the UDP socket to a local port so - * that it will begin to receive data that arrives on the - * specified port. A UDP socket will receive data - * addressed to the specified port number on any IP - * address of the host. - * - * A UDP socket that is bound to a local port will use - * this port number as a source port in outgoing UDP - * messages. - * - */ -int udp_socket_bind(struct udp_socket *c, - uint16_t local_port); - -/** - * \brief Bind a UDP socket to a remote address and port - * \param c A pointer to the struct udp_socket that should be connected - * \param remote_addr The IP address of the remote host, or NULL if the UDP socket should only be connected to a specific port - * \param remote_port The UDP port number, in host byte order, to which the UDP socket should be connected - * \retval -1 Connecting the UDP socket failed - * \retval 1 Connecting the UDP socket succeeded - * - * This function connects the UDP socket to a specific - * remote port and optional remote IP address. When a UDP - * socket is connected to a remote port and address, it - * will only receive packets that are sent from the remote - * port and address. When sending data over a connected - * UDP socket, the data will be sent to the connected - * remote address. - * - * A UDP socket can be connected to a remote port, but not - * a remote IP address, by providing a NULL parameter as - * the remote_addr parameter. This lets the UDP socket - * receive data from any IP address on the specified port. - * - */ -int udp_socket_connect(struct udp_socket *c, - uip_ipaddr_t *remote_addr, - uint16_t remote_port); -/** - * \brief Send data on a UDP socket - * \param buf Buffer to send - * \param c A pointer to the struct udp_socket on which the data should be sent - * \param data A pointer to the data that should be sent - * \param datalen The length of the data to be sent - * \return The number of bytes sent, or -1 if an error occurred - * - * This function sends data over a UDP socket. The UDP - * socket must have been connected to a remote address and - * port with udp_socket_connect(). - * - */ -int udp_socket_send(struct net_buf *buf, struct udp_socket *c, - const void *data, uint16_t datalen); - -/** - * \brief Send data on a UDP socket to a specific address and port - * \param buf Buffer to send - * \param c A pointer to the struct udp_socket on which the data should be sent - * \param data A pointer to the data that should be sent - * \param datalen The length of the data to be sent - * \param addr The IP address to which the data should be sent - * \param port The UDP port number, in host byte order, to which the data should be sent - * \return The number of bytes sent, or -1 if an error occurred - * - * This function sends data over a UDP socket to a - * specific address and port. - * - * The UDP socket does not have to be connected to use - * this function. - * - */ -int udp_socket_sendto(struct net_buf *buf, struct udp_socket *c, - const void *data, uint16_t datalen, - const uip_ipaddr_t *addr, uint16_t port); - -/** - * \brief Close a UDP socket - * \param c A pointer to the struct udp_socket to be closed - * \retval -1 If closing the UDP socket failed - * \retval 1 If closing the UDP socket succeeded - * - * This function closes a UDP socket that has previously - * been registered with udp_socket_register(). All - * registered UDP sockets must be closed before exiting - * the process that registered them, or undefined behavior - * may occur. - * - */ -int udp_socket_close(struct udp_socket *c); - -#endif /* UDP_SOCKET_H */ diff --git a/net/ip/contiki/ip/uip-debug.c b/net/ip/contiki/ip/uip-debug.c deleted file mode 100644 index 6822a2e956fc62c33bbbd5065d4010b8381b9229..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/uip-debug.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -/** - * \file - * A set of debugging tools - * \author - * Nicolas Tsiftes - * Niclas Finne - * Joakim Eriksson - */ - -#include "contiki/ip/uip-debug.h" - -/*---------------------------------------------------------------------------*/ -void -uip_debug_ipaddr_print(const uip_ipaddr_t *addr) -{ - if(addr == NULL || addr->u8 == NULL) { - printf("(NULL IP addr)"); - return; - } -#if NETSTACK_CONF_WITH_IPV6 - uint16_t a; - unsigned int i; - int f; - for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { - a = (addr->u8[i] << 8) + addr->u8[i + 1]; - if(a == 0 && f >= 0) { - if(f++ == 0) { - PRINTA("::"); - } - } else { - if(f > 0) { - f = -1; - } else if(i > 0) { - PRINTA(":"); - } - PRINTA("%x", a); - } - } -#else /* NETSTACK_CONF_WITH_IPV6 */ - PRINTA("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]); -#endif /* NETSTACK_CONF_WITH_IPV6 */ -} -/*---------------------------------------------------------------------------*/ -void -uip_debug_lladdr_print(const uip_lladdr_t *addr) -{ - unsigned int i; - for(i = 0; i < sizeof(uip_lladdr_t); i++) { - if(i > 0) { - PRINTA(":"); - } - PRINTA("%x", addr->addr[i]); - } -} -/*---------------------------------------------------------------------------*/ -void -uip_debug_hex_dump(const unsigned char *buffer, int len) -{ - int i = 0; - - while (len--) { - if(*buffer <= 0xf) - PRINTA("0%X ", *buffer++); - else - PRINTA("%X ", *buffer++); - - i++; - if (i % 8 == 0) { - if (i % 16 == 0) { - PRINTA("\n"); - } else { - PRINTA(" "); - } - } - } -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/ip/uip-debug.h b/net/ip/contiki/ip/uip-debug.h deleted file mode 100644 index 64af051059da5aedacff0384a37e45f8b7b863d2..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/uip-debug.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ -/** - * \file - * A set of debugging macros. - * - * \author Nicolas Tsiftes - * Niclas Finne - * Joakim Eriksson - */ - -#ifndef UIP_DEBUG_H -#define UIP_DEBUG_H - -#include "contiki/ip/uip.h" -#include - -void uip_debug_ipaddr_print(const uip_ipaddr_t *addr); -void uip_debug_lladdr_print(const uip_lladdr_t *addr); -void uip_debug_hex_dump(const unsigned char *buffer, int len); - -#if defined(CONFIG_STDOUT_CONSOLE) -#include -#define PRINT printf -#else -#include -#define PRINT printk -#endif - -#define DEBUG_NONE 0 -#define DEBUG_PRINT 1 -#define DEBUG_ANNOTATE 2 -#define DEBUG_FULL DEBUG_ANNOTATE | DEBUG_PRINT - -#if (DEBUG == 1) -#if defined(CONFIG_NETWORK_IP_STACK_DEBUG_PRINT) -#define _DEBUG_ DEBUG_PRINT -#elif defined(CONFIG_NETWORK_IP_STACK_DEBUG_ANNOTATE) -#define _DEBUG_ DEBUG_ANNOTATE -#elif defined(CONFIG_NETWORK_IP_STACK_DEBUG_FULL) -#define _DEBUG_ DEBUG_FULL -#else -#define _DEBUG_ DEBUG_NONE -#endif -#endif - -/* PRINTA will always print if the debug routines are called directly */ -#ifdef __AVR__ -#include -#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args) -#else -#define PRINTA(...) PRINT(__VA_ARGS__) -#endif - -#if (_DEBUG_) & DEBUG_ANNOTATE -#ifdef __AVR__ -#define ANNOTATE(FORMAT,args...) printf_P(PSTR(FORMAT),##args) -#else -#define ANNOTATE(...) PRINT(__VA_ARGS__) -#endif -#else -#define ANNOTATE(...) -#endif /* (_DEBUG_) & DEBUG_ANNOTATE */ - -#if (_DEBUG_) & DEBUG_PRINT -#ifdef __AVR__ -#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) -#else -#define PRINTF(...) PRINT(__VA_ARGS__) -#endif -#define PRINT6ADDR(addr) uip_debug_ipaddr_print(addr) -#define PRINTLLADDR(lladdr) uip_debug_lladdr_print(lladdr) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(lladdr) -#endif /* (_DEBUG_) & DEBUG_PRINT */ - -#endif diff --git a/net/ip/contiki/ip/uip-nameserver.c b/net/ip/contiki/ip/uip-nameserver.c deleted file mode 100644 index 367fe421de7de759a9c7d88dcec363e64fc8aa4e..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/uip-nameserver.c +++ /dev/null @@ -1,236 +0,0 @@ -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * uIP Name Server interface - * \author Víctor Ariño - */ - -/* - * Copyright (c) 2014, tado° GmbH. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#include "contiki.h" -#include "contiki-net.h" - -#include "lib/list.h" -#include "lib/memb.h" - -#include -/** \brief Nameserver record */ -typedef struct uip_nameserver_record { - struct uip_nameserver_record *next; - uip_ipaddr_t ip; - uint32_t added; - uint32_t lifetime; -} uip_nameserver_record; - -#if UIP_NAMESERVER_POOL_SIZE > 1 -/** \brief Initialization flag */ -static uint8_t initialized = 0; -#endif - -/** \name List and memory block - * @{ - */ -#if UIP_NAMESERVER_POOL_SIZE > 1 -LIST(dns); -MEMB(dnsmemb, uip_nameserver_record, UIP_NAMESERVER_POOL_SIZE); -#else /* UIP_NAMESERVER_POOL_SIZE > 1 */ -static uip_ipaddr_t serveraddr; -static uint32_t serverlifetime; -#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ -/** @} */ - -/** \brief Expiration time in seconds */ -#define DNS_EXPIRATION(r) \ - (((UIP_NAMESERVER_INFINITE_LIFETIME - r->added) <= r->lifetime) ? \ - UIP_NAMESERVER_INFINITE_LIFETIME : r->added + r->lifetime) -/*----------------------------------------------------------------------------*/ -/** - * Initialize the module variables - */ -#if UIP_NAMESERVER_POOL_SIZE > 1 -static CC_INLINE void -init(void) -{ - list_init(dns); - memb_init(&dnsmemb); - initialized = 1; -} -#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ -/*----------------------------------------------------------------------------*/ -void -uip_nameserver_update(uip_ipaddr_t *nameserver, uint32_t lifetime) -{ -#if UIP_NAMESERVER_POOL_SIZE > 1 - register uip_nameserver_record *e; - - if(initialized == 0) { - init(); - } - - for(e = list_head(dns); e != NULL; e = list_item_next(e)) { - if(uip_ipaddr_cmp(&e->ip, nameserver)) { - break; - /* RFC6106: In case there's no more space, the new servers should replace - * the the eldest ones */ - } - } - - if(e == NULL) { - if((e = memb_alloc(&dnsmemb)) != NULL) { - list_add(dns, e); - } else { - uip_nameserver_record *p; - for(e = list_head(dns), p = list_head(dns); p != NULL; - p = list_item_next(p)) { - if(DNS_EXPIRATION(p) < DNS_EXPIRATION(e)) { - e = p; - } - } - } - } - - /* RFC6106: In case the entry is existing the expiration time must be - * updated. Otherwise, new entries are added. */ - if(e != NULL) { - if(lifetime == 0) { - memb_free(&dnsmemb, e); - list_remove(dns, e); - } else { - e->added = clock_seconds(); - e->lifetime = lifetime; - uip_ipaddr_copy(&e->ip, nameserver); - } - } -#else /* UIP_NAMESERVER_POOL_SIZE > 1 */ - uip_ipaddr_copy(&serveraddr, nameserver); - serverlifetime = lifetime; -#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ -} -/*----------------------------------------------------------------------------*/ -#if UIP_NAMESERVER_POOL_SIZE > 1 -/** - * Purge expired records - */ -static void -purge(void) -{ - register uip_nameserver_record *e = NULL; - uint32_t time = clock_seconds(); - for(e = list_head(dns); e != NULL; e = list_item_next(e)) { - if(DNS_EXPIRATION(e) < time) { - list_remove(dns, e); - memb_free(&dnsmemb, e); - e = list_head(dns); - } - } -} -#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ -/*----------------------------------------------------------------------------*/ -uip_ipaddr_t * -uip_nameserver_get(uint8_t num) -{ -#if UIP_NAMESERVER_POOL_SIZE > 1 - uint8_t i; - uip_nameserver_record *e = NULL; - - if(initialized == 0) { - return NULL; - } - purge(); - for(i = 1, e = list_head(dns); e != NULL && i <= num; - i++, e = list_item_next(e)) { - } - - if(e != NULL) { - return &e->ip; - } - return NULL; -#else /* UIP_NAMESERVER_POOL_SIZE > 1 */ - if(num > 0) { - return NULL; - } - return &serveraddr; -#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ -} -/*----------------------------------------------------------------------------*/ -uint32_t -uip_nameserver_next_expiration(void) -{ -#if UIP_NAMESERVER_POOL_SIZE > 1 - register uip_nameserver_record *e = NULL; - uint32_t exp = UIP_NAMESERVER_INFINITE_LIFETIME; - uint32_t t; - - if(initialized == 0 || list_length(dns) == 0) { - return 0; - } - purge(); - for(e = list_head(dns); e != NULL; e = list_item_next(e)) { - t = DNS_EXPIRATION(e); - if(t < exp) { - exp = t; - } - } - - return exp; -#else /* UIP_NAMESERVER_POOL_SIZE > 1 */ - return serverlifetime; -#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ -} -/*----------------------------------------------------------------------------*/ -uint16_t -uip_nameserver_count(void) -{ -#if UIP_NAMESERVER_POOL_SIZE > 1 - if(initialized == 0) { - return 0; - } - return list_length(dns); -#else /* UIP_NAMESERVER_POOL_SIZE > 1 */ -#if NETSTACK_CONF_WITH_IPV6 - if(uip_is_addr_unspecified(&serveraddr)) { -#else /* NETSTACK_CONF_WITH_IPV6 */ - if(uip_ipaddr_cmp(&serveraddr, &uip_all_zeroes_addr)) { -#endif /* NETSTACK_CONF_WITH_IPV6 */ - return 0; - } else { - return 1; - } -#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ -} -/*----------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/ip/uip-nameserver.h b/net/ip/contiki/ip/uip-nameserver.h deleted file mode 100644 index 41dcf58c8c15a87ad2eb645552eb6e86ef8687b2..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/uip-nameserver.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * uIP Name Server interface - * \author Víctor Ariño - */ - -/* - * Copyright (c) 2014, tado° GmbH. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#ifndef UIP_NAMESERVER_H_ -#define UIP_NAMESERVER_H_ - -/** - * \name General - * @{ - */ -/** \brief Number of Nameservers to keep */ -#ifndef UIP_CONF_NAMESERVER_POOL_SIZE -#define UIP_NAMESERVER_POOL_SIZE 1 -#else /* UIP_CONF_NAMESERVER_POOL_SIZE */ -#define UIP_NAMESERVER_POOL_SIZE UIP_CONF_NAMESERVER_POOL_SIZE -#endif /* UIP_CONF_NAMESERVER_POOL_SIZE */ -/** \brief Infinite Lifetime indicator */ -#define UIP_NAMESERVER_INFINITE_LIFETIME 0xFFFFFFFF -/** @} */ - -/** - * \name Nameserver maintenance - * @{ - */ -/** - * \brief Insert or update a nameserver into/from the pool - * - * The list is kept according to the RFC6106, which indicates that new entries - * will replace old ones (with lower lifetime) and existing entries will update - * their lifetimes. - * - * \param nameserver Pointer to the nameserver ip address - * \param lifetime Life time of the given address. Minimum is 0, which is - * considered to remove an entry. Maximum is 0xFFFFFFFF which - * is considered infinite. - */ -void uip_nameserver_update(uip_ipaddr_t *nameserver, uint32_t lifetime); - -/** - * \brief Get a Nameserver ip address given in RA - * - * \param num The number of the nameserver to obtain, starting at 0 and going - * up to the pool size. - */ -uip_ipaddr_t *uip_nameserver_get(uint8_t num); - -/** - * \brief Get next expiration time - * - * The least expiration time is returned - */ -uint32_t uip_nameserver_next_expiration(void); - -/** - * \brief Get the number of recorded name servers - */ -uint16_t uip_nameserver_count(void); -/** @} */ - -#endif /* UIP_NAMESERVER_H_ */ -/** @} */ diff --git a/net/ip/contiki/ip/uip-packetqueue.c b/net/ip/contiki/ip/uip-packetqueue.c deleted file mode 100644 index fd36788d43be6f1fb68925280ba28122b9f24ed3..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/uip-packetqueue.c +++ /dev/null @@ -1,85 +0,0 @@ -#include - -#include "contiki/ip/uip.h" - -#include "lib/memb.h" - -#include "contiki/ip/uip-packetqueue.h" - -#define MAX_NUM_QUEUED_PACKETS 2 -MEMB(packets_memb, struct uip_packetqueue_packet, MAX_NUM_QUEUED_PACKETS); - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_PACKET_QUEUE -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -/*---------------------------------------------------------------------------*/ -static void -packet_timedout(struct net_buf *buf, void *ptr) -{ - struct uip_packetqueue_handle *h = ptr; - - PRINTF("uip_packetqueue_free timed out handle %p, packet %p\n", h, h->packet); - memb_free(&packets_memb, h->packet); - h->packet = NULL; -} -/*---------------------------------------------------------------------------*/ -void -uip_packetqueue_new(struct uip_packetqueue_handle *handle) -{ - PRINTF("uip_packetqueue_new %p\n", handle); - handle->packet = NULL; -} -/*---------------------------------------------------------------------------*/ -struct uip_packetqueue_packet * -uip_packetqueue_alloc(struct net_buf *buf, struct uip_packetqueue_handle *handle, clock_time_t lifetime) -{ - PRINTF("uip_packetqueue_alloc %p\n", handle); - if(handle->packet != NULL) { - PRINTF("handle->packet != NULL, so failed to alloc\n"); - return NULL; - } - handle->packet = memb_alloc(&packets_memb); - if(handle->packet != NULL) { - PRINTF("uip_packetqueue_alloc packet %p\n", handle->packet); - ctimer_set(buf, &handle->packet->lifetimer, lifetime, - packet_timedout, handle); - } else { - PRINTF("uip_packetqueue_alloc failed\n"); - } - return handle->packet; -} -/*---------------------------------------------------------------------------*/ -void -uip_packetqueue_free(struct uip_packetqueue_handle *handle) -{ - PRINTF("uip_packetqueue_free %p\n", handle); - if(handle->packet != NULL) { - PRINTF("uip_packetqueue_free packet %p\n", handle->packet); - ctimer_stop(&handle->packet->lifetimer); - memb_free(&packets_memb, handle->packet); - handle->packet = NULL; - } -} -/*---------------------------------------------------------------------------*/ -uint8_t * -uip_packetqueue_buf(struct uip_packetqueue_handle *h) -{ - return h->packet != NULL? h->packet->queue_buf: NULL; -} -/*---------------------------------------------------------------------------*/ -uint16_t -uip_packetqueue_buflen(struct uip_packetqueue_handle *h) -{ - return h->packet != NULL? h->packet->queue_buf_len: 0; -} -/*---------------------------------------------------------------------------*/ -void -uip_packetqueue_set_buflen(struct uip_packetqueue_handle *h, uint16_t len) -{ - if(h->packet != NULL) { - h->packet->queue_buf_len = len; - } -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/ip/uip-packetqueue.h b/net/ip/contiki/ip/uip-packetqueue.h deleted file mode 100644 index 4f8aa1658316f2147fde47823e590a8c6a59d624..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/uip-packetqueue.h +++ /dev/null @@ -1,37 +0,0 @@ -#include - -#ifndef UIP_PACKETQUEUE_H -#define UIP_PACKETQUEUE_H - -#include "sys/ctimer.h" - -struct uip_packetqueue_handle; - -struct uip_packetqueue_packet { - struct uip_ds6_queued_packet *next; - uint8_t queue_buf[UIP_BUFSIZE - UIP_LLH_LEN]; - uint16_t queue_buf_len; - struct ctimer lifetimer; - struct uip_packetqueue_handle *handle; -}; - -struct uip_packetqueue_handle { - struct uip_packetqueue_packet *packet; -}; - -void uip_packetqueue_new(struct uip_packetqueue_handle *handle); - - -struct uip_packetqueue_packet * -uip_packetqueue_alloc(struct net_buf *buf, struct uip_packetqueue_handle *handle, clock_time_t lifetime); - - -void -uip_packetqueue_free(struct uip_packetqueue_handle *handle); - -uint8_t *uip_packetqueue_buf(struct uip_packetqueue_handle *h); -uint16_t uip_packetqueue_buflen(struct uip_packetqueue_handle *h); -void uip_packetqueue_set_buflen(struct uip_packetqueue_handle *h, uint16_t len); - - -#endif /* UIP_PACKETQUEUE_H */ diff --git a/net/ip/contiki/ip/uip-split.h b/net/ip/contiki/ip/uip-split.h deleted file mode 100644 index 49f55fba682d9976db4526a7fe4d51b3d4afab03..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/uip-split.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ -/** - * \addtogroup uip - * @{ - */ - -/** - * \defgroup uipsplit uIP TCP throughput booster hack - * @{ - * - * The basic uIP TCP implementation only allows each TCP connection to - * have a single TCP segment in flight at any given time. Because of - * the delayed ACK algorithm employed by most TCP receivers, uIP's - * limit on the amount of in-flight TCP segments seriously reduces the - * maximum achievable throughput for sending data from uIP. - * - * The uip-split module is a hack which tries to remedy this - * situation. By splitting maximum sized outgoing TCP segments into - * two, the delayed ACK algorithm is not invoked at TCP - * receivers. This improves the throughput when sending data from uIP - * by orders of magnitude. - * - * The uip-split module uses the uip-fw module (uIP IP packet - * forwarding) for sending packets. Therefore, the uip-fw module must - * be set up with the appropriate network interfaces for this module - * to work. - */ - - -/** - * \file - * Module for splitting outbound TCP segments in two to avoid the - * delayed ACK throughput degradation. - * \author - * Adam Dunkels - * - */ - -#ifndef UIP_SPLIT_H_ -#define UIP_SPLIT_H_ - -/** - * Handle outgoing packets. - * - * This function inspects an outgoing packet in the uip_buf buffer and - * sends it out using the uip_fw_output() function. If the packet is a - * full-sized TCP segment it will be split into two segments and - * transmitted separately. This function should be called instead of - * the actual device driver output function, or the uip_fw_output() - * function. - * - * The headers of the outgoing packet is assumed to be in the uip_buf - * buffer and the payload is assumed to be wherever uip_appdata - * points. The length of the outgoing packet is assumed to be in the - * uip_len variable. - * - */ -void uip_split_output(void); - -#endif /* UIP_SPLIT_H_ */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/ip/uip-udp-packet.c b/net/ip/contiki/ip/uip-udp-packet.c deleted file mode 100644 index db7382ad020548ee93144881b09ea229ae982b91..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/uip-udp-packet.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Module for sending UDP packets through uIP. - * \author - * Adam Dunkels - */ - -#include - -#include "contiki-conf.h" - -#include "contiki/ip/uip-udp-packet.h" -#include "contiki/ipv6/multicast/uip-mcast6.h" - -#include - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_UDP_PACKET -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -/*---------------------------------------------------------------------------*/ -uint8_t -uip_udp_packet_send(struct net_buf *buf, struct uip_udp_conn *c, const void *data, int len) -{ -#if UIP_UDP - if(data != NULL) { - uip_set_udp_conn(buf) = c; - uip_slen(buf) = len; - memcpy(&uip_buf(buf)[UIP_LLH_LEN + UIP_IPUDPH_LEN], data, - len > UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN? - UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN: len); - if (uip_process(&buf, UIP_UDP_SEND_CONN) == 0) { - /* The packet was dropped, we can return now */ - return 0; - } - -#if UIP_CONF_IPV6_MULTICAST - /* Let the multicast engine process the datagram before we send it */ - if(uip_is_addr_mcast_routable(&uip_udp_conn(buf)->ripaddr)) { - UIP_MCAST6.out(); - } -#endif /* UIP_IPV6_MULTICAST */ - - if (!uip_len(buf)) { - /* Message was successfully sent, just bail out now. */ - goto out; - } - -#if NETSTACK_CONF_WITH_IPV6 - if (!tcpip_ipv6_output(buf)) { - return 0; - } -#else - if(uip_len(buf) > 0) { - tcpip_output(buf, NULL); - } -#endif - } -out: - uip_slen(buf) = 0; -#endif /* UIP_UDP */ - return 1; -} -/*---------------------------------------------------------------------------*/ -uint8_t -uip_udp_packet_sendto(struct net_buf *buf, struct uip_udp_conn *c, const void *data, int len, - const uip_ipaddr_t *toaddr, uint16_t toport) -{ - uip_ipaddr_t curaddr; - uint16_t curport; - uint8_t ret = 0; - - if(toaddr != NULL) { - /* Save current IP addr/port. */ - uip_ipaddr_copy(&curaddr, &c->ripaddr); - curport = c->rport; - - /* Load new IP addr/port */ - uip_ipaddr_copy(&c->ripaddr, toaddr); - c->rport = toport; - - ret = uip_udp_packet_send(buf, c, data, len); - - /* Restore old IP addr/port */ - uip_ipaddr_copy(&c->ripaddr, &curaddr); - c->rport = curport; - } - - return ret; -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/ip/uip-udp-packet.h b/net/ip/contiki/ip/uip-udp-packet.h deleted file mode 100644 index bb47262e854979bed412983db7bf1870847743c8..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/uip-udp-packet.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header file for module for sending UDP packets through uIP. - * \author - * Adam Dunkels - */ - -#ifndef UIP_UDP_PACKET_H_ -#define UIP_UDP_PACKET_H_ - -#include - -#include "contiki/ip/uip.h" - -/* Return value: 0 - packet could not be sent, the net_buf is released by API - * 1 - packet sent, caller needs to de-allocate the buf - */ -uint8_t uip_udp_packet_send(struct net_buf *buf, struct uip_udp_conn *c, const void *data, int len); -uint8_t uip_udp_packet_sendto(struct net_buf *buf, struct uip_udp_conn *c, const void *data, int len, - const uip_ipaddr_t *toaddr, uint16_t toport); - -#endif /* UIP_UDP_PACKET_H_ */ diff --git a/net/ip/contiki/ip/uip.h b/net/ip/contiki/ip/uip.h deleted file mode 100644 index 707df6b8ace27646ba572d87ff0b0a1a109817e6..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/uip.h +++ /dev/null @@ -1,2236 +0,0 @@ -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack. - * - * - */ - -/** - * \addtogroup uip - * @{ - */ - -/** - * \file - * Header file for the uIP TCP/IP stack. - * \author Adam Dunkels - * \author Julien Abeille (IPv6 related code) - * \author Mathilde Durvy (IPv6 related code) - * - * The uIP TCP/IP stack header file contains definitions for a number - * of C macros that are used by uIP programs as well as internal uIP - * structures, TCP/IP header structures and function declarations. - * - */ - -#include -#include - -#ifndef UIP_H_ -#define UIP_H_ - -struct net_buf; - -#include "contiki/ip/uipopt.h" -#include "contiki/ip/uipaddr.h" -#include "contiki/ip/tcpip.h" - -/* Header sizes. */ -#if NETSTACK_CONF_WITH_IPV6 -#define UIP_IPH_LEN 40 -#define UIP_FRAGH_LEN 8 -#else /* NETSTACK_CONF_WITH_IPV6 */ -#define UIP_IPH_LEN 20 /* Size of IP header */ -#endif /* NETSTACK_CONF_WITH_IPV6 */ - -#define UIP_UDPH_LEN 8 /* Size of UDP header */ -#define UIP_TCPH_LEN 20 /* Size of TCP header */ -#define UIP_ICMPH_LEN 4 /* Size of ICMP header */ - -#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN) /* Size of IP + - * UDP - * header */ -#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Size of IP + - * TCP - * header */ -#define UIP_TCPIP_HLEN UIP_IPTCPH_LEN -#define UIP_IPICMPH_LEN (UIP_IPH_LEN + UIP_ICMPH_LEN) /* size of ICMP - + IP header */ -#define UIP_LLIPH_LEN (UIP_LLH_LEN + UIP_IPH_LEN) /* size of L2 - + IP header */ -#if NETSTACK_CONF_WITH_IPV6 -/** - * The sums below are quite used in ND. When used for uip_buf, we - * include link layer length when used for uip_len, we do not, hence - * we need values with and without LLH_LEN we do not use capital - * letters as these values are variable - */ -#define uip_l2_l3_hdr_len(buf) (UIP_LLH_LEN + UIP_IPH_LEN + uip_ext_len(buf)) -#define uip_l2_l3_icmp_hdr_len(buf) (UIP_LLH_LEN + UIP_IPH_LEN + uip_ext_len(buf) + UIP_ICMPH_LEN) -#define uip_l3_hdr_len(buf) (UIP_IPH_LEN + uip_ext_len(buf)) -#define uip_l3_icmp_hdr_len(buf) (UIP_IPH_LEN + uip_ext_len(buf) + UIP_ICMPH_LEN) -#endif /*NETSTACK_CONF_WITH_IPV6*/ - - -/*---------------------------------------------------------------------------*/ -/* First, the functions that should be called from the - * system. Initialization, the periodic timer, and incoming packets are - * handled by the following three functions. - */ -/** - * \defgroup uipconffunc uIP configuration functions - * @{ - * - * The uIP configuration functions are used for setting run-time - * parameters in uIP such as IP addresses. - */ - -/** - * Set the IP address of this host. - * - * The IP address is represented as a 4-byte array where the first - * octet of the IP address is put in the first member of the 4-byte - * array. - * - * Example: - \code - - uip_ipaddr_t addr; - - uip_ipaddr(&addr, 192,168,1,2); - uip_sethostaddr(&addr); - - \endcode - * \param addr A pointer to an IP address of type uip_ipaddr_t; - * - * \sa uip_ipaddr() - * - * \hideinitializer - */ -#define uip_sethostaddr(addr) uip_ipaddr_copy(&uip_hostaddr, (addr)) - -/** - * Get the IP address of this host. - * - * The IP address is represented as a 4-byte array where the first - * octet of the IP address is put in the first member of the 4-byte - * array. - * - * Example: - \code - uip_ipaddr_t hostaddr; - - uip_gethostaddr(&hostaddr); - \endcode - * \param addr A pointer to a uip_ipaddr_t variable that will be - * filled in with the currently configured IP address. - * - * \hideinitializer - */ -#define uip_gethostaddr(addr) uip_ipaddr_copy((addr), &uip_hostaddr) - -/** - * Set the default router's IP address. - * - * \param addr A pointer to a uip_ipaddr_t variable containing the IP - * address of the default router. - * - * \sa uip_ipaddr() - * - * \hideinitializer - */ -#define uip_setdraddr(addr) uip_ipaddr_copy(&uip_draddr, (addr)) - -/** - * Set the netmask. - * - * \param addr A pointer to a uip_ipaddr_t variable containing the IP - * address of the netmask. - * - * \sa uip_ipaddr() - * - * \hideinitializer - */ -#define uip_setnetmask(addr) uip_ipaddr_copy(&uip_netmask, (addr)) - - -/** - * Get the default router's IP address. - * - * \param addr A pointer to a uip_ipaddr_t variable that will be - * filled in with the IP address of the default router. - * - * \hideinitializer - */ -#define uip_getdraddr(addr) uip_ipaddr_copy((addr), &uip_draddr) - -/** - * Get the netmask. - * - * \param addr A pointer to a uip_ipaddr_t variable that will be - * filled in with the value of the netmask. - * - * \hideinitializer - */ -#define uip_getnetmask(addr) uip_ipaddr_copy((addr), &uip_netmask) - -/** @} */ - -/** - * \defgroup uipinit uIP initialization functions - * @{ - * - * The uIP initialization functions are used for booting uIP. - */ - -/** - * uIP initialization function. - * - * This function should be called at boot up to initilize the uIP - * TCP/IP stack. - */ -void uip_init(void); - -/** - * uIP initialization function. - * - * This function may be used at boot time to set the initial ip_id. - */ -void uip_setipid(uint16_t id); - -/** @} */ - -/** - * \defgroup uipdevfunc uIP device driver functions - * @{ - * - * These functions are used by a network device driver for interacting - * with uIP. - */ - -/** - * Process an incoming packet. - * - * This function should be called when the device driver has received - * a packet from the network. The packet from the device driver must - * be present in the uip_buf buffer, and the length of the packet - * should be placed in the uip_len variable. - * - * When the function returns, there may be an outbound packet placed - * in the uip_buf packet buffer. If so, the uip_len variable is set to - * the length of the packet. If no packet is to be sent out, the - * uip_len variable is set to 0. - * - * The usual way of calling the function is presented by the source - * code below. - \code - uip_len = devicedriver_poll(); - if(uip_len > 0) { - uip_input(); - if(uip_len > 0) { - devicedriver_send(); - } - } - \endcode - * - * \note If you are writing a uIP device driver that needs ARP - * (Address Resolution Protocol), e.g., when running uIP over - * Ethernet, you will need to call the uIP ARP code before calling - * this function: - \code - #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) - uip_len = ethernet_devicedrver_poll(); - if(uip_len > 0) { - if(BUF->type == UIP_HTONS(UIP_ETHTYPE_IP)) { - uip_arp_ipin(); - uip_input(); - if(uip_len > 0) { - uip_arp_out(); - ethernet_devicedriver_send(); - } - } else if(BUF->type == UIP_HTONS(UIP_ETHTYPE_ARP)) { - uip_arp_arpin(); - if(uip_len > 0) { - ethernet_devicedriver_send(); - } - } - \endcode - * - * \hideinitializer - */ -#define uip_input(buf) uip_process(&buf, UIP_DATA) - -/** - * Periodic processing for a connection identified by its number. - * - * This function does the necessary periodic processing (timers, - * polling) for a uIP TCP connection, and should be called when the - * periodic uIP timer goes off. It should be called for every - * connection, regardless of whether they are open of closed. - * - * When the function returns, it may have an outbound packet waiting - * for service in the uIP packet buffer, and if so the uip_len - * variable is set to a value larger than zero. The device driver - * should be called to send out the packet. - * - * The usual way of calling the function is through a for() loop like - * this: - \code - for(i = 0; i < UIP_CONNS; ++i) { - uip_periodic(i); - if(uip_len > 0) { - devicedriver_send(); - } - } - \endcode - * - * \note If you are writing a uIP device driver that needs ARP - * (Address Resolution Protocol), e.g., when running uIP over - * Ethernet, you will need to call the uip_arp_out() function before - * calling the device driver: - \code - for(i = 0; i < UIP_CONNS; ++i) { - uip_periodic(i); - if(uip_len > 0) { - uip_arp_out(); - ethernet_devicedriver_send(); - } - } - \endcode - * - * \param conn The number of the connection which is to be periodically polled. - * - * \hideinitializer - */ -#if UIP_TCP -#define uip_periodic(buf, conn) do { uip_set_conn(buf) = &uip_conns[conn]; \ - uip_process(&buf, UIP_TIMER); } while (0) - -/** - * Macro to determine whether a specific uIP connection is active - * - * \param conn The connection's number - * \retval 0 Connection closed - */ -#define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED) - -/** - * Perform periodic processing for a connection identified by a pointer - * to its structure. - * - * Same as uip_periodic() but takes a pointer to the actual uip_conn - * struct instead of an integer as its argument. This function can be - * used to force periodic processing of a specific connection. - * - * \param conn A pointer to the uip_conn struct for the connection to - * be processed. - * - * \hideinitializer - */ -#define uip_periodic_conn(buf, conn) do { uip_set_conn(buf) = conn; \ - uip_process(&buf, UIP_TIMER); } while (0) - -/** - * Request that a particular connection should be polled. - * - * Similar to uip_periodic_conn() but does not perform any timer - * processing. The application is polled for new data. - * - * \param conn A pointer to the uip_conn struct for the connection to - * be processed. - * - * \hideinitializer - */ -#define uip_poll_conn(buf, conn) do { uip_set_conn(buf) = conn; \ - uip_process(&buf, UIP_POLL_REQUEST); } while (0) - -#endif /* UIP_TCP */ - -#if UIP_UDP -/** - * Periodic processing for a UDP connection identified by its number. - * - * This function is essentially the same as uip_periodic(), but for - * UDP connections. It is called in a similar fashion as the - * uip_periodic() function: - \code - for(i = 0; i < UIP_UDP_CONNS; i++) { - uip_udp_periodic(i); - if(uip_len > 0) { - devicedriver_send(); - } - } - \endcode - * - * \note As for the uip_periodic() function, special care has to be - * taken when using uIP together with ARP and Ethernet: - \code - for(i = 0; i < UIP_UDP_CONNS; i++) { - uip_udp_periodic(i); - if(uip_len > 0) { - uip_arp_out(); - ethernet_devicedriver_send(); - } - } - \endcode - * - * \param conn The number of the UDP connection to be processed. - * - * \hideinitializer - */ -#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \ - uip_process(UIP_UDP_TIMER); } while(0) - -/** - * Periodic processing for a UDP connection identified by a pointer to - * its structure. - * - * Same as uip_udp_periodic() but takes a pointer to the actual - * uip_conn struct instead of an integer as its argument. This - * function can be used to force periodic processing of a specific - * connection. - * - * \param conn A pointer to the uip_udp_conn struct for the connection - * to be processed. - * - * \hideinitializer - */ -#define uip_udp_periodic_conn(buf, conn) do { uip_set_udp_conn(buf) = conn; \ - uip_process(&buf, UIP_UDP_TIMER); } while(0) -#endif /* UIP_UDP */ - -/** \brief Abandon the reassembly of the current packet */ -void uip_reass_over(void); - -/** - * The uIP packet buffer. - * - * The uip_aligned_buf array is used to hold incoming and outgoing - * packets. The device driver should place incoming data into this - * buffer. When sending data, the device driver should read the link - * level headers and the TCP/IP headers from this buffer. The size of - * the link level headers is configured by the UIP_LLH_LEN define. - * - * \note The application data need not be placed in this buffer, so - * the device driver must read it from the place pointed to by the - * uip_appdata pointer as illustrated by the following example: - \code - void - devicedriver_send(void) - { - hwsend(&uip_buf[0], UIP_LLH_LEN); - if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) { - hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN); - } else { - hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN); - hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN); - } - } - \endcode - */ - -typedef union { - uint32_t u32[(UIP_BUFSIZE + 3) / 4]; - uint8_t u8[UIP_BUFSIZE]; -} uip_buf_t; - -#if 0 -/* Moved to net_buf */ -CCIF extern uip_buf_t uip_aligned_buf; - -/** Macro to access uip_aligned_buf as an array of bytes */ -#define uip_buf (uip_aligned_buf.u8) -#endif - -/** @} */ - -/*---------------------------------------------------------------------------*/ -/* Functions that are used by the uIP application program. Opening and - * closing connections, sending and receiving data, etc. is all - * handled by the functions below. - */ -/** - * \defgroup uipappfunc uIP application functions - * @{ - * - * Functions used by an application running on top of uIP. - */ - -/** - * Start listening to the specified port. - * - * \note Since this function expects the port number in network byte - * order, a conversion using UIP_HTONS() or uip_htons() is necessary. - * - \code - uip_listen(UIP_HTONS(80)); - \endcode - * - * \param port A 16-bit port number in network byte order. - */ -void uip_listen(uint16_t port); - -/** - * Stop listening to the specified port. - * - * \note Since this function expects the port number in network byte - * order, a conversion using UIP_HTONS() or uip_htons() is necessary. - * - \code - uip_unlisten(UIP_HTONS(80)); - \endcode - * - * \param port A 16-bit port number in network byte order. - */ -void uip_unlisten(uint16_t port); - -/** - * Connect to a remote host using TCP. - * - * This function is used to start a new connection to the specified - * port on the specified host. It allocates a new connection identifier, - * sets the connection to the SYN_SENT state and sets the - * retransmission timer to 0. This will cause a TCP SYN segment to be - * sent out the next time this connection is periodically processed, - * which usually is done within 0.5 seconds after the call to - * uip_connect(). - * - * \note This function is available only if support for active open - * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h. - * - * \note Since this function requires the port number to be in network - * byte order, a conversion using UIP_HTONS() or uip_htons() is necessary. - * - \code - uip_ipaddr_t ipaddr; - - uip_ipaddr(&ipaddr, 192,168,1,2); - uip_connect(&ipaddr, UIP_HTONS(80)); - \endcode - * - * \param ripaddr The IP address of the remote host. - * - * \param port A 16-bit port number in network byte order. - * - * \return A pointer to the uIP connection identifier for the new connection, - * or NULL if no connection could be allocated. - * - */ -struct uip_conn *uip_connect(const uip_ipaddr_t *ripaddr, uint16_t port); - - - -/** - * \internal - * - * Check if a connection has outstanding (i.e., unacknowledged) data. - * - * \param conn A pointer to the uip_conn structure for the connection. - * - * \hideinitializer - */ -#define uip_outstanding(conn) ((conn)->len) - -/** - * Send data on the current connection. - * - * This function is used to send out a single segment of TCP - * data. Only applications that have been invoked by uIP for event - * processing can send data. - * - * The amount of data that actually is sent out after a call to this - * function is determined by the maximum amount of data TCP allows. uIP - * will automatically crop the data so that only the appropriate - * amount of data is sent. The function uip_mss() can be used to query - * uIP for the amount of data that actually will be sent. - * - * \note This function does not guarantee that the sent data will - * arrive at the destination. If the data is lost in the network, the - * application will be invoked with the uip_rexmit() event being - * set. The application will then have to resend the data using this - * function. - * - * \param data A pointer to the data which is to be sent. - * - * \param len The maximum amount of data bytes to be sent. - * - * \hideinitializer - */ -#if UIP_TCP -CCIF void uip_send(struct net_buf *buf, const void *data, int len); -#endif - -#if UIP_UDP -CCIF void uip_send_udp(struct net_buf *buf, const void *data, int len); -#endif - -/** - * The length of any incoming data that is currently available (if available) - * in the uip_appdata buffer. - * - * The test function uip_data() must first be used to check if there - * is any data available at all. - * - * \hideinitializer - */ -#define uip_datalen(buf) uip_len(buf) - -/** - * The length of any out-of-band data (urgent data) that has arrived - * on the connection. - * - * \note The configuration parameter UIP_URGDATA must be set for this - * function to be enabled. - * - * \hideinitializer - */ -#define uip_urgdatalen() uip_urglen - -/** - * Close the current connection. - * - * This function will close the current connection in a nice way. - * - * \hideinitializer - */ -#define uip_close() (uip_flags = UIP_CLOSE) - -/** - * Abort the current connection. - * - * This function will abort (reset) the current connection, and is - * usually used when an error has occurred that prevents using the - * uip_close() function. - * - * \hideinitializer - */ -#define uip_abort() (uip_flags = UIP_ABORT) - -/** - * Tell the sending host to stop sending data. - * - * This function will close our receiver's window so that we stop - * receiving data for the current connection. - * - * \hideinitializer - */ -#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED) - -/** - * Find out if the current connection has been previously stopped with - * uip_stop(). - * - * \hideinitializer - */ -#define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED) - -/** - * Restart the current connection, if is has previously been stopped - * with uip_stop(). - * - * This function will open the receiver's window again so that we - * start receiving data for the current connection. - * - * \hideinitializer - */ -#define uip_restart(buf) do { uip_flags(buf) |= UIP_NEWDATA; \ - uip_conn->tcpstateflags &= ~UIP_STOPPED; \ - } while(0) - - -/* uIP tests that can be made to determine in what state the current - connection is, and what the application function should do. */ - -/** - * Is the current connection a UDP connection? - * - * This function checks whether the current connection is a UDP connection. - * - * \hideinitializer - * - */ -#define uip_udpconnection() (uip_conn == NULL) - -/** - * Is new incoming data available? - * - * Will reduce to non-zero if there is new data for the application - * present at the uip_appdata pointer. The size of the data is - * available through the uip_len variable. - * - * \hideinitializer - */ -#define uip_newdata(buf) (uip_flags(buf) & UIP_NEWDATA) - -/** - * Has previously sent data been acknowledged? - * - * Will reduce to non-zero if the previously sent data has been - * acknowledged by the remote host. This means that the application - * can send new data. - * - * \hideinitializer - */ -#define uip_acked(buf) (uip_flags(buf) & UIP_ACKDATA) - -/** - * Has the connection just been connected? - * - * Reduces to non-zero if the current connection has been connected to - * a remote host. This will happen both if the connection has been - * actively opened (with uip_connect()) or passively opened (with - * uip_listen()). - * - * \hideinitializer - */ -#define uip_connected(buf) (uip_flags(buf) & UIP_CONNECTED) - -/** - * Has the connection been closed by the other end? - * - * Is non-zero if the connection has been closed by the remote - * host. The application may then do the necessary clean-ups. - * - * \hideinitializer - */ -#define uip_closed(buf) (uip_flags(buf) & UIP_CLOSE) - -/** - * Has the connection been aborted by the other end? - * - * Non-zero if the current connection has been aborted (reset) by the - * remote host. - * - * \hideinitializer - */ -#define uip_aborted(buf) (uip_flags(buf) & UIP_ABORT) - -/** - * Has the connection timed out? - * - * Non-zero if the current connection has been aborted due to too many - * retransmissions. - * - * \hideinitializer - */ -#define uip_timedout(buf) (uip_flags(buf) & UIP_TIMEDOUT) - -/** - * Do we need to retransmit previously data? - * - * Reduces to non-zero if the previously sent data has been lost in - * the network, and the application should retransmit it. The - * application should send the exact same data as it did the last - * time, using the uip_send() function. - * - * \hideinitializer - */ -#define uip_rexmit(buf) (uip_flags(buf) & UIP_REXMIT) - -/** - * Is the connection being polled by uIP? - * - * Is non-zero if the reason the application is invoked is that the - * current connection has been idle for a while and should be - * polled. - * - * The polling event can be used for sending data without having to - * wait for the remote host to send data. - * - * \hideinitializer - */ -#define uip_poll(buf) (uip_flags(buf) & UIP_POLL) - -/** - * Get the initial maximum segment size (MSS) of the current - * connection. - * - * \hideinitializer - */ -#define uip_initialmss(buf) (uip_conn(buf)->initialmss) - -/** - * Get the current maximum segment size that can be sent on the current - * connection. - * - * The current maximum segment size that can be sent on the - * connection is computed from the receiver's window and the MSS of - * the connection (which also is available by calling - * uip_initialmss()). - * - * \hideinitializer - */ -#define uip_mss(buf) (uip_conn(buf)->mss) - -/** - * Set up a new UDP connection. - * - * This function sets up a new UDP connection. The function will - * automatically allocate an unused local port for the new - * connection. However, another port can be chosen by using the - * uip_udp_bind() call, after the uip_udp_new() function has been - * called. - * - * Example: - \code - uip_ipaddr_t addr; - struct uip_udp_conn *c; - - uip_ipaddr(&addr, 192,168,2,1); - c = uip_udp_new(&addr, UIP_HTONS(12345)); - if(c != NULL) { - uip_udp_bind(c, UIP_HTONS(12344)); - } - \endcode - * \param ripaddr The IP address of the remote host. - * - * \param rport The remote port number in network byte order. - * - * \return The uip_udp_conn structure for the new connection, or NULL - * if no connection could be allocated. - */ -struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport); - -/** - * Remove a UDP connection. - * - * \param conn A pointer to the uip_udp_conn structure for the connection. - * - * \hideinitializer - */ -#define uip_udp_remove(conn) (conn)->lport = 0 - -/** - * Bind a UDP connection to a local port. - * - * \param conn A pointer to the uip_udp_conn structure for the - * connection. - * - * \param port The local port number, in network byte order. - * - * \hideinitializer - */ -#define uip_udp_bind(conn, port) (conn)->lport = port - -/** - * Send a UDP datagram of length len on the current connection. - * - * This function can only be called in response to a UDP event (poll - * or newdata). The data must be present in the uip_buf buffer, at the - * place pointed to by the uip_appdata pointer. - * - * \param len The length of the data in the uip_buf buffer. - * - * \hideinitializer - */ -#define uip_udp_send(buf, len) uip_send((char *)uip_appdata(buf), len) - -/** @} */ - -/* uIP convenience and converting functions. */ - -/** - * \defgroup uipconvfunc uIP conversion functions - * @{ - * - * These functions can be used for converting between different data - * formats used by uIP. - */ - -/** - * Convert an IP address to four bytes separated by commas. - * - * Example: - \code - uip_ipaddr_t ipaddr; - printf("ipaddr=%d.%d.%d.%d\n", uip_ipaddr_to_quad(&ipaddr)); - \endcode - * - * \param a A pointer to a uip_ipaddr_t. - * \hideinitializer - */ -#define uip_ipaddr_to_quad(a) (a)->u8[0],(a)->u8[1],(a)->u8[2],(a)->u8[3] - -/** - * Construct an IP address from four bytes. - * - * This function constructs an IP address of the type that uIP handles - * internally from four bytes. The function is handy for specifying IP - * addresses to use with e.g. the uip_connect() function. - * - * Example: - \code - uip_ipaddr_t ipaddr; - struct uip_conn *c; - - uip_ipaddr(&ipaddr, 192,168,1,2); - c = uip_connect(&ipaddr, UIP_HTONS(80)); - \endcode - * - * \param addr A pointer to a uip_ipaddr_t variable that will be - * filled in with the IP address. - * - * \param addr0 The first octet of the IP address. - * \param addr1 The second octet of the IP address. - * \param addr2 The third octet of the IP address. - * \param addr3 The forth octet of the IP address. - * - * \hideinitializer - */ -#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \ - (addr)->u8[0] = addr0; \ - (addr)->u8[1] = addr1; \ - (addr)->u8[2] = addr2; \ - (addr)->u8[3] = addr3; \ - } while(0) - -/** - * Construct an IPv6 address from eight 16-bit words. - * - * This function constructs an IPv6 address. - * - * \hideinitializer - */ -#define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) do { \ - (addr)->u16[0] = UIP_HTONS(addr0); \ - (addr)->u16[1] = UIP_HTONS(addr1); \ - (addr)->u16[2] = UIP_HTONS(addr2); \ - (addr)->u16[3] = UIP_HTONS(addr3); \ - (addr)->u16[4] = UIP_HTONS(addr4); \ - (addr)->u16[5] = UIP_HTONS(addr5); \ - (addr)->u16[6] = UIP_HTONS(addr6); \ - (addr)->u16[7] = UIP_HTONS(addr7); \ - } while(0) - -/** - * Construct an IPv6 address from sixteen 8-bit words. - * - * This function constructs an IPv6 address. - * - * \hideinitializer - */ -#define uip_ip6addr_u8(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7,addr8,addr9,addr10,addr11,addr12,addr13,addr14,addr15) do { \ - (addr)->u8[0] = addr0; \ - (addr)->u8[1] = addr1; \ - (addr)->u8[2] = addr2; \ - (addr)->u8[3] = addr3; \ - (addr)->u8[4] = addr4; \ - (addr)->u8[5] = addr5; \ - (addr)->u8[6] = addr6; \ - (addr)->u8[7] = addr7; \ - (addr)->u8[8] = addr8; \ - (addr)->u8[9] = addr9; \ - (addr)->u8[10] = addr10; \ - (addr)->u8[11] = addr11; \ - (addr)->u8[12] = addr12; \ - (addr)->u8[13] = addr13; \ - (addr)->u8[14] = addr14; \ - (addr)->u8[15] = addr15; \ - } while(0) - - -/** - * Copy an IP address from one place to another. - * - * Copies an IP address from one place to another. - * - * Example: - \code - uip_ipaddr_t ipaddr1, ipaddr2; - - uip_ipaddr(&ipaddr1, 192,16,1,2); - uip_ipaddr_copy(&ipaddr2, &ipaddr1); - \endcode - * - * \param dest The destination for the copy. - * \param src The source from where to copy. - * - * \hideinitializer - */ -#ifndef uip_ipaddr_copy -#define uip_ipaddr_copy(dest, src) (*(dest) = *(src)) -#endif -#ifndef uip_ip4addr_copy -#define uip_ip4addr_copy(dest, src) (*((uip_ip4addr_t *)dest) = *((uip_ip4addr_t *)src)) -#endif -#ifndef uip_ip6addr_copy -#define uip_ip6addr_copy(dest, src) (*((uip_ip6addr_t *)dest) = *((uip_ip6addr_t *)src)) -#endif - -/** - * Compare two IP addresses - * - * Compares two IP addresses. - * - * Example: - \code - uip_ipaddr_t ipaddr1, ipaddr2; - - uip_ipaddr(&ipaddr1, 192,16,1,2); - if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) { - printf("They are the same"); - } - \endcode - * - * \param addr1 The first IP address. - * \param addr2 The second IP address. - * - * \hideinitializer - */ -#define uip_ip4addr_cmp(addr1, addr2) ((addr1)->u16[0] == (addr2)->u16[0] && \ - (addr1)->u16[1] == (addr2)->u16[1]) -#define uip_ip6addr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0) - -#if NETSTACK_CONF_WITH_IPV6 -#define uip_ipaddr_cmp(addr1, addr2) uip_ip6addr_cmp(addr1, addr2) -#else /* NETSTACK_CONF_WITH_IPV6 */ -#define uip_ipaddr_cmp(addr1, addr2) uip_ip4addr_cmp(addr1, addr2) -#endif /* NETSTACK_CONF_WITH_IPV6 */ - -/** - * Compare two IP addresses with netmasks - * - * Compares two IP addresses with netmasks. The masks are used to mask - * out the bits that are to be compared. - * - * Example: - \code - uip_ipaddr_t ipaddr1, ipaddr2, mask; - - uip_ipaddr(&mask, 255,255,255,0); - uip_ipaddr(&ipaddr1, 192,16,1,2); - uip_ipaddr(&ipaddr2, 192,16,1,3); - if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) { - printf("They are the same"); - } - \endcode - * - * \param addr1 The first IP address. - * \param addr2 The second IP address. - * \param mask The netmask. - * - * \hideinitializer - */ - -#define uip_ipaddr_maskcmp(addr1, addr2, mask) \ - (((((uint16_t *)addr1)[0] & ((uint16_t *)mask)[0]) == \ - (((uint16_t *)addr2)[0] & ((uint16_t *)mask)[0])) && \ - ((((uint16_t *)addr1)[1] & ((uint16_t *)mask)[1]) == \ - (((uint16_t *)addr2)[1] & ((uint16_t *)mask)[1]))) - -#define uip_ipaddr_prefixcmp(addr1, addr2, length) \ - uip_ipaddr_prefixcmp2((uint8_t *)(addr1), (uint8_t *)(addr2), length) - -static inline bool uip_ipaddr_prefixcmp2(uint8_t *addr1, - uint8_t *addr2, - uint8_t length) -{ - uint8_t bits = 128 - length; - uint8_t bytes = bits / 8; - uint8_t remain = bits % 8; - - if (length > 128) { - return false; - } - - if (memcmp(addr1, addr2, 16 - bytes)) { - return false; - } - - return ((addr1[16 - bytes] & ((8 - remain) << 8)) - == - (addr2[16 - bytes] & ((8 - remain) << 8))); -} - -/* - * Check if an address is a broadcast address for a network. - * - * Checks if an address is the broadcast address for a network. The - * network is defined by an IP address that is on the network and the - * network's netmask. - * - * \param addr The IP address. - * \param netaddr The network's IP address. - * \param netmask The network's netmask. - * - * \hideinitializer - */ -/*#define uip_ipaddr_isbroadcast(addr, netaddr, netmask) - ((uip_ipaddr_t *)(addr)).u16 & ((uip_ipaddr_t *)(addr)).u16*/ - - - -/** - * Mask out the network part of an IP address. - * - * Masks out the network part of an IP address, given the address and - * the netmask. - * - * Example: - \code - uip_ipaddr_t ipaddr1, ipaddr2, netmask; - - uip_ipaddr(&ipaddr1, 192,16,1,2); - uip_ipaddr(&netmask, 255,255,255,0); - uip_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask); - \endcode - * - * In the example above, the variable "ipaddr2" will contain the IP - * address 192.168.1.0. - * - * \param dest Where the result is to be placed. - * \param src The IP address. - * \param mask The netmask. - * - * \hideinitializer - */ -#define uip_ipaddr_mask(dest, src, mask) do { \ - ((uint16_t *)dest)[0] = ((uint16_t *)src)[0] & ((uint16_t *)mask)[0]; \ - ((uint16_t *)dest)[1] = ((uint16_t *)src)[1] & ((uint16_t *)mask)[1]; \ - } while(0) - -/** - * Pick the first octet of an IP address. - * - * Picks out the first octet of an IP address. - * - * Example: - \code - uip_ipaddr_t ipaddr; - uint8_t octet; - - uip_ipaddr(&ipaddr, 1,2,3,4); - octet = uip_ipaddr1(&ipaddr); - \endcode - * - * In the example above, the variable "octet" will contain the value 1. - * - * \hideinitializer - */ -#define uip_ipaddr1(addr) ((addr)->u8[0]) - -/** - * Pick the second octet of an IP address. - * - * Picks out the second octet of an IP address. - * - * Example: - \code - uip_ipaddr_t ipaddr; - uint8_t octet; - - uip_ipaddr(&ipaddr, 1,2,3,4); - octet = uip_ipaddr2(&ipaddr); - \endcode - * - * In the example above, the variable "octet" will contain the value 2. - * - * \hideinitializer - */ -#define uip_ipaddr2(addr) ((addr)->u8[1]) - -/** - * Pick the third octet of an IP address. - * - * Picks out the third octet of an IP address. - * - * Example: - \code - uip_ipaddr_t ipaddr; - uint8_t octet; - - uip_ipaddr(&ipaddr, 1,2,3,4); - octet = uip_ipaddr3(&ipaddr); - \endcode - * - * In the example above, the variable "octet" will contain the value 3. - * - * \hideinitializer - */ -#define uip_ipaddr3(addr) ((addr)->u8[2]) - -/** - * Pick the fourth octet of an IP address. - * - * Picks out the fourth octet of an IP address. - * - * Example: - \code - uip_ipaddr_t ipaddr; - uint8_t octet; - - uip_ipaddr(&ipaddr, 1,2,3,4); - octet = uip_ipaddr4(&ipaddr); - \endcode - * - * In the example above, the variable "octet" will contain the value 4. - * - * \hideinitializer - */ -#define uip_ipaddr4(addr) ((addr)->u8[3]) - -/** - * Convert 16-bit quantity from host byte order to network byte order. - * - * This macro is primarily used for converting constants from host - * byte order to network byte order. For converting variables to - * network byte order, use the uip_htons() function instead. - * - * \hideinitializer - */ -#ifndef UIP_HTONS -# if UIP_BYTE_ORDER == UIP_BIG_ENDIAN -# define UIP_HTONS(n) (n) -# define UIP_HTONL(n) (n) -# else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ -# define UIP_HTONS(n) (uint16_t)((((uint16_t) (n)) << 8) | (((uint16_t) (n)) >> 8)) -# define UIP_HTONL(n) (((uint32_t)UIP_HTONS(n) << 16) | UIP_HTONS((uint32_t)(n) >> 16)) -# endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ -#else -#error "UIP_HTONS already defined!" -#endif /* UIP_HTONS */ - -/** - * Convert a 16-bit quantity from host byte order to network byte order. - * - * This function is primarily used for converting variables from host - * byte order to network byte order. For converting constants to - * network byte order, use the UIP_HTONS() macro instead. - */ -#ifndef uip_htons -CCIF uint16_t uip_htons(uint16_t val); -#endif /* uip_htons */ -#ifndef uip_ntohs -#define uip_ntohs uip_htons -#endif - -#ifndef uip_htonl -CCIF uint32_t uip_htonl(uint32_t val); -#endif /* uip_htonl */ -#ifndef uip_ntohl -#define uip_ntohl uip_htonl -#endif - -/** @} */ - -/** - * Pointer to the application data in the packet buffer. - * - * This pointer points to the application data when the application is - * called. If the application wishes to send data, the application may - * use this space to write the data into before calling uip_send(). - */ -#if 0 -/* part of net_buf */ -CCIF extern void *uip_appdata; -#endif - -#if UIP_URGDATA > 0 -/* uint8_t *uip_urgdata: - * - * This pointer points to any urgent data that has been received. Only - * present if compiled with support for urgent data (UIP_URGDATA). - */ -extern void *uip_urgdata; -#endif /* UIP_URGDATA > 0 */ - - -/** - * \defgroup uipdrivervars Variables used in uIP device drivers - * @{ - * - * uIP has a few global variables that are used in device drivers for - * uIP. - */ - -/** - * The length of the packet in the uip_buf buffer. - * - * The global variable uip_len holds the length of the packet in the - * uip_buf buffer. - * - * When the network device driver calls the uIP input function, - * uip_len should be set to the length of the packet in the uip_buf - * buffer. - * - * When sending packets, the device driver should use the contents of - * the uip_len variable to determine the length of the outgoing - * packet. - * - */ -#if 0 -/* No longer used as len is part of net_buf */ -CCIF extern uint16_t uip_len; -#endif - -/** - * The length of the extension headers - */ -#if 0 -/* No longer used as len is part of net_buf */ -extern uint8_t uip_ext_len; -#endif -/** @} */ - -#if UIP_URGDATA > 0 -extern uint16_t uip_urglen, uip_surglen; -#endif /* UIP_URGDATA > 0 */ - -/** - * Representation of a uIP TCP connection. - * - * The uip_conn structure is used for identifying a connection. All - * but one field in the structure are to be considered read-only by an - * application. The only exception is the appstate field whose purpose - * is to let the application store application-specific state (e.g., - * file pointers) for the connection. The type of this field is - * configured in the "uipopt.h" header file. - */ -struct uip_conn { - uip_ipaddr_t ripaddr; /**< The IP address of the remote host. */ - - uint16_t lport; /**< The local TCP port, in network byte order. */ - uint16_t rport; /**< The local remote TCP port, in network byte - order. */ - - uint8_t rcv_nxt[4]; /**< The sequence number that we expect to - receive next. */ - uint8_t snd_nxt[4]; /**< The sequence number that was last sent by - us. */ - uint16_t len; /**< Length of the data that was previously sent. */ - uint16_t mss; /**< Current maximum segment size for the - connection. */ - uint16_t initialmss; /**< Initial maximum segment size for the - connection. */ - uint8_t sa; /**< Retransmission time-out calculation state - variable. */ - uint8_t sv; /**< Retransmission time-out calculation state - variable. */ - uint8_t rto; /**< Retransmission time-out. */ - uint8_t tcpstateflags; /**< TCP state and flags. */ - uint8_t timer; /**< The retransmission timer. */ - uint8_t nrtx; /**< The number of retransmissions for the last - segment sent. */ - - /** The application state. */ - uip_tcp_appstate_t appstate; - - /* buffer holding the data to this connection */ - struct net_buf *buf; - -#if UIP_ACTIVE_OPEN - /* re-send SYN in active open connection */ - struct ctimer retransmit_timer; -#endif -}; - - -/** - * Pointer to the current TCP connection. - * - * The uip_conn pointer can be used to access the current TCP - * connection. - */ -#if 0 -/* Moved to net_buf */ -CCIF extern struct uip_conn *uip_conn; -#endif -#if UIP_TCP -/* The array containing all uIP connections. */ -CCIF extern struct uip_conn uip_conns[UIP_CONNS]; -#endif - -/** - * \addtogroup uiparch - * @{ - */ - -/** - * 4-byte array used for the 32-bit sequence number calculations. - */ -extern uint8_t uip_acc32[4]; -/** @} */ - -/** - * Representation of a uIP UDP connection. - */ -struct uip_udp_conn { - uip_ipaddr_t ripaddr; /**< The IP address of the remote peer. */ - uint16_t lport; /**< The local port number in network byte order. */ - uint16_t rport; /**< The remote port number in network byte order. */ - uint8_t ttl; /**< Default time-to-live. */ - - /** The application state. */ - uip_udp_appstate_t appstate; - - /* buffer holding the data to this connection */ - struct net_buf *buf; -}; - -/** - * The current UDP connection. - */ -#if 0 -/* Moved to net_buf */ -extern struct uip_udp_conn *uip_udp_conn; -#endif -extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; - -struct uip_fallback_interface { - void (*init)(void); - void (*output)(void); -}; - -#if UIP_CONF_ICMP6 -struct uip_icmp6_conn { - uip_icmp6_appstate_t appstate; - - /* buffer holding the data to this connection */ - struct net_buf *buf; -}; -extern struct uip_icmp6_conn uip_icmp6_conns; -#endif /*UIP_CONF_ICMP6*/ - -/** - * The uIP TCP/IP statistics. - * - * This is the variable in which the uIP TCP/IP statistics are gathered. - */ -#if UIP_STATISTICS == 1 -extern struct uip_stats uip_stat; -#define UIP_STAT(s) s -#else -#define UIP_STAT(s) -#endif /* UIP_STATISTICS == 1 */ - -/** - * The structure holding the TCP/IP statistics that are gathered if - * UIP_STATISTICS is set to 1. - * - */ -struct uip_stats { - struct { - uip_stats_t recv; /**< Number of received packets at the IP - layer. */ - uip_stats_t sent; /**< Number of sent packets at the IP - layer. */ - uip_stats_t forwarded;/**< Number of forwarded packets at the IP - layer. */ - uip_stats_t drop; /**< Number of dropped packets at the IP - layer. */ - uip_stats_t vhlerr; /**< Number of packets dropped due to wrong - IP version or header length. */ - uip_stats_t hblenerr; /**< Number of packets dropped due to wrong - IP length, high byte. */ - uip_stats_t lblenerr; /**< Number of packets dropped due to wrong - IP length, low byte. */ - uip_stats_t fragerr; /**< Number of packets dropped because they - were IP fragments. */ - uip_stats_t chkerr; /**< Number of packets dropped due to IP - checksum errors. */ - uip_stats_t protoerr; /**< Number of packets dropped because they - were neither ICMP, UDP nor TCP. */ - } ip; /**< IP statistics. */ - struct { - uip_stats_t recv; /**< Number of received ICMP packets. */ - uip_stats_t sent; /**< Number of sent ICMP packets. */ - uip_stats_t drop; /**< Number of dropped ICMP packets. */ - uip_stats_t typeerr; /**< Number of ICMP packets with a wrong - type. */ - uip_stats_t chkerr; /**< Number of ICMP packets with a bad - checksum. */ - } icmp; /**< ICMP statistics. */ -#if UIP_TCP - struct { - uip_stats_t recv; /**< Number of recived TCP segments. */ - uip_stats_t sent; /**< Number of sent TCP segments. */ - uip_stats_t drop; /**< Number of dropped TCP segments. */ - uip_stats_t chkerr; /**< Number of TCP segments with a bad - checksum. */ - uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK - number. */ - uip_stats_t rst; /**< Number of received TCP RST (reset) segments. */ - uip_stats_t rexmit; /**< Number of retransmitted TCP segments. */ - uip_stats_t syndrop; /**< Number of dropped SYNs because too few - connections were available. */ - uip_stats_t synrst; /**< Number of SYNs for closed ports, - triggering a RST. */ - } tcp; /**< TCP statistics. */ -#endif -#if UIP_UDP - struct { - uip_stats_t drop; /**< Number of dropped UDP segments. */ - uip_stats_t recv; /**< Number of recived UDP segments. */ - uip_stats_t sent; /**< Number of sent UDP segments. */ - uip_stats_t chkerr; /**< Number of UDP segments with a bad - checksum. */ - } udp; /**< UDP statistics. */ -#endif /* UIP_UDP */ -#if NETSTACK_CONF_WITH_IPV6 - struct { - uip_stats_t drop; /**< Number of dropped ND6 packets. */ - uip_stats_t recv; /**< Number of recived ND6 packets */ - uip_stats_t sent; /**< Number of sent ND6 packets */ - } nd6; -#endif /*NETSTACK_CONF_WITH_IPV6*/ -}; - - -/*---------------------------------------------------------------------------*/ -/* All the stuff below this point is internal to uIP and should not be - * used directly by an application or by a device driver. - */ -/*---------------------------------------------------------------------------*/ - - - -/* uint8_t uip_flags: - * - * When the application is called, uip_flags will contain the flags - * that are defined in this file. Please read below for more - * information. - */ -#if 0 -/* Moved to net_buf */ -CCIF extern uint8_t uip_flags; -#endif - -/* The following flags may be set in the global variable uip_flags - before calling the application callback. The UIP_ACKDATA, - UIP_NEWDATA, and UIP_CLOSE flags may both be set at the same time, - whereas the others are mutually exclusive. Note that these flags - should *NOT* be accessed directly, but only through the uIP - functions/macros. */ - -#define UIP_ACKDATA 1 /* Signifies that the outstanding data was - acked and the application should send - out new data instead of retransmitting - the last data. */ -#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent - us new data. */ -#define UIP_REXMIT 4 /* Tells the application to retransmit the - data that was last sent. */ -#define UIP_POLL 8 /* Used for polling the application, to - check if the application has data that - it wants to send. */ -#define UIP_CLOSE 16 /* The remote host has closed the - connection, thus the connection has - gone away. Or the application signals - that it wants to close the - connection. */ -#define UIP_ABORT 32 /* The remote host has aborted the - connection, thus the connection has - gone away. Or the application signals - that it wants to abort the - connection. */ -#define UIP_CONNECTED 64 /* We have got a connection from a remote - host and have set up a new connection - for it, or an active connection has - been successfully established. */ - -#define UIP_TIMEDOUT 128 /* The connection has been aborted due to - too many retransmissions. */ - - -/** - * \brief process the options within a hop by hop or destination option header - * \retval 0: nothing to send, - * \retval 1: drop pkt - * \retval 2: ICMP error message to send - */ -/*static uint8_t -uip_ext_hdr_options_process(); */ - -/* uip_process(flag): - * - * The actual uIP function which does all the work. - */ -uint8_t uip_process(struct net_buf **buf, uint8_t flag); - - /* The following flags are passed as an argument to the uip_process() - function. They are used to distinguish between the two cases where - uip_process() is called. It can be called either because we have - incoming data that should be processed, or because the periodic - timer has fired. These values are never used directly, but only in - the macros defined in this file. */ - -#define UIP_DATA 1 /* Tells uIP that there is incoming - data in the uip_buf buffer. The - length of the data is stored in the - global variable uip_len. */ -#define UIP_TIMER 2 /* Tells uIP that the periodic timer - has fired. */ -#define UIP_POLL_REQUEST 3 /* Tells uIP that a connection should - be polled. */ -#define UIP_UDP_SEND_CONN 4 /* Tells uIP that a UDP datagram - should be constructed in the - uip_buf buffer. */ -#if UIP_UDP -#define UIP_UDP_TIMER 5 -#endif /* UIP_UDP */ - -#if UIP_TCP -#define UIP_TCP_SEND_CONN 6 /* Tells uIP that a TCP segment - should be constructed in the - uip_buf buffer. */ -#endif - -/* The TCP states used in the uip_conn->tcpstateflags. */ -#define UIP_CLOSED 0 -#define UIP_SYN_RCVD 1 -#define UIP_SYN_SENT 2 -#define UIP_ESTABLISHED 3 -#define UIP_FIN_WAIT_1 4 -#define UIP_FIN_WAIT_2 5 -#define UIP_CLOSING 6 -#define UIP_TIME_WAIT 7 -#define UIP_LAST_ACK 8 -#define UIP_TS_MASK 15 - -#define UIP_STOPPED 16 - -/* The TCP and IP headers. */ -struct uip_tcpip_hdr { -#if NETSTACK_CONF_WITH_IPV6 - /* IPv6 header. */ - uint8_t vtc, - tcflow; - uint16_t flow; - uint8_t len[2]; - uint8_t proto, ttl; - uip_ip6addr_t srcipaddr, destipaddr; -#else /* NETSTACK_CONF_WITH_IPV6 */ - /* IPv4 header. */ - uint8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; - uint16_t ipchksum; - uip_ipaddr_t srcipaddr, destipaddr; -#endif /* NETSTACK_CONF_WITH_IPV6 */ - - /* TCP header. */ - uint16_t srcport, - destport; - uint8_t seqno[4], - ackno[4], - tcpoffset, - flags, - wnd[2]; - uint16_t tcpchksum; - uint8_t urgp[2]; - uint8_t optdata[4]; -} PACK_ALIAS_STRUCT; - -/* The ICMP and IP headers. */ -struct uip_icmpip_hdr { -#if NETSTACK_CONF_WITH_IPV6 - /* IPv6 header. */ - uint8_t vtc, - tcf; - uint16_t flow; - uint8_t len[2]; - uint8_t proto, ttl; - uip_ip6addr_t srcipaddr, destipaddr; -#else /* NETSTACK_CONF_WITH_IPV6 */ - /* IPv4 header. */ - uint8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; - uint16_t ipchksum; - uip_ipaddr_t srcipaddr, destipaddr; -#endif /* NETSTACK_CONF_WITH_IPV6 */ - - /* ICMP header. */ - uint8_t type, icode; - uint16_t icmpchksum; -#if !NETSTACK_CONF_WITH_IPV6 - uint16_t id, seqno; - uint8_t payload[1]; -#endif /* !NETSTACK_CONF_WITH_IPV6 */ -} PACK_ALIAS_STRUCT; - - -/* The UDP and IP headers. */ -struct uip_udpip_hdr { -#if NETSTACK_CONF_WITH_IPV6 - /* IPv6 header. */ - uint8_t vtc, - tcf; - uint16_t flow; - uint8_t len[2]; - uint8_t proto, ttl; - uip_ip6addr_t srcipaddr, destipaddr; -#else /* NETSTACK_CONF_WITH_IPV6 */ - /* IP header. */ - uint8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; - uint16_t ipchksum; - uip_ipaddr_t srcipaddr, destipaddr; -#endif /* NETSTACK_CONF_WITH_IPV6 */ - - /* UDP header. */ - uint16_t srcport, - destport; - uint16_t udplen; - uint16_t udpchksum; -} PACK_ALIAS_STRUCT; - -/* - * In IPv6 the length of the L3 headers before the transport header is - * not fixed, due to the possibility to include extension option headers - * after the IP header. hence we split here L3 and L4 headers - */ -/* The IP header */ -struct uip_ip_hdr { -#if NETSTACK_CONF_WITH_IPV6 - /* IPV6 header */ - uint8_t vtc; - uint8_t tcflow; - uint16_t flow; - uint8_t len[2]; - uint8_t proto, ttl; - uip_ip6addr_t srcipaddr, destipaddr; -#else /* NETSTACK_CONF_WITH_IPV6 */ - /* IPV4 header */ - uint8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; - uint16_t ipchksum; - uip_ipaddr_t srcipaddr, destipaddr; -#endif /* NETSTACK_CONF_WITH_IPV6 */ -} PACK_ALIAS_STRUCT; - - -/* - * IPv6 extension option headers: we are able to process - * the 4 extension headers defined in RFC2460 (IPv6): - * - Hop by hop option header, destination option header: - * These two are not used by any core IPv6 protocol, hence - * we just read them and go to the next. They convey options, - * the options defined in RFC2460 are Pad1 and PadN, which do - * some padding, and that we do not need to read (the length - * field in the header is enough) - * - Routing header: this one is most notably used by MIPv6, - * which we do not implement, hence we just read it and go - * to the next - * - Fragmentation header: we read this header and are able to - * reassemble packets - * - * We do not offer any means to send packets with extension headers - * - * We do not implement Authentication and ESP headers, which are - * used in IPSec and defined in RFC4302,4303,4305,4385 - */ -/* common header part */ -typedef struct uip_ext_hdr { - uint8_t next; - uint8_t len; -} PACK_ALIAS_STRUCT uip_ext_hdr; - -/* Hop by Hop option header */ -typedef struct uip_hbho_hdr { - uint8_t next; - uint8_t len; -} PACK_ALIAS_STRUCT uip_hbho_hdr; - -/* destination option header */ -typedef struct uip_desto_hdr { - uint8_t next; - uint8_t len; -} uip_desto_hdr; - -/* We do not define structures for PAD1 and PADN options */ - -/* - * routing header - * the routing header as 4 common bytes, then routing header type - * specific data there are several types of routing header. Type 0 was - * deprecated as per RFC5095 most notable other type is 2, used in - * RFC3775 (MIPv6) here we do not implement MIPv6, so we just need to - * parse the 4 first bytes - */ -typedef struct uip_routing_hdr { - uint8_t next; - uint8_t len; - uint8_t routing_type; - uint8_t seg_left; -} PACK_ALIAS_STRUCT uip_routing_hdr; - -/* fragmentation header */ -typedef struct uip_frag_hdr { - uint8_t next; - uint8_t res; - uint16_t offsetresmore; - uint32_t id; -} uip_frag_hdr; - -/* - * an option within the destination or hop by hop option headers - * it contains type an length, which is true for all options but PAD1 - */ -typedef struct uip_ext_hdr_opt { - uint8_t type; - uint8_t len; -} PACK_ALIAS_STRUCT uip_ext_hdr_opt; - -/* PADN option */ -typedef struct uip_ext_hdr_opt_padn { - uint8_t opt_type; - uint8_t opt_len; -} PACK_ALIAS_STRUCT uip_ext_hdr_opt_padn; - -/* RPL option */ -typedef struct uip_ext_hdr_opt_rpl { - uint8_t opt_type; - uint8_t opt_len; - uint8_t flags; - uint8_t instance; - uint16_t senderrank; -} PACK_ALIAS_STRUCT uip_ext_hdr_opt_rpl; - -/* TCP header */ -struct uip_tcp_hdr { - uint16_t srcport; - uint16_t destport; - uint8_t seqno[4]; - uint8_t ackno[4]; - uint8_t tcpoffset; - uint8_t flags; - uint8_t wnd[2]; - uint16_t tcpchksum; - uint8_t urgp[2]; - uint8_t optdata[4]; -} PACK_ALIAS_STRUCT; - -/* The ICMP headers. */ -struct uip_icmp_hdr { - uint8_t type, icode; - uint16_t icmpchksum; -#if !NETSTACK_CONF_WITH_IPV6 - uint16_t id, seqno; -#endif /* !NETSTACK_CONF_WITH_IPV6 */ -} PACK_ALIAS_STRUCT; - - -/* The UDP headers. */ -struct uip_udp_hdr { - uint16_t srcport; - uint16_t destport; - uint16_t udplen; - uint16_t udpchksum; -} PACK_ALIAS_STRUCT; - - -/** - * The buffer size available for user data in the \ref uip_buf buffer. - * - * This macro holds the available size for user data in the \ref - * uip_buf buffer. The macro is intended to be used for checking - * bounds of available user data. - * - * Example: - \code - snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i); - \endcode - * - * \hideinitializer - */ -#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) -#define UIP_APPDATA_PTR(buf) (void *)&uip_buf(buf)[UIP_LLH_LEN + UIP_TCPIP_HLEN] - -#define UIP_PROTO_ICMP 1 -#define UIP_PROTO_TCP 6 -#define UIP_PROTO_UDP 17 -#define UIP_PROTO_ICMP6 58 - - -#if NETSTACK_CONF_WITH_IPV6 -/** @{ */ -/** \brief extension headers types */ -#define UIP_PROTO_HBHO 0 -#define UIP_PROTO_DESTO 60 -#define UIP_PROTO_ROUTING 43 -#define UIP_PROTO_FRAG 44 -#define UIP_PROTO_NONE 59 -/** @} */ - -/** @{ */ -/** \brief Destination and Hop By Hop extension headers option types */ -#define UIP_EXT_HDR_OPT_PAD1 0 -#define UIP_EXT_HDR_OPT_PADN 1 -#define UIP_EXT_HDR_OPT_RPL 0x63 - -/** @} */ - -/** @{ */ -/** - * \brief Bitmaps for extension header processing - * - * When processing extension headers, we should record somehow which one we - * see, because you cannot have twice the same header, except for destination - * We store all this in one uint8_t bitmap one bit for each header expected. The - * order in the bitmap is the order recommended in RFC2460 - */ -#define UIP_EXT_HDR_BITMAP_HBHO 0x01 -#define UIP_EXT_HDR_BITMAP_DESTO1 0x02 -#define UIP_EXT_HDR_BITMAP_ROUTING 0x04 -#define UIP_EXT_HDR_BITMAP_FRAG 0x08 -#define UIP_EXT_HDR_BITMAP_AH 0x10 -#define UIP_EXT_HDR_BITMAP_ESP 0x20 -#define UIP_EXT_HDR_BITMAP_DESTO2 0x40 -/** @} */ - - -#endif /* NETSTACK_CONF_WITH_IPV6 */ - - -#if UIP_FIXEDADDR -CCIF extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; -#else /* UIP_FIXEDADDR */ -CCIF extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; -#endif /* UIP_FIXEDADDR */ -CCIF extern const uip_ipaddr_t uip_broadcast_addr; -CCIF extern const uip_ipaddr_t uip_all_zeroes_addr; - -#if UIP_FIXEDETHADDR -CCIF extern const uip_lladdr_t uip_lladdr; -#else -CCIF extern uip_lladdr_t uip_lladdr; -#endif - - - - -#if NETSTACK_CONF_WITH_IPV6 -/** Length of the link local prefix */ -#define UIP_LLPREF_LEN 10 - -/** - * \brief Is IPv6 address a the unspecified address - * a is of type uip_ipaddr_t - */ -#define uip_is_addr_loopback(a) \ - ((((a)->u16[0]) == 0) && \ - (((a)->u16[1]) == 0) && \ - (((a)->u16[2]) == 0) && \ - (((a)->u16[3]) == 0) && \ - (((a)->u16[4]) == 0) && \ - (((a)->u16[5]) == 0) && \ - (((a)->u16[6]) == 0) && \ - (((a)->u8[14]) == 0) && \ - (((a)->u8[15]) == 0x01)) -/** - * \brief Is IPv6 address a the unspecified address - * a is of type uip_ipaddr_t - */ -#define uip_is_addr_unspecified(a) \ - ((((a)->u16[0]) == 0) && \ - (((a)->u16[1]) == 0) && \ - (((a)->u16[2]) == 0) && \ - (((a)->u16[3]) == 0) && \ - (((a)->u16[4]) == 0) && \ - (((a)->u16[5]) == 0) && \ - (((a)->u16[6]) == 0) && \ - (((a)->u16[7]) == 0)) - -/** \brief Is IPv6 address a the link local all-nodes multicast address */ -#define uip_is_addr_linklocal_allnodes_mcast(a) \ - ((((a)->u8[0]) == 0xff) && \ - (((a)->u8[1]) == 0x02) && \ - (((a)->u16[1]) == 0) && \ - (((a)->u16[2]) == 0) && \ - (((a)->u16[3]) == 0) && \ - (((a)->u16[4]) == 0) && \ - (((a)->u16[5]) == 0) && \ - (((a)->u16[6]) == 0) && \ - (((a)->u8[14]) == 0) && \ - (((a)->u8[15]) == 0x01)) - -/** \brief Is IPv6 address a the link local all-routers multicast address */ -#define uip_is_addr_linklocal_allrouters_mcast(a) \ - ((((a)->u8[0]) == 0xff) && \ - (((a)->u8[1]) == 0x02) && \ - (((a)->u16[1]) == 0) && \ - (((a)->u16[2]) == 0) && \ - (((a)->u16[3]) == 0) && \ - (((a)->u16[4]) == 0) && \ - (((a)->u16[5]) == 0) && \ - (((a)->u16[6]) == 0) && \ - (((a)->u8[14]) == 0) && \ - (((a)->u8[15]) == 0x02)) - -/** - * \brief Checks whether the address a is link local. - * a is of type uip_ipaddr_t - */ -#define uip_is_addr_linklocal(a) \ - ((a)->u8[0] == 0xfe && \ - (a)->u8[1] == 0x80) - -/** \brief set IP address a to unspecified */ -#define uip_create_unspecified(a) uip_ip6addr(a, 0, 0, 0, 0, 0, 0, 0, 0) - -/** \brief set IP address a to the link local all-nodes multicast address */ -#define uip_create_linklocal_allnodes_mcast(a) uip_ip6addr(a, 0xff02, 0, 0, 0, 0, 0, 0, 0x0001) - -/** \brief set IP address a to the link local all-routers multicast address */ -#define uip_create_linklocal_allrouters_mcast(a) uip_ip6addr(a, 0xff02, 0, 0, 0, 0, 0, 0, 0x0002) -#define uip_create_linklocal_prefix(addr) do { \ - (addr)->u16[0] = UIP_HTONS(0xfe80); \ - (addr)->u16[1] = 0; \ - (addr)->u16[2] = 0; \ - (addr)->u16[3] = 0; \ - } while(0) - -/** - * \brief is addr (a) a solicited node multicast address, see RFC3513 - * a is of type uip_ipaddr_t* - */ -#define uip_is_addr_solicited_node(a) \ - ((((a)->u8[0]) == 0xFF) && \ - (((a)->u8[1]) == 0x02) && \ - (((a)->u16[1]) == 0x00) && \ - (((a)->u16[2]) == 0x00) && \ - (((a)->u16[3]) == 0x00) && \ - (((a)->u16[4]) == 0x00) && \ - (((a)->u8[10]) == 0x00) && \ - (((a)->u8[11]) == 0x01) && \ - (((a)->u8[12]) == 0xFF)) - -/** - * \brief put in b the solicited node address corresponding to address a - * both a and b are of type uip_ipaddr_t* - * */ -#define uip_create_solicited_node(a, b) \ - (((b)->u8[0]) = 0xFF); \ - (((b)->u8[1]) = 0x02); \ - (((b)->u16[1]) = 0); \ - (((b)->u16[2]) = 0); \ - (((b)->u16[3]) = 0); \ - (((b)->u16[4]) = 0); \ - (((b)->u8[10]) = 0); \ - (((b)->u8[11]) = 0x01); \ - (((b)->u8[12]) = 0xFF); \ - (((b)->u8[13]) = ((a)->u8[13])); \ - (((b)->u16[7]) = ((a)->u16[7])) - -/** - * \brief is addr (a) a link local unicast address, see RFC3513 - * i.e. is (a) on prefix FE80::/10 - * a is of type uip_ipaddr_t* - */ -#define uip_is_addr_link_local(a) \ - ((((a)->u8[0]) == 0xFE) && \ - (((a)->u8[1]) == 0x80)) - -/** - * \brief was addr (a) forged based on the mac address m - * a type is uip_ipaddr_t - * m type is uiplladdr_t - */ -#if UIP_CONF_LL_802154 -#define uip_is_addr_mac_addr_based(a, m) \ - ((((a)->u8[8]) == (((m)->addr[0]) ^ 0x02)) && \ - (((a)->u8[9]) == (m)->addr[1]) && \ - (((a)->u8[10]) == (m)->addr[2]) && \ - (((a)->u8[11]) == (m)->addr[3]) && \ - (((a)->u8[12]) == (m)->addr[4]) && \ - (((a)->u8[13]) == (m)->addr[5]) && \ - (((a)->u8[14]) == (m)->addr[6]) && \ - (((a)->u8[15]) == (m)->addr[7])) -#else - -#define uip_is_addr_mac_addr_based(a, m) \ - ((((a)->u8[8]) == (((m)->addr[0]) | 0x02)) && \ - (((a)->u8[9]) == (m)->addr[1]) && \ - (((a)->u8[10]) == (m)->addr[2]) && \ - (((a)->u8[11]) == 0xff) && \ - (((a)->u8[12]) == 0xfe) && \ - (((a)->u8[13]) == (m)->addr[3]) && \ - (((a)->u8[14]) == (m)->addr[4]) && \ - (((a)->u8[15]) == (m)->addr[5])) - -#endif /*UIP_CONF_LL_802154*/ - -/** - * \brief is address a multicast address, see RFC 3513 - * a is of type uip_ipaddr_t* - * */ -#define uip_is_addr_mcast(a) \ - (((a)->u8[0]) == 0xFF) - -/** - * \brief is address a global multicast address (FFxE::/16), - * a is of type uip_ip6addr_t* - * */ -#define uip_is_addr_mcast_global(a) \ - ((((a)->u8[0]) == 0xFF) && \ - (((a)->u8[1] & 0x0F) == 0x0E)) - -/** - * \brief is address a non-routable multicast address. - * Scopes 1 (interface-local) and 2 (link-local) are non-routable - * See RFC4291 and draft-ietf-6man-multicast-scopes - * a is of type uip_ip6addr_t* - * */ -#define uip_is_addr_mcast_non_routable(a) \ - ((((a)->u8[0]) == 0xFF) && \ - (((a)->u8[1] & 0x0F) <= 0x02)) - -/** - * \brief is address a routable multicast address. - * Scope 3 (Realm-Local) or higher are routable - * Realm-Local scope is defined in draft-ietf-6man-multicast-scopes - * See RFC4291 and draft-ietf-6man-multicast-scopes - * a is of type uip_ip6addr_t* - * */ -#define uip_is_addr_mcast_routable(a) \ - ((((a)->u8[0]) == 0xFF) && \ - (((a)->u8[1] & 0x0F) > 0x02)) - -/** - * \brief is group-id of multicast address a - * the all nodes group-id - */ -#define uip_is_mcast_group_id_all_nodes(a) \ - ((((a)->u16[1]) == 0) && \ - (((a)->u16[2]) == 0) && \ - (((a)->u16[3]) == 0) && \ - (((a)->u16[4]) == 0) && \ - (((a)->u16[5]) == 0) && \ - (((a)->u16[6]) == 0) && \ - (((a)->u8[14]) == 0) && \ - (((a)->u8[15]) == 1)) - -/** - * \brief is group-id of multicast address a - * the all routers group-id - */ -#define uip_is_mcast_group_id_all_routers(a) \ - ((((a)->u16[1]) == 0) && \ - (((a)->u16[2]) == 0) && \ - (((a)->u16[3]) == 0) && \ - (((a)->u16[4]) == 0) && \ - (((a)->u16[5]) == 0) && \ - (((a)->u16[6]) == 0) && \ - (((a)->u8[14]) == 0) && \ - (((a)->u8[15]) == 2)) - - -/** - * \brief are last three bytes of both addresses equal? - * This is used to compare solicited node multicast addresses - */ -#define uip_are_solicited_bytes_equal(a, b) \ - ((((a)->u8[13]) == ((b)->u8[13])) && \ - (((a)->u8[14]) == ((b)->u8[14])) && \ - (((a)->u8[15]) == ((b)->u8[15]))) - -#endif /*NETSTACK_CONF_WITH_IPV6*/ - -/** - * Calculate the Internet checksum over a buffer. - * - * The Internet checksum is the one's complement of the one's - * complement sum of all 16-bit words in the buffer. - * - * See RFC1071. - * - * \param data A pointer to the buffer over which the checksum is to be - * computed. - * - * \param len The length of the buffer over which the checksum is to - * be computed. - * - * \return The Internet checksum of the buffer. - */ -uint16_t uip_chksum(uint16_t *data, uint16_t len); - -/** - * Calculate the IP header checksum of the packet header in uip_buf. - * - * The IP header checksum is the Internet checksum of the 20 bytes of - * the IP header. - * - * \return The IP header checksum of the IP header in the uip_buf - * buffer. - */ -uint16_t uip_ipchksum(struct net_buf *buf); - -/** - * Calculate the TCP checksum of the packet in uip_buf and uip_appdata. - * - * The TCP checksum is the Internet checksum of data contents of the - * TCP segment, and a pseudo-header as defined in RFC793. - * - * \return The TCP checksum of the TCP segment in uip_buf and pointed - * to by uip_appdata. - */ -uint16_t uip_tcpchksum(struct net_buf *buf); - -/** - * Calculate the UDP checksum of the packet in uip_buf and uip_appdata. - * - * The UDP checksum is the Internet checksum of data contents of the - * UDP segment, and a pseudo-header as defined in RFC768. - * - * \return The UDP checksum of the UDP segment in uip_buf and pointed - * to by uip_appdata. - */ -uint16_t uip_udpchksum(struct net_buf *buf); - -/** - * Calculate the ICMP checksum of the packet in uip_buf. - * - * \return The ICMP checksum of the ICMP packet in uip_buf - */ -uint16_t uip_icmp6chksum(struct net_buf *buf); - - -#endif /* UIP_H_ */ - - -/** @} */ diff --git a/net/ip/contiki/ip/uipaddr.h b/net/ip/contiki/ip/uipaddr.h deleted file mode 100644 index 6f08d74f638c18a526cb3514122fb177725edafd..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/uipaddr.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack. - * - * - */ - -#ifndef UIPADDR_H_ -#define UIPADDR_H_ - -/** - * Representation of an IP address. - * - */ -typedef union uip_ip4addr_t { - uint8_t u8[4]; /* Initializer, must come first. */ - uint16_t u16[2]; -} uip_ip4addr_t; - -typedef union uip_ip6addr_t { - uint8_t u8[16]; /* Initializer, must come first. */ - uint16_t u16[8]; -} PACK_ALIAS_STRUCT uip_ip6addr_t; - -#if NETSTACK_CONF_WITH_IPV6 -typedef uip_ip6addr_t uip_ipaddr_t; -#else /* NETSTACK_CONF_WITH_IPV6 */ -typedef uip_ip4addr_t uip_ipaddr_t; -#endif /* NETSTACK_CONF_WITH_IPV6 */ - -/*---------------------------------------------------------------------------*/ - -/** \brief 16 bit 802.15.4 address */ -typedef struct uip_802154_shortaddr { - uint8_t addr[2]; -} uip_802154_shortaddr; -/** \brief 64 bit 802.15.4 address */ -typedef struct uip_802154_longaddr { - uint8_t addr[8]; -} uip_802154_longaddr; - -/** \brief 802.11 address */ -typedef struct uip_80211_addr { - uint8_t addr[6]; -} uip_80211_addr; - -/** \brief 802.3 address */ -typedef struct uip_eth_addr { - uint8_t addr[6]; -} uip_eth_addr; - - -#if UIP_CONF_LL_802154 -/** \brief 802.15.4 address */ -typedef uip_802154_longaddr uip_lladdr_t; -#define UIP_802154_SHORTADDR_LEN 2 -#define UIP_802154_LONGADDR_LEN 8 -#define UIP_LLADDR_LEN UIP_802154_LONGADDR_LEN -#else /*UIP_CONF_LL_802154*/ -#if UIP_CONF_LL_80211 -/** \brief 802.11 address */ -typedef uip_80211_addr uip_lladdr_t; -#define UIP_LLADDR_LEN 6 -#else /*UIP_CONF_LL_80211*/ -/** \brief Ethernet address */ -typedef uip_eth_addr uip_lladdr_t; -#define UIP_LLADDR_LEN 6 -#endif /*UIP_CONF_LL_80211*/ -#endif /*UIP_CONF_LL_802154*/ - -#endif /* UIPADDR_H_ */ diff --git a/net/ip/contiki/ip/uiplib.c b/net/ip/contiki/ip/uiplib.c deleted file mode 100644 index adc465eb5d60baa32df9843cc9bfb8a13b368e69..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/uiplib.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2004, Adam Dunkels and the Swedish Institute of - * Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack and the Contiki operating system. - * - * - */ - - -#include "contiki/ip/uip.h" -#include "contiki/ip/uiplib.h" -#include - -#define DEBUG DEBUG_NONE -#include "contiki/ip/uip-debug.h" - -/*-----------------------------------------------------------------------------------*/ -#if NETSTACK_CONF_WITH_IPV6 -int -uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *ipaddr) -{ - uint16_t value; - int tmp, zero; - unsigned int len; - char c = 0; //gcc warning if not initialized - - value = 0; - zero = -1; - if(*addrstr == '[') addrstr++; - - for(len = 0; len < sizeof(uip_ip6addr_t) - 1; addrstr++) { - c = *addrstr; - if(c == ':' || c == '\0' || c == ']' || c == '/') { - ipaddr->u8[len] = (value >> 8) & 0xff; - ipaddr->u8[len + 1] = value & 0xff; - len += 2; - value = 0; - - if(c == '\0' || c == ']' || c == '/') { - break; - } - - if(*(addrstr + 1) == ':') { - /* Zero compression */ - if(zero < 0) { - zero = len; - } - addrstr++; - } - } else { - if(c >= '0' && c <= '9') { - tmp = c - '0'; - } else if(c >= 'a' && c <= 'f') { - tmp = c - 'a' + 10; - } else if(c >= 'A' && c <= 'F') { - tmp = c - 'A' + 10; - } else { - PRINTF("uiplib: illegal char: '%c'\n", c); - return 0; - } - value = (value << 4) + (tmp & 0xf); - } - } - if(c != '\0' && c != ']' && c != '/') { - PRINTF("uiplib: too large address\n"); - return 0; - } - if(len < sizeof(uip_ip6addr_t)) { - if(zero < 0) { - PRINTF("uiplib: too short address\n"); - return 0; - } - memmove(&ipaddr->u8[zero + sizeof(uip_ip6addr_t) - len], - &ipaddr->u8[zero], len - zero); - memset(&ipaddr->u8[zero], 0, sizeof(uip_ip6addr_t) - len); - } - - return 1; -} -#endif /* NETSTACK_CONF_WITH_IPV6 */ -/*-----------------------------------------------------------------------------------*/ -/* Parse a IPv4-address from a string. Returns the number of characters read - * for the address. */ -int -uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *ipaddr) -{ - unsigned char tmp; - char c; - unsigned char i, j; - uint8_t charsread = 0; - - tmp = 0; - - for(i = 0; i < 4; ++i) { - j = 0; - do { - c = *addrstr; - ++j; - if(j > 4) { - return 0; - } - if(c == '.' || c == 0 || c == ' ') { - ipaddr->u8[i] = tmp; - tmp = 0; - } else if(c >= '0' && c <= '9') { - tmp = (tmp * 10) + (c - '0'); - } else { - return 0; - } - ++addrstr; - ++charsread; - } while(c != '.' && c != 0 && c != ' '); - - } - return charsread-1; -} -/*-----------------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/ip/uiplib.h b/net/ip/contiki/ip/uiplib.h deleted file mode 100644 index af4369e679ed18fcfcabdc26bac565477be0259d..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/uiplib.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2002, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the Contiki desktop environment for the C64. - * - * - */ - -/** - * \file - * Various uIP library functions. - * \author - * Adam Dunkels - * - */ - -#ifndef UIPLIB_H_ -#define UIPLIB_H_ - -#include "contiki/ip/uip.h" - -/** - * \addtogroup uipconvfunc - * @{ - */ - -/** - * Convert a textual representation of an IP address to a numerical representation. - * - * This function takes a textual representation of an IP address in - * the form a.b.c.d for IPv4 or a:b:c:d:e:f:g:h for IPv6 and converts - * it into a numeric IP address representation that can be used by - * other uIP functions. - * - * \param addrstr A pointer to a string containing the IP address in - * textual form. - * - * \param addr A pointer to a uip_ip4addr_t that will be filled in with - * the numerical representation of the address. - * - * \retval 0 If the IP address could not be parsed. - * \retval Non-zero If the IP address was parsed. - */ -#if NETSTACK_CONF_WITH_IPV6 -#define uiplib_ipaddrconv uiplib_ip6addrconv -#else /* NETSTACK_CONF_WITH_IPV6 */ -#define uiplib_ipaddrconv uiplib_ip4addrconv -#endif /* NETSTACK_CONF_WITH_IPV6 */ - -CCIF int uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *addr); -CCIF int uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *addr); -/** @} */ - -#endif /* UIPLIB_H_ */ diff --git a/net/ip/contiki/ip/uipopt.h b/net/ip/contiki/ip/uipopt.h deleted file mode 100644 index f2610c53f14e14ec14e0f10b35a6e409975e4ada..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ip/uipopt.h +++ /dev/null @@ -1,684 +0,0 @@ -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack. - * - * - */ - -/** - * \file - * Configuration options for uIP. - * \author Adam Dunkels - * - * This file is used for tweaking various configuration options for - * uIP. You should make a copy of this file into one of your project's - * directories instead of editing this example "uipopt.h" file that - * comes with the uIP distribution. - */ - -/** - * \addtogroup uip - * @{ - */ - -/** - * \defgroup uipopt Configuration options for uIP - * @{ - * - * uIP is configured using the per-project configuration file - * "uipopt.h". This file contains all compile-time options for uIP and - * should be tweaked to match each specific project. The uIP - * distribution contains a documented example "uipopt.h" that can be - * copied and modified for each project. - * - * \note Contiki does not use the uipopt.h file to configure uIP, but - * uses a per-port uip-conf.h file that should be edited instead. - */ - -#ifndef UIPOPT_H_ -#define UIPOPT_H_ - -#ifndef UIP_LITTLE_ENDIAN -#define UIP_LITTLE_ENDIAN 3412 -#endif /* UIP_LITTLE_ENDIAN */ -#ifndef UIP_BIG_ENDIAN -#define UIP_BIG_ENDIAN 1234 -#endif /* UIP_BIG_ENDIAN */ - -#include "contiki-conf.h" - -/*------------------------------------------------------------------------------*/ - -/** - * \defgroup uipoptstaticconf Static configuration options - * @{ - * - * These configuration options can be used for setting the IP address - * settings statically, but only if UIP_FIXEDADDR is set to 1. The - * configuration options for a specific node includes IP address, - * netmask and default router as well as the Ethernet address. The - * netmask, default router and Ethernet address are applicable only - * if uIP should be run over Ethernet. - * - * This options are meaningful only for the IPv4 code. - * - * All of these should be changed to suit your project. - */ - -/** - * Determines if uIP should use a fixed IP address or not. - * - * If uIP should use a fixed IP address, the settings are set in the - * uipopt.h file. If not, the macros uip_sethostaddr(), - * uip_setdraddr() and uip_setnetmask() should be used instead. - * - * \hideinitializer - */ -#define UIP_FIXEDADDR 0 - -/** - * Ping IP address assignment. - * - * uIP uses a "ping" packets for setting its own IP address if this - * option is set. If so, uIP will start with an empty IP address and - * the destination IP address of the first incoming "ping" (ICMP echo) - * packet will be used for setting the hosts IP address. - * - * \note This works only if UIP_FIXEDADDR is 0. - * - * \hideinitializer - */ -#ifdef UIP_CONF_PINGADDRCONF -#define UIP_PINGADDRCONF (UIP_CONF_PINGADDRCONF) -#else /* UIP_CONF_PINGADDRCONF */ -#define UIP_PINGADDRCONF 0 -#endif /* UIP_CONF_PINGADDRCONF */ - - -/** - * Specifies if the uIP ARP module should be compiled with a fixed - * Ethernet MAC address or not. - * - * If this configuration option is 0, the macro uip_setethaddr() can - * be used to specify the Ethernet address at run-time. - * - * \hideinitializer - */ -#define UIP_FIXEDETHADDR 0 - -/** @} */ -/*------------------------------------------------------------------------------*/ - -/** - * \defgroup uipoptgeneral General configuration options - * @{ - */ - -/** - * The link level header length. - * - * This is the offset into the uip_buf where the IP header can be - * found. For Ethernet, this should be set to 14. For SLIP, this - * should be set to 0. - * - * \note we probably won't use this constant for other link layers than - * ethernet as they have variable header length (this is due to variable - * number and type of address fields and to optional security features) - * E.g.: 802.15.4 -> 2 + (1/2*4/8) + 0/5/6/10/14 - * 802.11 -> 4 + (6*3/4) + 2 - * \hideinitializer - */ -#ifdef UIP_CONF_LLH_LEN -#define UIP_LLH_LEN (UIP_CONF_LLH_LEN) -#else /* UIP_LLH_LEN */ -#define UIP_LLH_LEN 0 -#endif /* UIP_CONF_LLH_LEN */ - -/** - * The size of the uIP packet buffer. - * - * The uIP packet buffer should not be smaller than 60 bytes, and does - * not need to be larger than 1514 bytes. Lower size results in lower - * TCP throughput, larger size results in higher TCP throughput. - * - * \hideinitializer - */ -#ifndef UIP_CONF_BUFFER_SIZE -#define UIP_BUFSIZE (UIP_LINK_MTU + UIP_LLH_LEN) -#else /* UIP_CONF_BUFFER_SIZE */ -#define UIP_BUFSIZE (UIP_CONF_BUFFER_SIZE) -#endif /* UIP_CONF_BUFFER_SIZE */ - - -/** - * Determines if statistics support should be compiled in. - * - * The statistics is useful for debugging and to show the user. - * - * \hideinitializer - */ -#ifndef UIP_CONF_STATISTICS -#define UIP_STATISTICS 0 -#else /* UIP_CONF_STATISTICS */ -#define UIP_STATISTICS (UIP_CONF_STATISTICS) -#endif /* UIP_CONF_STATISTICS */ - -/** - * Determines if logging of certain events should be compiled in. - * - * This is useful mostly for debugging. The function uip_log() - * must be implemented to suit the architecture of the project, if - * logging is turned on. - * - * \hideinitializer - */ -#ifndef UIP_CONF_LOGGING -#define UIP_LOGGING 0 -#else /* UIP_CONF_LOGGING */ -#define UIP_LOGGING (UIP_CONF_LOGGING) -#endif /* UIP_CONF_LOGGING */ - -/** - * Broadcast support. - * - * This flag configures IP broadcast support. This is useful only - * together with UDP. - * - * \hideinitializer - * - */ -#ifndef UIP_CONF_BROADCAST -#define UIP_BROADCAST 0 -#else /* UIP_CONF_BROADCAST */ -#define UIP_BROADCAST (UIP_CONF_BROADCAST) -#endif /* UIP_CONF_BROADCAST */ - -/** - * Print out a uIP log message. - * - * This function must be implemented by the module that uses uIP, and - * is called by uIP whenever a log message is generated. - */ -void uip_log(char *msg); - -/** @} */ -/*------------------------------------------------------------------------------*/ -/** - * \defgroup uipoptip IP configuration options - * @{ - * - */ -/** - * The IP TTL (time to live) of IP packets sent by uIP. - * - * This should normally not be changed. - */ -#ifdef UIP_CONF_TTL -#define UIP_TTL UIP_CONF_TTL -#else /* UIP_CONF_TTL */ -#define UIP_TTL 64 -#endif /* UIP_CONF_TTL */ - -/** - * The maximum time an IP fragment should wait in the reassembly - * buffer before it is dropped. - * - */ -#define UIP_REASS_MAXAGE 60 /*60s*/ - -/** - * Turn on support for IP packet reassembly. - * - * uIP supports reassembly of fragmented IP packets. This features - * requires an additional amount of RAM to hold the reassembly buffer - * and the reassembly code size is approximately 700 bytes. The - * reassembly buffer is of the same size as the uip_buf buffer - * (configured by UIP_BUFSIZE). - * - * \note IP packet reassembly is not heavily tested. - * - * \hideinitializer - */ -#ifdef UIP_CONF_REASSEMBLY -#define UIP_REASSEMBLY (UIP_CONF_REASSEMBLY) -#else /* UIP_CONF_REASSEMBLY */ -#define UIP_REASSEMBLY 0 -#endif /* UIP_CONF_REASSEMBLY */ -/** @} */ - -/*------------------------------------------------------------------------------*/ -/** - * \defgroup uipoptipv6 IPv6 configuration options - * @{ - * - */ - -/** The maximum transmission unit at the IP Layer*/ -#define UIP_LINK_MTU 1280 - -#ifndef NETSTACK_CONF_WITH_IPV6 -/** Do we use IPv6 or not (default: no) */ -#define NETSTACK_CONF_WITH_IPV6 0 -#endif - -#ifndef UIP_CONF_IPV6_QUEUE_PKT -/** Do we do per %neighbor queuing during address resolution (default: no) */ -#define UIP_CONF_IPV6_QUEUE_PKT 0 -#endif - -#ifndef UIP_CONF_IPV6_CHECKS -/** Do we do IPv6 consistency checks (highly recommended, default: yes) */ -#define UIP_CONF_IPV6_CHECKS 1 -#endif - -#ifndef UIP_CONF_IPV6_REASSEMBLY -/** Do we do IPv6 fragmentation (default: no) */ -#define UIP_CONF_IPV6_REASSEMBLY 0 -#endif - -#ifndef UIP_CONF_NETIF_MAX_ADDRESSES -/** Default number of IPv6 addresses associated to the node's interface */ -#define UIP_CONF_NETIF_MAX_ADDRESSES 3 -#endif - -#ifndef UIP_CONF_DS6_PREFIX_NBU -/** Default number of IPv6 prefixes associated to the node's interface */ -#define UIP_CONF_DS6_PREFIX_NBU 2 -#endif - -#ifndef UIP_CONF_DS6_DEFRT_NBU -/** Minimum number of default routers */ -#define UIP_CONF_DS6_DEFRT_NBU 2 -#endif -/** @} */ - -/*------------------------------------------------------------------------------*/ -/** - * \defgroup uipoptudp UDP configuration options - * @{ - * - * \note The UDP support in uIP is still not entirely complete; there - * is no support for sending or receiving broadcast or multicast - * packets, but it works well enough to support a number of vital - * applications such as DNS queries, though - */ - -/** - * Toggles whether UDP support should be compiled in or not. - * - * \hideinitializer - */ -#ifdef UIP_CONF_UDP -#define UIP_UDP UIP_CONF_UDP -#else /* UIP_CONF_UDP */ -#define UIP_UDP 1 -#endif /* UIP_CONF_UDP */ - -/** - * Toggles if UDP checksums should be used or not. - * - * \note Support for UDP checksums is currently not included in uIP, - * so this option has no function. - * - * \hideinitializer - */ -#ifdef UIP_CONF_UDP_CHECKSUMS -#define UIP_UDP_CHECKSUMS (UIP_CONF_UDP_CHECKSUMS) -#else -#define UIP_UDP_CHECKSUMS (NETSTACK_CONF_WITH_IPV6) -#endif - -/** - * The maximum amount of concurrent UDP connections. - * - * \hideinitializer - */ -#ifdef UIP_CONF_UDP_CONNS -#define UIP_UDP_CONNS (UIP_CONF_UDP_CONNS) -#else /* UIP_CONF_UDP_CONNS */ -#define UIP_UDP_CONNS 10 -#endif /* UIP_CONF_UDP_CONNS */ - -/** - * The name of the function that should be called when UDP datagrams arrive. - * - * \hideinitializer - */ - - -/** @} */ -/*------------------------------------------------------------------------------*/ -/** - * \defgroup uipopttcp TCP configuration options - * @{ - */ - -/** - * Toggles whether TCP support should be compiled in or not. - * - * \hideinitializer - */ -#ifdef UIP_CONF_TCP -#define UIP_TCP (UIP_CONF_TCP) -#else /* UIP_CONF_TCP */ -#define UIP_TCP 1 -#endif /* UIP_CONF_TCP */ - -/** - * Determines if support for opening connections from uIP should be - * compiled in. - * - * If the applications that are running on top of uIP for this project - * do not need to open outgoing TCP connections, this configuration - * option can be turned off to reduce the code size of uIP. - * - * \hideinitializer - */ -#ifndef UIP_CONF_ACTIVE_OPEN -#define UIP_ACTIVE_OPEN 1 -#else /* UIP_CONF_ACTIVE_OPEN */ -#define UIP_ACTIVE_OPEN (UIP_CONF_ACTIVE_OPEN) -#endif /* UIP_CONF_ACTIVE_OPEN */ - -/** - * The maximum number of simultaneously open TCP connections. - * - * Since the TCP connections are statically allocated, turning this - * configuration knob down results in less RAM used. Each TCP - * connection requires approximately 30 bytes of memory. - * - * \hideinitializer - */ -#ifndef UIP_CONF_MAX_CONNECTIONS -#define UIP_CONNS 10 -#else /* UIP_CONF_MAX_CONNECTIONS */ -#define UIP_CONNS (UIP_CONF_MAX_CONNECTIONS) -#endif /* UIP_CONF_MAX_CONNECTIONS */ - - -/** - * The maximum number of simultaneously listening TCP ports. - * - * Each listening TCP port requires 2 bytes of memory. - * - * \hideinitializer - */ -#ifndef UIP_CONF_MAX_LISTENPORTS -#define UIP_LISTENPORTS 20 -#else /* UIP_CONF_MAX_LISTENPORTS */ -#define UIP_LISTENPORTS (UIP_CONF_MAX_LISTENPORTS) -#endif /* UIP_CONF_MAX_LISTENPORTS */ - -/** - * Determines if support for TCP urgent data notification should be - * compiled in. - * - * Urgent data (out-of-band data) is a rarely used TCP feature that - * very seldom would be required. - * - * \hideinitializer - */ -#define UIP_URGDATA 0 - -/** - * The initial retransmission timeout counted in timer pulses. - * - * This should not be changed. - */ -#define UIP_RTO 3 - -/** - * The maximum number of times a segment should be retransmitted - * before the connection should be aborted. - * - * This should not be changed. - */ -#define UIP_MAXRTX 8 - -/** - * The maximum number of times a SYN segment should be retransmitted - * before a connection request should be deemed to have been - * unsuccessful. - * - * This should not need to be changed. - */ -#define UIP_MAXSYNRTX 5 - -/** - * The TCP maximum segment size. - * - * This is should not be to set to more than - * UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN. - */ -#ifdef UIP_CONF_TCP_MSS -#if UIP_CONF_TCP_MSS > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) -#error UIP_CONF_TCP_MSS is too large for the current UIP_BUFSIZE -#endif /* UIP_CONF_TCP_MSS > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) */ -#define UIP_TCP_MSS (UIP_CONF_TCP_MSS) -#else /* UIP_CONF_TCP_MSS */ -#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) -#endif /* UIP_CONF_TCP_MSS */ - -/** - * The size of the advertised receiver's window. - * - * Should be set low (i.e., to the size of the uip_buf buffer) if the - * application is slow to process incoming data, or high (32768 bytes) - * if the application processes data quickly. - * - * \hideinitializer - */ -#ifndef UIP_CONF_RECEIVE_WINDOW -#define UIP_RECEIVE_WINDOW (UIP_TCP_MSS) -#else -#define UIP_RECEIVE_WINDOW (UIP_CONF_RECEIVE_WINDOW) -#endif - -/** - * How long a connection should stay in the TIME_WAIT state. - * - * This can be reduced for faster entry into power saving modes. - */ -#ifndef UIP_CONF_WAIT_TIMEOUT -#define UIP_TIME_WAIT_TIMEOUT 120 -#else -#define UIP_TIME_WAIT_TIMEOUT UIP_CONF_WAIT_TIMEOUT -#endif - -/** @} */ -/*------------------------------------------------------------------------------*/ -/** - * \defgroup uipoptarp ARP configuration options - * @{ - */ - -/** - * The size of the ARP table. - * - * This option should be set to a larger value if this uIP node will - * have many connections from the local network. - * - * \hideinitializer - */ -#ifdef UIP_CONF_ARPTAB_SIZE -#define UIP_ARPTAB_SIZE (UIP_CONF_ARPTAB_SIZE) -#else -#define UIP_ARPTAB_SIZE 8 -#endif - -/** - * The maximum age of ARP table entries measured in 10ths of seconds. - * - * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD - * default). - */ -#define UIP_ARP_MAXAGE 120 - - -/** @} */ - -/*------------------------------------------------------------------------------*/ - -/** - * \defgroup uipoptmac layer 2 options (for ipv6) - * @{ - */ - -#define UIP_DEFAULT_PREFIX_LEN 64 - -/** @} */ - -/*------------------------------------------------------------------------------*/ - -/** - * \defgroup uipoptsics 6lowpan options (for ipv6) - * @{ - */ -/** - * Timeout for packet reassembly at the 6lowpan layer - * (should be < 60s) - */ -#ifdef SICSLOWPAN_CONF_MAXAGE -#define SICSLOWPAN_REASS_MAXAGE (SICSLOWPAN_CONF_MAXAGE) -#else -#define SICSLOWPAN_REASS_MAXAGE 20 -#endif - -/** - * Do we compress the IP header or not (default: no) - */ -#ifndef SICSLOWPAN_CONF_COMPRESSION -#define SICSLOWPAN_CONF_COMPRESSION 0 -#endif - -/** - * If we use IPHC compression, how many address contexts do we support - */ -#ifndef SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS -#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 -#endif - -/** - * Do we support 6lowpan fragmentation - */ -#ifndef SICSLOWPAN_CONF_FRAG -#define SICSLOWPAN_CONF_FRAG 0 -#endif - -/** @} */ - -/*------------------------------------------------------------------------------*/ -/** - * \defgroup uipoptcpu CPU architecture configuration - * @{ - * - * The CPU architecture configuration is where the endianess of the - * CPU on which uIP is to be run is specified. Most CPUs today are - * little endian, and the most notable exception are the Motorolas - * which are big endian. The BYTE_ORDER macro should be changed to - * reflect the CPU architecture on which uIP is to be run. - */ - -/** - * The byte order of the CPU architecture on which uIP is to be run. - * - * This option can be either UIP_BIG_ENDIAN (Motorola byte order) or - * UIP_LITTLE_ENDIAN (Intel byte order). - * - * \hideinitializer - */ -#ifdef UIP_CONF_BYTE_ORDER -#define UIP_BYTE_ORDER (UIP_CONF_BYTE_ORDER) -#else /* UIP_CONF_BYTE_ORDER */ -#define UIP_BYTE_ORDER (UIP_LITTLE_ENDIAN) -#endif /* UIP_CONF_BYTE_ORDER */ - -/** @} */ -/*------------------------------------------------------------------------------*/ - -/** - * \defgroup uipoptapp Application specific configurations - * @{ - * - * An uIP application is implemented using a single application - * function that is called by uIP whenever a TCP/IP event occurs. The - * name of this function must be registered with uIP at compile time - * using the UIP_APPCALL definition. - * - * uIP applications can store the application state within the - * uip_conn structure by specifying the type of the application - * structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t. - * - * The file containing the definitions must be included in the - * uipopt.h file. - * - * The following example illustrates how this can look. - \code - - void httpd_appcall(void); - #define UIP_APPCALL httpd_appcall - - struct httpd_state { - uint8_t state; - uint16_t count; - char *dataptr; - char *script; - }; - typedef struct httpd_state uip_tcp_appstate_t - \endcode - */ - -/** - * \var #define UIP_APPCALL - * - * The name of the application function that uIP should call in - * response to TCP/IP events. - * - */ - -/** - * \var typedef uip_tcp_appstate_t - * - * The type of the application state that is to be stored in the - * uip_conn structure. This usually is typedef:ed to a struct holding - * application state information. - */ - -/** - * \var typedef uip_udp_appstate_t - * - * The type of the application state that is to be stored in the - * uip_conn structure. This usually is typedef:ed to a struct holding - * application state information. - */ -/** @} */ - -#endif /* UIPOPT_H_ */ -/** @} */ -/** @} */ diff --git a/net/ip/contiki/ipv4/uip-neighbor.c b/net/ip/contiki/ipv4/uip-neighbor.c deleted file mode 100644 index 5b8203e40d023c0124e1434b991d105b213b0fe1..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv4/uip-neighbor.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Database of link-local neighbors, used by IPv6 code and - * to be used by a future ARP code rewrite. - * \author - * Adam Dunkels - */ - -#include "contiki/ipv4/uip-neighbor.h" - -#include -#include - -#define MAX_TIME 128 - -#ifdef UIP_NEIGHBOR_CONF_ENTRIES -#define ENTRIES UIP_NEIGHBOR_CONF_ENTRIES -#else /* UIP_NEIGHBOR_CONF_ENTRIES */ -#define ENTRIES 8 -#endif /* UIP_NEIGHBOR_CONF_ENTRIES */ - -struct neighbor_entry { - uip_ipaddr_t ipaddr; - struct uip_neighbor_addr addr; - uint8_t time; -}; -static struct neighbor_entry entries[ENTRIES]; - -/*---------------------------------------------------------------------------*/ -void -uip_neighbor_init(void) -{ - int i; - - for(i = 0; i < ENTRIES; ++i) { - entries[i].time = MAX_TIME; - } -} -/*---------------------------------------------------------------------------*/ -void -uip_neighbor_periodic(void) -{ - int i; - - for(i = 0; i < ENTRIES; ++i) { - if(entries[i].time < MAX_TIME) { - entries[i].time++; - } - } -} -/*---------------------------------------------------------------------------*/ -void -uip_neighbor_add(uip_ipaddr_t *ipaddr, struct uip_neighbor_addr *addr) -{ - int i, oldest; - uint8_t oldest_time; - - /* printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n", - addr->addr.addr[0], addr->addr.addr[1], addr->addr.addr[2], addr->addr.addr[3], - addr->addr.addr[4], addr->addr.addr[5]);*/ - - /* Find the first unused entry or the oldest used entry. */ - oldest_time = 0; - oldest = 0; - for(i = 0; i < ENTRIES; ++i) { - if(entries[i].time == MAX_TIME) { - oldest = i; - break; - } - if(uip_ipaddr_cmp(&entries[i].ipaddr, ipaddr)) { - oldest = i; - break; - } - if(entries[i].time > oldest_time) { - oldest = i; - oldest_time = entries[i].time; - } - } - - /* Use the oldest or first free entry (either pointed to by the - "oldest" variable). */ - entries[oldest].time = 0; - uip_ipaddr_copy(&entries[oldest].ipaddr, ipaddr); - memcpy(&entries[oldest].addr, addr, sizeof(struct uip_neighbor_addr)); -} -/*---------------------------------------------------------------------------*/ -static struct neighbor_entry * -find_entry(uip_ipaddr_t *ipaddr) -{ - int i; - - for(i = 0; i < ENTRIES; ++i) { - if(uip_ipaddr_cmp(&entries[i].ipaddr, ipaddr)) { - return &entries[i]; - } - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -void -uip_neighbor_update(uip_ipaddr_t *ipaddr) -{ - struct neighbor_entry *e; - - e = find_entry(ipaddr); - if(e != NULL) { - e->time = 0; - } -} -/*---------------------------------------------------------------------------*/ -struct uip_neighbor_addr * -uip_neighbor_lookup(uip_ipaddr_t *ipaddr) -{ - struct neighbor_entry *e; - - e = find_entry(ipaddr); - if(e != NULL) { - /* printf("Lookup neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n", - e->addr.addr.addr[0], e->addr.addr.addr[1], e->addr.addr.addr[2], e->addr.addr.addr[3], - e->addr.addr.addr[4], e->addr.addr.addr[5]);*/ - - return &e->addr; - } - return NULL; -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/ipv4/uip-neighbor.h b/net/ip/contiki/ipv4/uip-neighbor.h deleted file mode 100644 index 707c32cbaed90c2b10a967c8d70ac0167f187c4c..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv4/uip-neighbor.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header file for database of link-local neighbors, used by - * IPv6 code and to be used by future ARP code. - * \author - * Adam Dunkels - */ - -#ifndef UIP_NEIGHBOR_H_ -#define UIP_NEIGHBOR_H_ - -#include "contiki/ip/uip.h" - -struct uip_neighbor_addr { -#if UIP_NEIGHBOR_CONF_ADDRTYPE - UIP_NEIGHBOR_CONF_ADDRTYPE addr; -#else - struct uip_eth_addr addr; -#endif -}; - -void uip_neighbor_init(void); -void uip_neighbor_add(uip_ipaddr_t *ipaddr, struct uip_neighbor_addr *addr); -void uip_neighbor_update(uip_ipaddr_t *ipaddr); -struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t *ipaddr); -void uip_neighbor_periodic(void); - -#endif /* UIP-NEIGHBOR_H_ */ diff --git a/net/ip/contiki/ipv4/uip.c b/net/ip/contiki/ipv4/uip.c deleted file mode 100644 index d182c638e3d37b9de129c35409799dce1f2329f4..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv4/uip.c +++ /dev/null @@ -1,2278 +0,0 @@ -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack. - * - * - */ - -/** - * \file - * The uIP TCP/IP stack code. - * \author Adam Dunkels - */ - -/** - * \addtogroup uip - * @{ - */ - -#define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/ - -/* - * uIP is a small implementation of the IP, UDP and TCP protocols (as - * well as some basic ICMP stuff). The implementation couples the IP, - * UDP, TCP and the application layers very tightly. To keep the size - * of the compiled code down, this code frequently uses the goto - * statement. While it would be possible to break the uip_process() - * function into many smaller functions, this would increase the code - * size because of the overhead of parameter passing and the fact that - * the optimier would not be as efficient. - * - * The principle is that we have a small buffer, called the uip_buf, - * in which the device driver puts an incoming packet. The TCP/IP - * stack parses the headers in the packet, and calls the - * application. If the remote host has sent data to the application, - * this data is present in the uip_buf and the application read the - * data from there. It is up to the application to put this data into - * a byte stream if needed. The application will not be fed with data - * that is out of sequence. - * - * If the application whishes to send data to the peer, it should put - * its data into the uip_buf. The uip_appdata pointer points to the - * first available byte. The TCP/IP stack will calculate the - * checksums, and fill in the necessary header fields and finally send - * the packet back to the peer. -*/ - -#include "contiki/ip/uip.h" -#include "contiki/ip/uipopt.h" -#include "contiki/ipv4/uip_arp.h" - -#include "contiki/ipv4/uip-neighbor.h" - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_IPV4 -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#include -#include -#include - -#ifdef CONFIG_DHCP -#include "contiki/ip/dhcpc.h" -#endif - -extern void net_context_set_connection_status(struct net_context *context, - int status); -void *net_context_get_internal_connection(struct net_context *context); -void net_context_set_internal_connection(struct net_context *context, - void *conn); -struct net_context *net_context_find_internal_connection(void *conn); -void net_context_tcp_set_pending(struct net_context *context, - struct net_buf *buf); - -/*---------------------------------------------------------------------------*/ -/* Variable definitions. */ - - -/* The IP address of this host. If it is defined to be fixed (by - setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set - here. Otherwise, the address */ -#if UIP_FIXEDADDR > 0 -const uip_ipaddr_t uip_hostaddr = - { UIP_IPADDR0, UIP_IPADDR1, UIP_IPADDR2, UIP_IPADDR3 }; -const uip_ipaddr_t uip_draddr = - { UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3 }; -const uip_ipaddr_t uip_netmask = - { UIP_NETMASK0, UIP_NETMASK1, UIP_NETMASK2, UIP_NETMASK3 }; -#else -uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask; -#endif /* UIP_FIXEDADDR */ - -const uip_ipaddr_t uip_broadcast_addr = -#if NETSTACK_CONF_WITH_IPV6 - { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }; -#else /* NETSTACK_CONF_WITH_IPV6 */ - { { 0xff, 0xff, 0xff, 0xff } }; -#endif /* NETSTACK_CONF_WITH_IPV6 */ -const uip_ipaddr_t uip_all_zeroes_addr = { { 0x0, /* rest is 0 */ } }; - -#if UIP_FIXEDETHADDR -const uip_lladdr_t uip_lladdr = {{UIP_ETHADDR0, - UIP_ETHADDR1, - UIP_ETHADDR2, - UIP_ETHADDR3, - UIP_ETHADDR4, - UIP_ETHADDR5}}; -#else -uip_lladdr_t uip_lladdr = {{0,0,0,0,0,0}}; -#endif - -#if 0 -/* These are moved to net_buf.h */ -/* The packet buffer that contains incoming packets. */ -uip_buf_t uip_aligned_buf; - -void *uip_appdata; /* The uip_appdata pointer points to - application data. */ -void *uip_sappdata; /* The uip_appdata pointer points to - the application data which is to - be sent. */ -#if UIP_URGDATA > 0 -void *uip_urgdata; /* The uip_urgdata pointer points to - urgent data (out-of-band data), if - present. */ -uint16_t uip_urglen, uip_surglen; -#endif /* UIP_URGDATA > 0 */ - -uint16_t uip_len, uip_slen; - /* The uip_len is either 8 or 16 bits, - depending on the maximum packet - size. */ - -uint8_t uip_flags; /* The uip_flags variable is used for - communication between the TCP/IP stack - and the application program. */ -struct uip_conn *uip_conn; /* uip_conn always points to the current - connection. */ -#endif /* 0 */ - -struct uip_conn uip_conns[UIP_CONNS]; - /* The uip_conns array holds all TCP - connections. */ -uint16_t uip_listenports[UIP_LISTENPORTS]; - /* The uip_listenports list all currently - listning ports. */ -#if UIP_UDP -#if 0 -/* Moved to net_buf */ -struct uip_udp_conn *uip_udp_conn; -#endif /* 0 */ -struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; -#endif /* UIP_UDP */ - -static uint16_t ipid; /* Ths ipid variable is an increasing - number that is used for the IP ID - field. */ - -void uip_setipid(uint16_t id) { ipid = id; } - -static uint8_t iss[4]; /* The iss variable is used for the TCP - initial sequence number. */ - -#if UIP_ACTIVE_OPEN || UIP_UDP -static uint16_t lastport; /* Keeps track of the last port used for - a new connection. */ -#endif /* UIP_ACTIVE_OPEN || UIP_UDP */ - -/* Temporary variables. */ -uint8_t uip_acc32[4]; -static uint8_t c; -#if UIP_TCP -static uint8_t opt; -static uint16_t tmp16; -#endif /* UIP_TCP */ - -/* Structures and definitions. */ -#define TCP_FIN 0x01 -#define TCP_SYN 0x02 -#define TCP_RST 0x04 -#define TCP_PSH 0x08 -#define TCP_ACK 0x10 -#define TCP_URG 0x20 -#define TCP_CTL 0x3f - -#define TCP_OPT_END 0 /* End of TCP options list */ -#define TCP_OPT_NOOP 1 /* "No-operation" TCP option */ -#define TCP_OPT_MSS 2 /* Maximum segment size TCP option */ - -#define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */ - -#define ICMP_ECHO_REPLY 0 -#define ICMP_ECHO 8 - -#define ICMP_DEST_UNREACHABLE 3 -#define ICMP_PORT_UNREACHABLE 3 - -#define ICMP6_ECHO_REPLY 129 -#define ICMP6_ECHO 128 -#define ICMP6_NEIGHBOR_SOLICITATION 135 -#define ICMP6_NEIGHBOR_ADVERTISEMENT 136 - -#define ICMP6_FLAG_S (1 << 6) - -#define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1 -#define ICMP6_OPTION_TARGET_LINK_ADDRESS 2 - - -/* Macros. */ -#define BUF(buf) ((struct uip_tcpip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) -#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0]) -#define ICMPBUF(buf) ((struct uip_icmpip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) -#define UDPBUF(buf) ((struct uip_udpip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) - - -#if UIP_STATISTICS == 1 -struct uip_stats uip_stat; -#define UIP_STAT(s) s -#else -#define UIP_STAT(s) -#endif /* UIP_STATISTICS == 1 */ - -#if UIP_LOGGING == 1 -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif /* UIP_LOGGING == 1 */ - -#if ! UIP_ARCH_ADD32 -void -uip_add32(uint8_t *op32, uint16_t op16) -{ - uip_acc32[3] = op32[3] + (op16 & 0xff); - uip_acc32[2] = op32[2] + (op16 >> 8); - uip_acc32[1] = op32[1]; - uip_acc32[0] = op32[0]; - - if(uip_acc32[2] < (op16 >> 8)) { - ++uip_acc32[1]; - if(uip_acc32[1] == 0) { - ++uip_acc32[0]; - } - } - - - if(uip_acc32[3] < (op16 & 0xff)) { - ++uip_acc32[2]; - if(uip_acc32[2] == 0) { - ++uip_acc32[1]; - if(uip_acc32[1] == 0) { - ++uip_acc32[0]; - } - } - } -} - -#endif /* UIP_ARCH_ADD32 */ - -#if ! UIP_ARCH_CHKSUM -/*---------------------------------------------------------------------------*/ -static uint16_t -chksum(uint16_t sum, const uint8_t *data, uint16_t len) -{ - uint16_t t; - const uint8_t *dataptr; - const uint8_t *last_byte; - - dataptr = data; - last_byte = data + len - 1; - - while(dataptr < last_byte) { /* At least two more bytes */ - t = (dataptr[0] << 8) + dataptr[1]; - sum += t; - if(sum < t) { - sum++; /* carry */ - } - dataptr += 2; - } - - if(dataptr == last_byte) { - t = (dataptr[0] << 8) + 0; - sum += t; - if(sum < t) { - sum++; /* carry */ - } - } - - /* Return sum in host byte order. */ - return sum; -} -/*---------------------------------------------------------------------------*/ -uint16_t -uip_chksum(uint16_t *data, uint16_t len) -{ - return uip_htons(chksum(0, (uint8_t *)data, len)); -} -/*---------------------------------------------------------------------------*/ -#ifndef UIP_ARCH_IPCHKSUM -uint16_t -uip_ipchksum(struct net_buf *buf) -{ - uint16_t sum; - - sum = chksum(0, &uip_buf(buf)[UIP_LLH_LEN], UIP_IPH_LEN); - DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum); - return (sum == 0) ? 0xffff : uip_htons(sum); -} -#endif -/*---------------------------------------------------------------------------*/ -static uint16_t -upper_layer_chksum(struct net_buf *buf, uint8_t proto) -{ - uint16_t upper_layer_len; - uint16_t sum; - -#if NETSTACK_CONF_WITH_IPV6 - upper_layer_len = (((uint16_t)(BUF->len[0]) << 8) + BUF->len[1]); -#else /* NETSTACK_CONF_WITH_IPV6 */ - upper_layer_len = (((uint16_t)(BUF(buf)->len[0]) << 8) + BUF(buf)->len[1]) - UIP_IPH_LEN; -#endif /* NETSTACK_CONF_WITH_IPV6 */ - - /* First sum pseudoheader. */ - - /* IP protocol and length fields. This addition cannot carry. */ - sum = upper_layer_len + proto; - /* Sum IP source and destination addresses. */ - sum = chksum(sum, (uint8_t *)&BUF(buf)->srcipaddr, 2 * sizeof(uip_ipaddr_t)); - - /* Sum TCP header and data. */ - sum = chksum(sum, &uip_buf(buf)[UIP_IPH_LEN + UIP_LLH_LEN], - upper_layer_len); - - return (sum == 0) ? 0xffff : uip_htons(sum); -} -/*---------------------------------------------------------------------------*/ -#if NETSTACK_CONF_WITH_IPV6 -uint16_t -uip_icmp6chksum(void) -{ - return upper_layer_chksum(UIP_PROTO_ICMP6); - -} -#endif /* NETSTACK_CONF_WITH_IPV6 */ -/*---------------------------------------------------------------------------*/ -uint16_t -uip_tcpchksum(struct net_buf *buf) -{ - return upper_layer_chksum(buf, UIP_PROTO_TCP); -} -/*---------------------------------------------------------------------------*/ -#if UIP_UDP_CHECKSUMS -uint16_t -uip_udpchksum(void) -{ - return upper_layer_chksum(UIP_PROTO_UDP); -} -#endif /* UIP_UDP_CHECKSUMS */ -#endif /* UIP_ARCH_CHKSUM */ -/*---------------------------------------------------------------------------*/ -void -uip_init(void) -{ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - uip_listenports[c] = 0; - } - for(c = 0; c < UIP_CONNS; ++c) { - uip_conns[c].tcpstateflags = UIP_CLOSED; - } -#if UIP_ACTIVE_OPEN || UIP_UDP - lastport = 1024; -#endif /* UIP_ACTIVE_OPEN || UIP_UDP */ - -#if UIP_UDP - for(c = 0; c < UIP_UDP_CONNS; ++c) { - uip_udp_conns[c].lport = 0; - } -#endif /* UIP_UDP */ - - - /* IPv4 initialization. */ -#if UIP_FIXEDADDR == 0 - /* uip_hostaddr[0] = uip_hostaddr[1] = 0;*/ -#endif /* UIP_FIXEDADDR */ - -} -/*---------------------------------------------------------------------------*/ -#if UIP_ACTIVE_OPEN -struct uip_conn * -uip_connect(const uip_ipaddr_t *ripaddr, uint16_t rport) -{ - register struct uip_conn *conn, *cconn; - - /* Find an unused local port. */ - again: - ++lastport; - - if(lastport >= 32000) { - lastport = 4096; - } - - /* Check if this port is already in use, and if so try to find - another one. */ - for(c = 0; c < UIP_CONNS; ++c) { - conn = &uip_conns[c]; - if(conn->tcpstateflags != UIP_CLOSED && - conn->lport == uip_htons(lastport)) { - goto again; - } - } - - conn = 0; - for(c = 0; c < UIP_CONNS; ++c) { - cconn = &uip_conns[c]; - if(cconn->tcpstateflags == UIP_CLOSED) { - conn = cconn; - break; - } - if(cconn->tcpstateflags == UIP_TIME_WAIT) { - if(conn == 0 || - cconn->timer > conn->timer) { - conn = cconn; - } - } - } - - if(conn == 0) { - return 0; - } - - conn->tcpstateflags = UIP_SYN_SENT; - - conn->snd_nxt[0] = iss[0]; - conn->snd_nxt[1] = iss[1]; - conn->snd_nxt[2] = iss[2]; - conn->snd_nxt[3] = iss[3]; - - conn->initialmss = conn->mss = UIP_TCP_MSS; - - conn->len = 1; /* TCP length of the SYN is one. */ - conn->nrtx = 0; - conn->timer = 1; /* Send the SYN next time around. */ - conn->rto = UIP_RTO; - conn->sa = 0; - conn->sv = 16; /* Initial value of the RTT variance. */ - conn->lport = uip_htons(lastport); - conn->rport = rport; - uip_ipaddr_copy(&conn->ripaddr, ripaddr); - - return conn; -} -#endif /* UIP_ACTIVE_OPEN */ -/*---------------------------------------------------------------------------*/ -#if UIP_UDP -struct uip_udp_conn * -uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport) -{ - register struct uip_udp_conn *conn; - - /* Find an unused local port. */ - again: - ++lastport; - - if(lastport >= 32000) { - lastport = 4096; - } - - for(c = 0; c < UIP_UDP_CONNS; ++c) { - if(uip_udp_conns[c].lport == uip_htons(lastport)) { - goto again; - } - } - - - conn = 0; - for(c = 0; c < UIP_UDP_CONNS; ++c) { - if(uip_udp_conns[c].lport == 0) { - conn = &uip_udp_conns[c]; - break; - } - } - - if(conn == 0) { - return 0; - } - - conn->lport = UIP_HTONS(lastport); - conn->rport = rport; - if(ripaddr == NULL) { - memset(&conn->ripaddr, 0, sizeof(uip_ipaddr_t)); - } else { - uip_ipaddr_copy(&conn->ripaddr, ripaddr); - } - conn->ttl = UIP_TTL; - - return conn; -} -#endif /* UIP_UDP */ -/*---------------------------------------------------------------------------*/ -void -uip_unlisten(uint16_t port) -{ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - if(uip_listenports[c] == port) { - uip_listenports[c] = 0; - return; - } - } -} -/*---------------------------------------------------------------------------*/ -void -uip_listen(uint16_t port) -{ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - if(uip_listenports[c] == 0) { - uip_listenports[c] = port; - return; - } - } -} -/*---------------------------------------------------------------------------*/ -/* XXX: IP fragment reassembly: not well-tested. */ - -#if UIP_REASSEMBLY && !NETSTACK_CONF_WITH_IPV6 -#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN) -static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE]; -static uint8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)]; -static const uint8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f, - 0x0f, 0x07, 0x03, 0x01}; -static uint16_t uip_reasslen; -static uint8_t uip_reassflags; -#define UIP_REASS_FLAG_LASTFRAG 0x01 -static uint8_t uip_reasstmr; - -#define IP_MF 0x20 - -static uint8_t -uip_reass(void) -{ - uint16_t offset, len; - uint16_t i; - - /* If ip_reasstmr is zero, no packet is present in the buffer, so we - write the IP header of the fragment into the reassembly - buffer. The timer is updated with the maximum age. */ - if(uip_reasstmr == 0) { - memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN); - uip_reasstmr = UIP_REASS_MAXAGE; - uip_reassflags = 0; - /* Clear the bitmap. */ - memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap)); - } - - /* Check if the incoming fragment matches the one currently present - in the reasembly buffer. If so, we proceed with copying the - fragment into the buffer. */ - if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] && - BUF->srcipaddr[1] == FBUF->srcipaddr[1] && - BUF->destipaddr[0] == FBUF->destipaddr[0] && - BUF->destipaddr[1] == FBUF->destipaddr[1] && - BUF->ipid[0] == FBUF->ipid[0] && - BUF->ipid[1] == FBUF->ipid[1]) { - - len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4; - offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8; - - /* If the offset or the offset + fragment length overflows the - reassembly buffer, we discard the entire packet. */ - if(offset > UIP_REASS_BUFSIZE || - offset + len > UIP_REASS_BUFSIZE) { - uip_reasstmr = 0; - goto nullreturn; - } - - /* Copy the fragment into the reassembly buffer, at the right - offset. */ - memcpy(&uip_reassbuf[UIP_IPH_LEN + offset], - (char *)BUF + (int)((BUF->vhl & 0x0f) * 4), - len); - - /* Update the bitmap. */ - if(offset / (8 * 8) == (offset + len) / (8 * 8)) { - /* If the two endpoints are in the same byte, we only update - that byte. */ - - uip_reassbitmap[offset / (8 * 8)] |= - bitmap_bits[(offset / 8 ) & 7] & - ~bitmap_bits[((offset + len) / 8 ) & 7]; - } else { - /* If the two endpoints are in different bytes, we update the - bytes in the endpoints and fill the stuff inbetween with - 0xff. */ - uip_reassbitmap[offset / (8 * 8)] |= - bitmap_bits[(offset / 8 ) & 7]; - for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) { - uip_reassbitmap[i] = 0xff; - } - uip_reassbitmap[(offset + len) / (8 * 8)] |= - ~bitmap_bits[((offset + len) / 8 ) & 7]; - } - - /* If this fragment has the More Fragments flag set to zero, we - know that this is the last fragment, so we can calculate the - size of the entire packet. We also set the - IP_REASS_FLAG_LASTFRAG flag to indicate that we have received - the final fragment. */ - - if((BUF->ipoffset[0] & IP_MF) == 0) { - uip_reassflags |= UIP_REASS_FLAG_LASTFRAG; - uip_reasslen = offset + len; - } - - /* Finally, we check if we have a full packet in the buffer. We do - this by checking if we have the last fragment and if all bits - in the bitmap are set. */ - if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) { - /* Check all bytes up to and including all but the last byte in - the bitmap. */ - for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) { - if(uip_reassbitmap[i] != 0xff) { - goto nullreturn; - } - } - /* Check the last byte in the bitmap. It should contain just the - right amount of bits. */ - if(uip_reassbitmap[uip_reasslen / (8 * 8)] != - (uint8_t)~bitmap_bits[uip_reasslen / 8 & 7]) { - goto nullreturn; - } - - /* If we have come this far, we have a full packet in the - buffer, so we allocate a pbuf and copy the packet into it. We - also reset the timer. */ - uip_reasstmr = 0; - memcpy(BUF, FBUF, uip_reasslen); - - /* Pretend to be a "normal" (i.e., not fragmented) IP packet - from now on. */ - BUF->ipoffset[0] = BUF->ipoffset[1] = 0; - BUF->len[0] = uip_reasslen >> 8; - BUF->len[1] = uip_reasslen & 0xff; - BUF->ipchksum = 0; - BUF->ipchksum = ~(uip_ipchksum()); - - return uip_reasslen; - } - } - - nullreturn: - return 0; -} -#endif /* UIP_REASSEMBLY */ -/*---------------------------------------------------------------------------*/ -#if UIP_TCP -static void -uip_add_rcv_nxt(struct net_buf *buf, uint16_t n) -{ - uip_add32(uip_conn(buf)->rcv_nxt, n); - uip_conn(buf)->rcv_nxt[0] = uip_acc32[0]; - uip_conn(buf)->rcv_nxt[1] = uip_acc32[1]; - uip_conn(buf)->rcv_nxt[2] = uip_acc32[2]; - uip_conn(buf)->rcv_nxt[3] = uip_acc32[3]; -} -#endif /* UIP_TCP */ - -#if UIP_TCP -static inline void handle_tcp_retransmit_timer(struct net_buf *not_used, - void *ptr) -{ - struct uip_conn *conn = ptr; - - PRINTF("%s: connection %p buf %p\n", __func__, conn, conn ? conn->buf : 0); - if (conn && conn->buf) { - conn->timer = 0; - if (uip_process(&conn->buf, UIP_TIMER)) { - tcpip_resend_syn(conn, conn->buf); - } - } -} - -static inline void tcp_set_retrans_timer(struct uip_conn *conn) -{ - ctimer_set(NULL, &conn->retransmit_timer, CLOCK_SECOND, - &handle_tcp_retransmit_timer, conn); -} - -static inline void tcp_cancel_retrans_timer(struct uip_conn *conn) -{ - ctimer_stop(&conn->retransmit_timer); -} -#endif /* UIP_TCP */ -/*---------------------------------------------------------------------------*/ -uint8_t -uip_process(struct net_buf **buf_out, uint8_t flag) -{ - struct net_buf *buf = *buf_out; -#if UIP_TCP - register struct uip_conn *uip_connr = uip_conn(buf); -#endif - -#if UIP_UDP - int i; - if(flag == UIP_UDP_SEND_CONN) { - goto udp_send; - } -#endif /* UIP_UDP */ -#if UIP_TCP - if(flag != UIP_TCP_SEND_CONN) { -#endif - uip_sappdata(buf) = uip_appdata(buf) = &uip_buf(buf)[UIP_IPTCPH_LEN + UIP_LLH_LEN]; -#if UIP_TCP - } -#endif - /* Check if we were invoked because of a poll request for a - particular connection. */ -#if UIP_TCP - if(flag == UIP_POLL_REQUEST || flag == UIP_TCP_SEND_CONN) { - - /* If the connection is not found, and we are initiating the - * connection, try to get it. - */ - if (!uip_connr) { - uip_connr = net_context_get_internal_connection(ip_buf_context(buf)); - if (!uip_connr) { - PRINTF("No matching connection found for buf %p\n", buf); - ip_buf_sent_status(buf) = -ENOTCONN; - return 0; - } else { - uip_set_conn(buf) = uip_connr; - PRINTF("Using connection %p for buf %p\n", uip_conn(buf), buf); - } - } - - if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED && - !uip_outstanding(uip_connr)) { - if (flag == UIP_POLL) { - uip_flags(buf) = UIP_POLL; - } - UIP_APPCALL(buf); - goto appsend; -#if UIP_ACTIVE_OPEN - } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) { - if (uip_connr->nrtx > UIP_MAXSYNRTX) { - /* SYN has been sent too many times, just stop the connection. - */ - PRINTF("Too many SYN sent, dropping connection %p\n", uip_connr); - net_context_set_connection_status(ip_buf_context(buf), -ETIMEDOUT); - goto drop; - } - - /* In the SYN_SENT state, we retransmit out SYN. */ - BUF(buf)->flags = 0; - goto tcp_send_syn; -#endif /* UIP_ACTIVE_OPEN */ - } - if (flag == UIP_TCP_SEND_CONN) { - switch (uip_connr->tcpstateflags & UIP_TS_MASK) { - case UIP_CLOSED: - case UIP_FIN_WAIT_1: - case UIP_FIN_WAIT_2: - case UIP_CLOSING: - case UIP_TIME_WAIT: - ip_buf_sent_status(buf) = -ECONNABORTED; - goto drop; - } - if (uip_outstanding(uip_connr)) { - ip_buf_sent_status(buf) = -EAGAIN; - PRINTF("Retry to send packet len %d, outstanding data len %d, " - "conn %p\n", uip_len(buf), uip_outstanding(uip_connr), - uip_connr); - flag = UIP_TIMER; - goto tcp_retry; - } - } - goto drop; - } -#else /* TCP */ - if(flag == UIP_POLL_REQUEST) { - goto drop; - } -#endif /* UIP_TCP */ - - /* Check if we were invoked because of the periodic timer firing. */ - if(flag == UIP_TIMER) { -#if UIP_REASSEMBLY - if(uip_reasstmr != 0) { - --uip_reasstmr; - } -#endif /* UIP_REASSEMBLY */ - -#if UIP_TCP - /* Increase the initial sequence number. */ - if(++iss[3] == 0) { - if(++iss[2] == 0) { - if(++iss[1] == 0) { - ++iss[0]; - } - } - } - - /* Reset the length variables. */ - uip_len(buf) = 0; - uip_slen(buf) = 0; - tcp_retry: - /* Check if the connection is in a state in which we simply wait - for the connection to time out. If so, we increase the - connection's timer and remove the connection if it times - out. */ - if(uip_connr->tcpstateflags == UIP_TIME_WAIT || - uip_connr->tcpstateflags == UIP_FIN_WAIT_2) { - ++(uip_connr->timer); - if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) { - uip_connr->tcpstateflags = UIP_CLOSED; - } - } else if(uip_connr->tcpstateflags != UIP_CLOSED) { - if (!uip_connr->buf) { - /* There cannot be any data pending if buf is NULL */ - uip_outstanding(uip_connr) = 0; - } - - /* If the connection has outstanding data, we increase the - connection's timer and see if it has reached the RTO value - in which case we retransmit. */ - - if(uip_outstanding(uip_connr)) { - if(uip_connr->timer-- == 0) { - if(uip_connr->nrtx == UIP_MAXRTX || - ((uip_connr->tcpstateflags == UIP_SYN_SENT || - uip_connr->tcpstateflags == UIP_SYN_RCVD) && - uip_connr->nrtx == UIP_MAXSYNRTX)) { - uip_connr->tcpstateflags = UIP_CLOSED; - - /* We call UIP_APPCALL() with uip_flags set to - UIP_TIMEDOUT to inform the application that the - connection has timed out. */ - uip_flags(buf) = UIP_TIMEDOUT; - UIP_APPCALL(buf); - - /* We also send a reset packet to the remote host. */ - BUF(buf)->flags = TCP_RST | TCP_ACK; - goto tcp_send_nodata; - } - - /* Exponential backoff. */ - uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4? - 4: - uip_connr->nrtx); - ++(uip_connr->nrtx); - - /* Ok, so we need to retransmit. We do this differently - depending on which state we are in. In ESTABLISHED, we - call upon the application so that it may prepare the - data for the retransmit. In SYN_RCVD, we resend the - SYNACK that we sent earlier and in LAST_ACK we have to - retransmit our FINACK. */ - UIP_STAT(++uip_stat.tcp.rexmit); - switch(uip_connr->tcpstateflags & UIP_TS_MASK) { - case UIP_SYN_RCVD: - /* In the SYN_RCVD state, we should retransmit our - SYNACK. */ - goto tcp_send_synack; - -#if UIP_ACTIVE_OPEN - case UIP_SYN_SENT: - /* In the SYN_SENT state, we retransmit out SYN. */ - BUF(buf)->flags = 0; - goto tcp_send_syn; -#endif /* UIP_ACTIVE_OPEN */ - - case UIP_ESTABLISHED: - /* In the ESTABLISHED state, we call upon the application - to do the actual retransmit after which we jump into - the code for sending out the packet (the apprexmit - label). */ - uip_flags(buf) = UIP_REXMIT; - UIP_APPCALL(buf); - goto apprexmit; - - case UIP_FIN_WAIT_1: - case UIP_CLOSING: - case UIP_LAST_ACK: - /* In all these states we should retransmit a FINACK. */ - goto tcp_send_finack; - - } - } - } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) { - /* If there was no need for a retransmission, we poll the - application for new data. */ - uip_flags(buf) = UIP_POLL; - UIP_APPCALL(buf); - goto appsend; - } - } -#endif - goto drop; - } -#if UIP_UDP - if(flag == UIP_UDP_TIMER) { - if(uip_udp_conn(buf)->lport != 0) { - uip_set_conn(buf) = NULL; - uip_sappdata(buf) = uip_appdata(buf) = &uip_buf(buf)[UIP_LLH_LEN + UIP_IPUDPH_LEN]; - uip_len(buf) = uip_slen(buf) = 0; - uip_flags(buf) = UIP_POLL; - UIP_UDP_APPCALL(buf); - goto udp_send; - } else { - goto drop; - } - } -#endif - - /* This is where the input processing starts. */ - UIP_STAT(++uip_stat.ip.recv); - - /* Start of IP input header processing code. */ - -#if NETSTACK_CONF_WITH_IPV6 - /* Check validity of the IP header. */ - if((BUF(buf)->vtc & 0xf0) != 0x60) { /* IP version and header length. */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.vhlerr); - UIP_LOG("ipv6: invalid version."); - goto drop; - } -#else /* NETSTACK_CONF_WITH_IPV6 */ - /* Check validity of the IP header. */ - if(BUF(buf)->vhl != 0x45) { /* IP version and header length. */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.vhlerr); - UIP_LOG("ip: invalid version or header length."); - goto drop; - } -#endif /* NETSTACK_CONF_WITH_IPV6 */ - - /* Check the size of the packet. If the size reported to us in - uip_len is smaller the size reported in the IP header, we assume - that the packet has been corrupted in transit. If the size of - uip_len is larger than the size reported in the IP packet header, - the packet has been padded and we set uip_len to the correct - value. */ - - if((BUF(buf)->len[0] << 8) + BUF(buf)->len[1] <= uip_len(buf)) { - uip_len(buf) = (BUF(buf)->len[0] << 8) + BUF(buf)->len[1]; -#if NETSTACK_CONF_WITH_IPV6 - uip_len += 40; /* The length reported in the IPv6 header is the - length of the payload that follows the - header. However, uIP uses the uip_len variable - for holding the size of the entire packet, - including the IP header. For IPv4 this is not a - problem as the length field in the IPv4 header - contains the length of the entire packet. But - for IPv6 we need to add the size of the IPv6 - header (40 bytes). */ -#endif /* NETSTACK_CONF_WITH_IPV6 */ - } else { - UIP_LOG("ip: packet shorter than reported in IP header."); - goto drop; - } - -#if !NETSTACK_CONF_WITH_IPV6 - /* Check the fragment flag. */ - if((BUF(buf)->ipoffset[0] & 0x3f) != 0 || - BUF(buf)->ipoffset[1] != 0) { -#if UIP_REASSEMBLY - uip_len = uip_reass(); - if(uip_len == 0) { - goto drop; - } -#else /* UIP_REASSEMBLY */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.fragerr); - UIP_LOG("ip: fragment dropped."); - goto drop; -#endif /* UIP_REASSEMBLY */ - } -#endif /* NETSTACK_CONF_WITH_IPV6 */ - - if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) { - /* If we are configured to use ping IP address configuration and - haven't been assigned an IP address yet, we accept all ICMP - packets. */ -#if UIP_PINGADDRCONF && !NETSTACK_CONF_WITH_IPV6 - if(BUF->proto == UIP_PROTO_ICMP) { - UIP_LOG("ip: possible ping config packet received."); - goto icmp_input; - } else { - UIP_LOG("ip: packet dropped since no address assigned."); - goto drop; - } -#endif /* UIP_PINGADDRCONF */ - - } else { - /* If IP broadcast support is configured, we check for a broadcast - UDP packet, which may be destined to us. */ -#if UIP_BROADCAST - DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum()); - if(BUF->proto == UIP_PROTO_UDP && - (uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr) || - (BUF->destipaddr.u8[0] & 224) == 224)) { /* XXX this is a - hack to be able - to receive UDP - multicast - packets. We check - for the bit - pattern of the - multicast - prefix. */ - goto udp_input; - } -#endif /* UIP_BROADCAST */ - - /* Check if the packet is destined for our IP address. */ -#if !NETSTACK_CONF_WITH_IPV6 -#ifdef CONFIG_DHCP - /* DHCP message destination address in DHCP OFFER and ACK - * packets, destination address is 255.255.255.255, so skip - * addres comparison in this case - */ - if(BUF(buf)->proto == UIP_PROTO_UDP) { - uip_appdata(buf) = &uip_buf(buf)[UIP_LLH_LEN + UIP_IPUDPH_LEN]; - } - - if(msg_for_dhcpc(buf)) { - if(!(uip_ipaddr_cmp(&BUF(buf)->destipaddr, &uip_hostaddr) || - uip_ipaddr_cmp(&BUF(buf)->destipaddr, &uip_broadcast_addr))) { - UIP_STAT(++uip_stat.ip.drop); - goto drop; - } - } else -#endif - if(!uip_ipaddr_cmp(&BUF(buf)->destipaddr, &uip_hostaddr)) { - UIP_STAT(++uip_stat.ip.drop); - goto drop; - } -#else /* NETSTACK_CONF_WITH_IPV6 */ - /* For IPv6, packet reception is a little trickier as we need to - make sure that we listen to certain multicast addresses (all - hosts multicast address, and the solicited-node multicast - address) as well. However, we will cheat here and accept all - multicast packets that are sent to the ff02::/16 addresses. */ - if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr) && - BUF->destipaddr.u16[0] != UIP_HTONS(0xff02)) { - UIP_STAT(++uip_stat.ip.drop); - goto drop; - } -#endif /* NETSTACK_CONF_WITH_IPV6 */ - } - -#if !NETSTACK_CONF_WITH_IPV6 - if(uip_ipchksum(buf) != 0xffff) { /* Compute and check the IP header - checksum. */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.chkerr); - UIP_LOG("ip: bad checksum."); - goto drop; - } -#endif /* NETSTACK_CONF_WITH_IPV6 */ - -#if UIP_TCP - if(BUF(buf)->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so, - proceed with TCP input - processing. */ - goto tcp_input; - } -#endif - -#if UIP_UDP - if(BUF(buf)->proto == UIP_PROTO_UDP) { - goto udp_input; - } -#endif /* UIP_UDP */ - -#if !NETSTACK_CONF_WITH_IPV6 - /* ICMPv4 processing code follows. */ - if(BUF(buf)->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from - here. */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.protoerr); - UIP_LOG("ip: neither tcp nor icmp."); - goto drop; - } - -#if UIP_PINGADDRCONF - icmp_input: -#endif /* UIP_PINGADDRCONF */ - UIP_STAT(++uip_stat.icmp.recv); - - /* ICMP echo (i.e., ping) processing. This is simple, we only change - the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP - checksum before we return the packet. */ - if(ICMPBUF(buf)->type != ICMP_ECHO) { - UIP_STAT(++uip_stat.icmp.drop); - UIP_STAT(++uip_stat.icmp.typeerr); - UIP_LOG("icmp: not icmp echo."); - goto drop; - } - - /* If we are configured to use ping IP address assignment, we use - the destination IP address of this ping packet and assign it to - ourself. */ -#if UIP_PINGADDRCONF - if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) { - uip_hostaddr = BUF->destipaddr; - } -#endif /* UIP_PINGADDRCONF */ - - ICMPBUF(buf)->type = ICMP_ECHO_REPLY; - - if(ICMPBUF(buf)->icmpchksum >= UIP_HTONS(0xffff - (ICMP_ECHO << 8))) { - ICMPBUF(buf)->icmpchksum += UIP_HTONS(ICMP_ECHO << 8) + 1; - } else { - ICMPBUF(buf)->icmpchksum += UIP_HTONS(ICMP_ECHO << 8); - } - - /* Swap IP addresses. */ - uip_ipaddr_copy(&BUF(buf)->destipaddr, &BUF(buf)->srcipaddr); - uip_ipaddr_copy(&BUF(buf)->srcipaddr, &uip_hostaddr); - - UIP_STAT(++uip_stat.icmp.sent); - BUF(buf)->ttl = UIP_TTL; - goto ip_send_nolen; - - /* End of IPv4 input header processing code. */ -#else /* !NETSTACK_CONF_WITH_IPV6 */ - - /* This is IPv6 ICMPv6 processing code. */ - DEBUG_PRINTF("icmp6_input: length %d\n", uip_len); - - if(BUF->proto != UIP_PROTO_ICMP6) { /* We only allow ICMPv6 packets from - here. */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.protoerr); - UIP_LOG("ip: neither tcp nor icmp6."); - goto drop; - } - - UIP_STAT(++uip_stat.icmp.recv); - - /* If we get a neighbor solicitation for our address we should send - a neighbor advertisement message back. */ - if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) { - if(uip_ipaddr_cmp(&ICMPBUF->icmp6data, &uip_hostaddr)) { - - if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) { - /* Save the sender's address in our neighbor list. */ - uip_neighbor_add(&ICMPBUF->srcipaddr, &(ICMPBUF->options[2])); - } - - /* We should now send a neighbor advertisement back to where the - neighbor solicication came from. */ - ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT; - ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */ - - ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0; - - uip_ipaddr_copy(&ICMPBUF->destipaddr, &ICMPBUF->srcipaddr); - uip_ipaddr_copy(&ICMPBUF->srcipaddr, &uip_hostaddr); - ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS; - ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */ - memcpy(&(ICMPBUF->options[2]), &uip_lladdr, sizeof(uip_lladdr)); - ICMPBUF->icmpchksum = 0; - ICMPBUF->icmpchksum = ~uip_icmp6chksum(); - - goto send; - - } - goto drop; - } else if(ICMPBUF->type == ICMP6_ECHO) { - /* ICMP echo (i.e., ping) processing. This is simple, we only - change the ICMP type from ECHO to ECHO_REPLY and update the - ICMP checksum before we return the packet. */ - - ICMPBUF->type = ICMP6_ECHO_REPLY; - - uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr); - uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr); - ICMPBUF->icmpchksum = 0; - ICMPBUF->icmpchksum = ~uip_icmp6chksum(); - - UIP_STAT(++uip_stat.icmp.sent); - goto send; - } else { - DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type); - UIP_STAT(++uip_stat.icmp.drop); - UIP_STAT(++uip_stat.icmp.typeerr); - UIP_LOG("icmp: unknown ICMP message."); - goto drop; - } - - /* End of IPv6 ICMP processing. */ - -#endif /* !NETSTACK_CONF_WITH_IPV6 */ - -#if UIP_UDP - /* UDP input processing. */ - udp_input: - /* UDP processing is really just a hack. We don't do anything to the - UDP/IP headers, but let the UDP application do all the hard - work. If the application sets uip_slen, it has a packet to - send. */ -#if UIP_UDP_CHECKSUMS - uip_len = uip_len - UIP_IPUDPH_LEN; - uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; - if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) { - UIP_STAT(++uip_stat.udp.drop); - UIP_STAT(++uip_stat.udp.chkerr); - UIP_LOG("udp: bad checksum."); - goto drop; - } -#else /* UIP_UDP_CHECKSUMS */ - uip_len(buf) = uip_len(buf) - UIP_IPUDPH_LEN; -#endif /* UIP_UDP_CHECKSUMS */ - - /* Make sure that the UDP destination port number is not zero. */ - if(UDPBUF(buf)->destport == 0) { - UIP_LOG("udp: zero port."); - goto drop; - } - - /* Demultiplex this UDP packet between the UDP "connections". */ - for(i = 0, uip_set_udp_conn(buf) = &uip_udp_conns[0]; - i < UIP_UDP_CONNS && uip_udp_conn(buf) < &uip_udp_conns[UIP_UDP_CONNS]; - i++, uip_set_udp_conn(buf) += sizeof(struct uip_udp_conn)) { - /* If the local UDP port is non-zero, the connection is considered - to be used. If so, the local port number is checked against the - destination port number in the received packet. If the two port - numbers match, the remote port number is checked if the - connection is bound to a remote port. Finally, if the - connection is bound to a remote IP address, the source IP - address of the packet is checked. */ - if(uip_udp_conn(buf)->lport != 0 && - UDPBUF(buf)->destport == uip_udp_conn(buf)->lport && - (uip_udp_conn(buf)->rport == 0 || - UDPBUF(buf)->srcport == uip_udp_conn(buf)->rport) && - (uip_ipaddr_cmp(&uip_udp_conn(buf)->ripaddr, &uip_all_zeroes_addr) || - uip_ipaddr_cmp(&uip_udp_conn(buf)->ripaddr, &uip_broadcast_addr) || - uip_ipaddr_cmp(&BUF(buf)->srcipaddr, &uip_udp_conn(buf)->ripaddr))) { - goto udp_found; - } - } - UIP_LOG("udp: no matching connection found"); - UIP_STAT(++uip_stat.udp.drop); -#if UIP_CONF_ICMP_DEST_UNREACH && !NETSTACK_CONF_WITH_IPV6 - /* Copy fields from packet header into payload of this ICMP packet. */ - memcpy(&(ICMPBUF->payload[0]), ICMPBUF, UIP_IPH_LEN + 8); - - /* Set the ICMP type and code. */ - ICMPBUF->type = ICMP_DEST_UNREACHABLE; - ICMPBUF->icode = ICMP_PORT_UNREACHABLE; - - /* Calculate the ICMP checksum. */ - ICMPBUF->icmpchksum = 0; - ICMPBUF->icmpchksum = ~uip_chksum((uint16_t *)&(ICMPBUF->type), 36); - - /* Set the IP destination address to be the source address of the - original packet. */ - uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr); - - /* Set our IP address as the source address. */ - uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr); - - /* The size of the ICMP destination unreachable packet is 36 + the - size of the IP header (20) = 56. */ - uip_len = 36 + UIP_IPH_LEN; - ICMPBUF->len[0] = 0; - ICMPBUF->len[1] = (uint8_t)uip_len; - ICMPBUF->ttl = UIP_TTL; - ICMPBUF->proto = UIP_PROTO_ICMP; - - goto ip_send_nolen; -#else /* UIP_CONF_ICMP_DEST_UNREACH */ - goto drop; -#endif /* UIP_CONF_ICMP_DEST_UNREACH */ - - udp_found: - PRINTF("In udp_found\n"); - UIP_STAT(++uip_stat.udp.recv); - uip_set_conn(buf) = NULL; - uip_flags(buf) = UIP_NEWDATA; - uip_sappdata(buf) = uip_appdata(buf) = &uip_buf(buf)[UIP_LLH_LEN + UIP_IPUDPH_LEN]; - uip_slen(buf) = 0; - UIP_UDP_APPCALL(buf); - if(uip_slen(buf) == 0) { - /* If the application does not want to send anything, then uip_slen(buf) - * will be 0. In this case we MUST NOT set uip_len(buf) to 0 as that would - * cause the net_buf to be released by rx fiber. In this case it is - * application responsibility to release the buffer. - */ - return 0; - } - - udp_send: - PRINTF("In udp_send\n"); - if(uip_slen(buf) == 0) { - goto drop; - } - uip_len(buf) = uip_slen(buf) + UIP_IPUDPH_LEN; - ip_buf_len(buf) = uip_len(buf); - -#if NETSTACK_CONF_WITH_IPV6 - /* For IPv6, the IP length field does not include the IPv6 IP header - length. */ - BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); - BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); -#else /* NETSTACK_CONF_WITH_IPV6 */ - BUF(buf)->len[0] = (uip_len(buf) >> 8); - BUF(buf)->len[1] = (uip_len(buf) & 0xff); -#endif /* NETSTACK_CONF_WITH_IPV6 */ - - BUF(buf)->ttl = uip_udp_conn(buf)->ttl; - BUF(buf)->proto = UIP_PROTO_UDP; - - UDPBUF(buf)->udplen = UIP_HTONS(uip_slen(buf) + UIP_UDPH_LEN); - UDPBUF(buf)->udpchksum = 0; - - BUF(buf)->srcport = uip_udp_conn(buf)->lport; - BUF(buf)->destport = uip_udp_conn(buf)->rport; - - uip_ipaddr_copy(&BUF(buf)->srcipaddr, &uip_hostaddr); - uip_ipaddr_copy(&BUF(buf)->destipaddr, &uip_udp_conn(buf)->ripaddr); - - uip_appdata(buf) = &uip_buf(buf)[UIP_LLH_LEN + UIP_IPTCPH_LEN]; - -#if UIP_UDP_CHECKSUMS - /* Calculate UDP checksum. */ - UDPBUF->udpchksum = ~(uip_udpchksum()); - if(UDPBUF->udpchksum == 0) { - UDPBUF->udpchksum = 0xffff; - } -#endif /* UIP_UDP_CHECKSUMS */ - - UIP_STAT(++uip_stat.udp.sent); - goto ip_send_nolen; -#endif /* UIP_UDP */ - - /* TCP input processing. */ -#if UIP_TCP - tcp_input: - UIP_STAT(++uip_stat.tcp.recv); - - /* Start of TCP input header processing code. */ - - if(uip_tcpchksum(buf) != 0xffff) { /* Compute and check the TCP - checksum. */ - UIP_STAT(++uip_stat.tcp.drop); - UIP_STAT(++uip_stat.tcp.chkerr); - UIP_LOG("tcp: bad checksum."); - goto drop; - } - - /* Make sure that the TCP port number is not zero. */ - if(BUF(buf)->destport == 0 || BUF(buf)->srcport == 0) { - UIP_LOG("tcp: zero port."); - goto drop; - } - - /* Demultiplex this segment. */ - /* First check any active connections. */ - for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1]; - ++uip_connr) { - if(uip_connr->tcpstateflags != UIP_CLOSED && - BUF(buf)->destport == uip_connr->lport && - BUF(buf)->srcport == uip_connr->rport && - uip_ipaddr_cmp(&BUF(buf)->srcipaddr, &uip_connr->ripaddr)) { - goto found; - } - } - - /* If we didn't find an active connection that expected the packet, - either this packet is an old duplicate, or this is a SYN packet - destined for a connection in LISTEN. If the SYN flag isn't set, - it is an old packet and we send a RST. */ - if((BUF(buf)->flags & TCP_CTL) != TCP_SYN) { - goto reset; - } - - tmp16 = BUF(buf)->destport; - /* Next, check listening connections. */ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - if(tmp16 == uip_listenports[c]) { - goto found_listen; - } - } - - /* No matching connection found, so we send a RST packet. */ - UIP_STAT(++uip_stat.tcp.synrst); - - reset: - /* We do not send resets in response to resets. */ - if(BUF(buf)->flags & TCP_RST) { - goto drop; - } - - UIP_STAT(++uip_stat.tcp.rst); - - BUF(buf)->flags = TCP_RST | TCP_ACK; - uip_len(buf) = UIP_IPTCPH_LEN; - BUF(buf)->tcpoffset = 5 << 4; - - /* Flip the seqno and ackno fields in the TCP header. */ - c = BUF(buf)->seqno[3]; - BUF(buf)->seqno[3] = BUF(buf)->ackno[3]; - BUF(buf)->ackno[3] = c; - - c = BUF(buf)->seqno[2]; - BUF(buf)->seqno[2] = BUF(buf)->ackno[2]; - BUF(buf)->ackno[2] = c; - - c = BUF(buf)->seqno[1]; - BUF(buf)->seqno[1] = BUF(buf)->ackno[1]; - BUF(buf)->ackno[1] = c; - - c = BUF(buf)->seqno[0]; - BUF(buf)->seqno[0] = BUF(buf)->ackno[0]; - BUF(buf)->ackno[0] = c; - - /* We also have to increase the sequence number we are - acknowledging. If the least significant byte overflowed, we need - to propagate the carry to the other bytes as well. */ - if(++BUF(buf)->ackno[3] == 0) { - if(++BUF(buf)->ackno[2] == 0) { - if(++BUF(buf)->ackno[1] == 0) { - ++BUF(buf)->ackno[0]; - } - } - } - - /* Swap port numbers. */ - tmp16 = BUF(buf)->srcport; - BUF(buf)->srcport = BUF(buf)->destport; - BUF(buf)->destport = tmp16; - - /* Swap IP addresses. */ - uip_ipaddr_copy(&BUF(buf)->destipaddr, &BUF(buf)->srcipaddr); - uip_ipaddr_copy(&BUF(buf)->srcipaddr, &uip_hostaddr); - - /* And send out the RST packet! */ - goto tcp_send_noconn; - - /* This label will be jumped to if we matched the incoming packet - with a connection in LISTEN. In that case, we should create a new - connection and send a SYNACK in return. */ - found_listen: - PRINTF("In found listen\n"); - /* First we check if there are any connections avaliable. Unused - connections are kept in the same table as used connections, but - unused ones have the tcpstate set to CLOSED. Also, connections in - TIME_WAIT are kept track of and we'll use the oldest one if no - CLOSED connections are found. Thanks to Eddie C. Dost for a very - nice algorithm for the TIME_WAIT search. */ - uip_connr = 0; - for(c = 0; c < UIP_CONNS; ++c) { - if(uip_conns[c].tcpstateflags == UIP_CLOSED) { - uip_connr = &uip_conns[c]; - break; - } - if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) { - if(uip_connr == 0 || - uip_conns[c].timer > uip_connr->timer) { - uip_connr = &uip_conns[c]; - } - } - } - - if(uip_connr == 0) { - /* All connections are used already, we drop packet and hope that - the remote end will retransmit the packet at a time when we - have more spare connections. */ - UIP_STAT(++uip_stat.tcp.syndrop); - UIP_LOG("tcp: found no unused connections."); - goto drop; - } - uip_set_conn(buf) = uip_connr; - - /* Fill in the necessary fields for the new connection. */ - uip_connr->rto = uip_connr->timer = UIP_RTO; - uip_connr->sa = 0; - uip_connr->sv = 4; - uip_connr->nrtx = 0; - uip_connr->lport = BUF(buf)->destport; - uip_connr->rport = BUF(buf)->srcport; - uip_ipaddr_copy(&uip_connr->ripaddr, &BUF(buf)->srcipaddr); - uip_connr->tcpstateflags = UIP_SYN_RCVD; - - uip_connr->snd_nxt[0] = iss[0]; - uip_connr->snd_nxt[1] = iss[1]; - uip_connr->snd_nxt[2] = iss[2]; - uip_connr->snd_nxt[3] = iss[3]; - uip_connr->len = 1; - - if (flag == UIP_TCP_SEND_CONN) { - /* So we are trying send some data to other host */ - if (uip_connr->buf && uip_connr->buf != buf) { - uip_connr->buf = ip_buf_ref(buf); - } - } - - /* rcv_nxt should be the seqno from the incoming packet + 1. */ - uip_connr->rcv_nxt[3] = BUF(buf)->seqno[3]; - uip_connr->rcv_nxt[2] = BUF(buf)->seqno[2]; - uip_connr->rcv_nxt[1] = BUF(buf)->seqno[1]; - uip_connr->rcv_nxt[0] = BUF(buf)->seqno[0]; - uip_add_rcv_nxt(buf, 1); - - /* Parse the TCP MSS option, if present. */ - if((BUF(buf)->tcpoffset & 0xf0) > 0x50) { - for(c = 0; c < ((BUF(buf)->tcpoffset >> 4) - 5) << 2 ;) { - opt = uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + c]; - if(opt == TCP_OPT_END) { - /* End of options. */ - break; - } else if(opt == TCP_OPT_NOOP) { - ++c; - /* NOP option. */ - } else if(opt == TCP_OPT_MSS && - uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { - /* An MSS option with the right option length. */ - tmp16 = ((uint16_t)uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | - (uint16_t)uip_buf(buf)[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c]; - uip_connr->initialmss = uip_connr->mss = - tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; - - /* And we are done processing options. */ - break; - } else { - /* All other options have a length field, so that we easily - can skip past them. */ - if(uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { - /* If the length field is zero, the options are malformed - and we don't process them further. */ - break; - } - c += uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; - } - } - } - - /* Our response will be a SYNACK. */ -#if UIP_ACTIVE_OPEN - tcp_send_synack: - BUF(buf)->flags = TCP_ACK; - - tcp_send_syn: - BUF(buf)->flags |= TCP_SYN; - tcp_set_retrans_timer(uip_connr); -#else /* UIP_ACTIVE_OPEN */ - tcp_send_synack: - BUF(buf)->flags = TCP_SYN | TCP_ACK; -#endif /* UIP_ACTIVE_OPEN */ - - /* We send out the TCP Maximum Segment Size option with our - SYNACK. */ - BUF(buf)->optdata[0] = TCP_OPT_MSS; - BUF(buf)->optdata[1] = TCP_OPT_MSS_LEN; - BUF(buf)->optdata[2] = (UIP_TCP_MSS) / 256; - BUF(buf)->optdata[3] = (UIP_TCP_MSS) & 255; - uip_len(buf) = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN; - BUF(buf)->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4; - goto tcp_send; - - /* This label will be jumped to if we found an active connection. */ - found: - PRINTF("In found\n"); - uip_set_conn(buf) = uip_connr; - uip_flags(buf) = 0; - /* We do a very naive form of TCP reset processing; we just accept - any RST and kill our connection. We should in fact check if the - sequence number of this reset is within our advertised window - before we accept the reset. */ - if(BUF(buf)->flags & TCP_RST) { - uip_connr->tcpstateflags = UIP_CLOSED; - UIP_LOG("tcp: got reset, aborting connection."); - uip_flags(buf) = UIP_ABORT; - UIP_APPCALL(buf); - goto drop; - } - - if (flag != UIP_TCP_SEND_CONN) { - /* If flag is set to UIP_TCP_SEND_CONN, then it means that we are - * trying to send the actual packet coming from user. In this case - * do not mess with the packet length. - */ - - /* Calculate the length of the data, if the application has sent - any data to us. */ - c = (BUF(buf)->tcpoffset >> 4) << 2; - /* uip_len will contain the length of the actual TCP data. This is - calculated by subtracing the length of the TCP header (in - c) and the length of the IP header (20 bytes). */ - uip_len(buf) = uip_len(buf) - c - UIP_IPH_LEN; - } - - /* First, check if the sequence number of the incoming packet is - what we're expecting next. If not, we send out an ACK with the - correct numbers in, unless we are in the SYN_RCVD state and - receive a SYN, in which case we should retransmit our SYNACK - (which is done futher down). */ - if(!((((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && - ((BUF(buf)->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) || - (((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) && - ((BUF(buf)->flags & TCP_CTL) == TCP_SYN)))) { - if((uip_len(buf) > 0 || ((BUF(buf)->flags & (TCP_SYN | TCP_FIN)) != 0)) && - (BUF(buf)->seqno[0] != uip_connr->rcv_nxt[0] || - BUF(buf)->seqno[1] != uip_connr->rcv_nxt[1] || - BUF(buf)->seqno[2] != uip_connr->rcv_nxt[2] || - BUF(buf)->seqno[3] != uip_connr->rcv_nxt[3])) { - goto tcp_send_ack; - } - } - - /* Next, check if the incoming segment acknowledges any outstanding - data. If so, we update the sequence number, reset the length of - the outstanding data, calculate RTT estimations, and reset the - retransmission timer. */ - if((BUF(buf)->flags & TCP_ACK) && uip_outstanding(uip_connr)) { - uip_add32(uip_connr->snd_nxt, uip_connr->len); - - if(BUF(buf)->ackno[0] == uip_acc32[0] && - BUF(buf)->ackno[1] == uip_acc32[1] && - BUF(buf)->ackno[2] == uip_acc32[2] && - BUF(buf)->ackno[3] == uip_acc32[3]) { - /* Update sequence number. */ - uip_connr->snd_nxt[0] = uip_acc32[0]; - uip_connr->snd_nxt[1] = uip_acc32[1]; - uip_connr->snd_nxt[2] = uip_acc32[2]; - uip_connr->snd_nxt[3] = uip_acc32[3]; - - /* Do RTT estimation, unless we have done retransmissions. */ - if(uip_connr->nrtx == 0) { - signed char m; - m = uip_connr->rto - uip_connr->timer; - /* This is taken directly from VJs original code in his paper */ - m = m - (uip_connr->sa >> 3); - uip_connr->sa += m; - if(m < 0) { - m = -m; - } - m = m - (uip_connr->sv >> 2); - uip_connr->sv += m; - uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv; - - } - /* Set the acknowledged flag. */ - uip_flags(buf) = UIP_ACKDATA; - /* Reset the retransmission timer. */ - uip_connr->timer = uip_connr->rto; - - /* Reset length of outstanding data. */ - uip_connr->len = 0; - } - - } - - /* Do different things depending on in what state the connection is. */ - switch(uip_connr->tcpstateflags & UIP_TS_MASK) { - /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not - implemented, since we force the application to close when the - peer sends a FIN (hence the application goes directly from - ESTABLISHED to LAST_ACK). */ - case UIP_SYN_RCVD: - /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and - we are waiting for an ACK that acknowledges the data we sent - out the last time. Therefore, we want to have the UIP_ACKDATA - flag set. If so, we enter the ESTABLISHED state. */ - if(uip_flags(buf) & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_ESTABLISHED; - uip_flags(buf) = UIP_CONNECTED; - uip_connr->len = 0; - if(uip_len(buf) > 0) { - uip_flags(buf) |= UIP_NEWDATA; - uip_add_rcv_nxt(buf, uip_len(buf)); - } - uip_slen(buf) = 0; - UIP_APPCALL(buf); - goto appsend; - } - /* We need to retransmit the SYNACK */ - if((BUF(buf)->flags & TCP_CTL) == TCP_SYN) { - goto tcp_send_synack; - } - goto drop; -#if UIP_ACTIVE_OPEN - case UIP_SYN_SENT: - /* In SYN_SENT, we wait for a SYNACK that is sent in response to - our SYN. The rcv_nxt is set to sequence number in the SYNACK - plus one, and we send an ACK. We move into the ESTABLISHED - state. */ - if((uip_flags(buf) & UIP_ACKDATA) && - (BUF(buf)->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) { - - /* Parse the TCP MSS option, if present. */ - if((BUF(buf)->tcpoffset & 0xf0) > 0x50) { - for(c = 0; c < ((BUF(buf)->tcpoffset >> 4) - 5) << 2 ;) { - opt = uip_buf(buf)[UIP_IPTCPH_LEN + UIP_LLH_LEN + c]; - if(opt == TCP_OPT_END) { - /* End of options. */ - break; - } else if(opt == TCP_OPT_NOOP) { - ++c; - /* NOP option. */ - } else if(opt == TCP_OPT_MSS && - uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { - /* An MSS option with the right option length. */ - tmp16 = (uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | - uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c]; - uip_connr->initialmss = - uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; - - /* And we are done processing options. */ - break; - } else { - /* All other options have a length field, so that we easily - can skip past them. */ - if(uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { - /* If the length field is zero, the options are malformed - and we don't process them further. */ - break; - } - c += uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; - } - } - } - uip_connr->tcpstateflags = UIP_ESTABLISHED; - uip_connr->rcv_nxt[0] = BUF(buf)->seqno[0]; - uip_connr->rcv_nxt[1] = BUF(buf)->seqno[1]; - uip_connr->rcv_nxt[2] = BUF(buf)->seqno[2]; - uip_connr->rcv_nxt[3] = BUF(buf)->seqno[3]; - uip_add_rcv_nxt(buf, 1); - uip_flags(buf) = UIP_CONNECTED | UIP_NEWDATA; - uip_connr->len = 0; - uip_len(buf) = 0; - uip_slen(buf) = 0; - ip_buf_sent_status(buf) = 0; - uip_set_conn(buf) = uip_connr; - - if (uip_connr->buf) { - /* Now that we know the original connection request, clear - * the buf in connr - */ - net_context_set_connection_status(ip_buf_context(uip_connr->buf), 0); - net_context_set_internal_connection(ip_buf_context(uip_connr->buf), - uip_connr); - tcp_cancel_retrans_timer(uip_connr); - - /* We received ACK for syn */ - if (uip_connr->buf) { - net_context_set_connection_status(ip_buf_context(uip_connr->buf), -EINPROGRESS); - } - - /* Now send the pending data */ - buf = uip_connr->buf; - *buf_out = buf; - - uip_flags(buf) = UIP_CONNECTED; - } - /* Right now we have received SYN-ACK so we can now start to send data. - * The UIP_APPCALL() will cause a call to this function by the - * net_context.c TCP process thread which will call - * handle_tcp_connection(). - */ - UIP_APPCALL(buf); - PRINTF("Returning now buf %p ref %p\n", buf, buf->ref); - return 0; - } - /* Inform the application that the connection failed */ - uip_flags(buf) = UIP_ABORT; - UIP_APPCALL(buf); - /* The connection is closed after we send the RST */ - uip_conn(buf)->tcpstateflags = UIP_CLOSED; - goto reset; -#endif /* UIP_ACTIVE_OPEN */ - - case UIP_ESTABLISHED: - /* In the ESTABLISHED state, we call upon the application to feed - data into the uip_buf. If the UIP_ACKDATA flag is set, the - application should put new data into the buffer, otherwise we are - retransmitting an old segment, and the application should put that - data into the buffer. - - If the incoming packet is a FIN, we should close the connection on - this side as well, and we send out a FIN and enter the LAST_ACK - state. We require that there is no outstanding data; otherwise the - sequence numbers will be screwed up. */ - - if(BUF(buf)->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) { - if(uip_outstanding(uip_connr)) { - goto drop; - } - uip_add_rcv_nxt(buf, 1 + uip_len(buf)); - uip_flags(buf) |= UIP_CLOSE; - if(uip_len(buf) > 0) { - uip_flags(buf) |= UIP_NEWDATA; - } - UIP_APPCALL(buf); - uip_connr->len = 1; - uip_connr->tcpstateflags = UIP_LAST_ACK; - uip_connr->nrtx = 0; - tcp_send_finack: - BUF(buf)->flags = TCP_FIN | TCP_ACK; - goto tcp_send_nodata; - } - - /* Check the URG flag. If this is set, the segment carries urgent - data that we must pass to the application. */ - if((BUF(buf)->flags & TCP_URG) != 0) { -#if UIP_URGDATA > 0 - uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1]; - if(uip_urglen > uip_len) { - /* There is more urgent data in the next segment to come. */ - uip_urglen = uip_len; - } - uip_add_rcv_nxt(uip_urglen); - uip_len -= uip_urglen; - uip_urgdata = uip_appdata; - uip_appdata += uip_urglen; - } else { - uip_urglen = 0; -#else /* UIP_URGDATA > 0 */ - uip_appdata(buf) = ((char *)uip_appdata(buf)) + ((BUF(buf)->urgp[0] << 8) | BUF(buf)->urgp[1]); - uip_len(buf) -= (BUF(buf)->urgp[0] << 8) | BUF(buf)->urgp[1]; -#endif /* UIP_URGDATA > 0 */ - } - - /* If uip_len > 0 we have TCP data in the packet, and we flag this - by setting the UIP_NEWDATA flag and update the sequence number - we acknowledge. If the application has stopped the dataflow - using uip_stop(), we must not accept any data packets from the - remote host. */ - if(uip_len(buf) > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) { - uip_flags(buf) |= UIP_NEWDATA; - uip_add_rcv_nxt(buf, uip_len(buf)); - } - - /* Check if the available buffer space advertised by the other end - is smaller than the initial MSS for this connection. If so, we - set the current MSS to the window size to ensure that the - application does not send more data than the other end can - handle. - - If the remote host advertises a zero window, we set the MSS to - the initial MSS so that the application will send an entire MSS - of data. This data will not be acknowledged by the receiver, - and the application will retransmit it. This is called the - "persistent timer" and uses the retransmission mechanim. - */ - tmp16 = ((uint16_t)BUF(buf)->wnd[0] << 8) + (uint16_t)BUF(buf)->wnd[1]; - if(tmp16 > uip_connr->initialmss || - tmp16 == 0) { - tmp16 = uip_connr->initialmss; - } - uip_connr->mss = tmp16; - - /* If this packet constitutes an ACK for outstanding data (flagged - by the UIP_ACKDATA flag, we should call the application since it - might want to send more data. If the incoming packet had data - from the peer (as flagged by the UIP_NEWDATA flag), the - application must also be notified. - - When the application is called, the global variable uip_len - contains the length of the incoming data. The application can - access the incoming data through the global pointer - uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN - bytes into the uip_buf array. - - If the application wishes to send any data, this data should be - put into the uip_appdata and the length of the data should be - put into uip_len. If the application don't have any data to - send, uip_len must be set to 0. */ - if(uip_flags(buf) & (UIP_NEWDATA | UIP_ACKDATA)) { - if(flag != UIP_TCP_SEND_CONN) { - /* Do not reset the slen because we are being called - * directly by the application. - */ - uip_slen(buf) = 0; - } - - if (uip_connr->buf) { - net_context_tcp_set_pending(ip_buf_context(uip_connr->buf), NULL); - net_context_set_internal_connection(ip_buf_context(uip_connr->buf), - uip_connr); - - /* At this point we have received ACK to data in uip_connr->buf */ - - /* This is not an error but tells net_core.c:net_send() that - * user should be able to send now more data. - */ - net_context_set_connection_status(ip_buf_context(uip_connr->buf), - EISCONN); - - ip_buf_unref(uip_connr->buf); - uip_connr->buf = NULL; - - tcp_cancel_retrans_timer(uip_connr); - - } else { - /* We have no pending data so this will cause ACK to be sent to - * peer in few lines below. - */ - uip_flags(buf) |= UIP_NEWDATA; - } - - UIP_APPCALL(buf); - - appsend: - - if(uip_flags(buf) & UIP_ABORT) { - uip_slen(buf) = 0; - uip_connr->tcpstateflags = UIP_CLOSED; - BUF(buf)->flags = TCP_RST | TCP_ACK; - goto tcp_send_nodata; - } - - if(uip_flags(buf) & UIP_CLOSE) { - uip_slen(buf) = 0; - uip_connr->len = 1; - uip_connr->tcpstateflags = UIP_FIN_WAIT_1; - uip_connr->nrtx = 0; - BUF(buf)->flags = TCP_FIN | TCP_ACK; - goto tcp_send_nodata; - } - - /* If uip_slen > 0, the application has data to be sent. */ - if(uip_slen(buf) > 0) { - - /* If the connection has acknowledged data, the contents of - the ->len variable should be discarded. */ - if((uip_flags(buf) & UIP_ACKDATA) != 0) { - uip_connr->len = 0; - } - - /* If the ->len variable is non-zero the connection has - already data in transit and cannot send anymore right - now. */ - if(uip_connr->len == 0) { - - /* The application cannot send more than what is allowed by - the mss (the minumum of the MSS and the available - window). */ - if(uip_slen(buf) > uip_connr->mss) { - uip_slen(buf) = uip_connr->mss; - } - - /* Remember how much data we send out now so that we know - when everything has been acknowledged. */ - uip_connr->len = uip_slen(buf); - - PRINTF("Setting connection %p to pending length %d\n", - uip_connr, uip_connr->len); - - if (uip_connr->buf) { - if (uip_connr->buf != buf) { - PRINTF("Data packet %p already pending....\n", - uip_connr->buf); - } - } else { - uip_connr->buf = ip_buf_ref(buf); - } - - } else { - - /* If the application already had unacknowledged data, we - make sure that the application does not send (i.e., - retransmit) out more than it previously sent out. */ - uip_slen(buf) = uip_connr->len; - } - } - uip_connr->nrtx = 0; - apprexmit: - uip_appdata(buf) = uip_sappdata(buf); - - /* If the application has data to be sent, or if the incoming - packet had new data in it, we must send out a packet. */ - if(uip_slen(buf) > 0 && uip_connr->len > 0) { - /* Add the length of the IP and TCP headers. */ - uip_len(buf) = uip_connr->len + UIP_TCPIP_HLEN; - /* We always set the ACK flag in response packets. */ - BUF(buf)->flags = TCP_ACK | TCP_PSH; - /* Send the packet. */ - goto tcp_send_noopts; - } - /* If there is no data to send, just send out a pure ACK if - there is newdata. */ - if(uip_flags(buf) & UIP_NEWDATA) { - uip_len(buf) = UIP_TCPIP_HLEN; - BUF(buf)->flags = TCP_ACK; - goto tcp_send_noopts; - } - } - goto drop; - case UIP_LAST_ACK: - /* We can close this connection if the peer has acknowledged our - FIN. This is indicated by the UIP_ACKDATA flag. */ - if(uip_flags(buf) & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_CLOSED; - uip_flags(buf) = UIP_CLOSE; - UIP_APPCALL(buf); - } - break; - - case UIP_FIN_WAIT_1: - /* The application has closed the connection, but the remote host - hasn't closed its end yet. Thus we do nothing but wait for a - FIN from the other side. */ - if(uip_len(buf) > 0) { - uip_add_rcv_nxt(buf, uip_len(buf)); - } - if(BUF(buf)->flags & TCP_FIN) { - if(uip_flags(buf) & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - uip_connr->len = 0; - } else { - uip_connr->tcpstateflags = UIP_CLOSING; - } - uip_add_rcv_nxt(buf, 1); - uip_flags(buf) = UIP_CLOSE; - UIP_APPCALL(buf); - goto tcp_send_ack; - } else if(uip_flags(buf) & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_FIN_WAIT_2; - uip_connr->len = 0; - goto drop; - } - if(uip_len(buf) > 0) { - goto tcp_send_ack; - } - goto drop; - - case UIP_FIN_WAIT_2: - if(uip_len(buf) > 0) { - uip_add_rcv_nxt(buf, uip_len(buf)); - } - if(BUF(buf)->flags & TCP_FIN) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - uip_add_rcv_nxt(buf, 1); - uip_flags(buf) = UIP_CLOSE; - UIP_APPCALL(buf); - goto tcp_send_ack; - } - if(uip_len(buf) > 0) { - goto tcp_send_ack; - } - goto drop; - - case UIP_TIME_WAIT: - goto tcp_send_ack; - - case UIP_CLOSING: - if(uip_flags(buf) & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - } - } - goto drop; - - /* We jump here when we are ready to send the packet, and just want - to set the appropriate TCP sequence numbers in the TCP header. */ - tcp_send_ack: - PRINTF("In tcp_send_ack\n"); - BUF(buf)->flags = TCP_ACK; - - tcp_send_nodata: - if (flag != UIP_TCP_SEND_CONN) { - PRINTF("In tcp_send_nodata\n"); - uip_len(buf) = UIP_IPTCPH_LEN; - buf->len = UIP_IPTCPH_LEN; - } - - tcp_send_noopts: - BUF(buf)->tcpoffset = (UIP_TCPH_LEN / 4) << 4; - - /* We're done with the input processing. We are now ready to send a - reply. Our job is to fill in all the fields of the TCP and IP - headers before calculating the checksum and finally send the - packet. */ - tcp_send: - PRINTF("In tcp_send\n"); - - BUF(buf)->ackno[0] = uip_connr->rcv_nxt[0]; - BUF(buf)->ackno[1] = uip_connr->rcv_nxt[1]; - BUF(buf)->ackno[2] = uip_connr->rcv_nxt[2]; - BUF(buf)->ackno[3] = uip_connr->rcv_nxt[3]; - - BUF(buf)->seqno[0] = uip_connr->snd_nxt[0]; - BUF(buf)->seqno[1] = uip_connr->snd_nxt[1]; - BUF(buf)->seqno[2] = uip_connr->snd_nxt[2]; - BUF(buf)->seqno[3] = uip_connr->snd_nxt[3]; - - BUF(buf)->srcport = uip_connr->lport; - BUF(buf)->destport = uip_connr->rport; - - uip_ipaddr_copy(&BUF(buf)->srcipaddr, &uip_hostaddr); - uip_ipaddr_copy(&BUF(buf)->destipaddr, &uip_connr->ripaddr); - PRINTF("Sending TCP packet to "); - PRINT6ADDR(&BUF(buf)->destipaddr); - PRINTF(" from "); - PRINT6ADDR(&BUF(buf)->srcipaddr); - PRINTF("\n"); - - if(uip_connr->tcpstateflags & UIP_STOPPED) { - /* If the connection has issued uip_stop(), we advertise a zero - window so that the remote host will stop sending data. */ - BUF(buf)->wnd[0] = BUF(buf)->wnd[1] = 0; - } else { - BUF(buf)->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8); - BUF(buf)->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); - } - - tcp_send_noconn: - BUF(buf)->proto = UIP_PROTO_TCP; - - BUF(buf)->ttl = UIP_TTL; -#if NETSTACK_CONF_WITH_IPV6 - /* For IPv6, the IP length field does not include the IPv6 IP header - length. */ - BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); - BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); -#else /* NETSTACK_CONF_WITH_IPV6 */ - BUF(buf)->len[0] = (uip_len(buf) >> 8); - BUF(buf)->len[1] = (uip_len(buf) & 0xff); -#endif /* NETSTACK_CONF_WITH_IPV6 */ - - BUF(buf)->urgp[0] = BUF(buf)->urgp[1] = 0; - - /* Calculate TCP checksum. */ - BUF(buf)->tcpchksum = 0; - BUF(buf)->tcpchksum = ~(uip_tcpchksum(buf)); -#endif - - ip_send_nolen: -#if NETSTACK_CONF_WITH_IPV6 - BUF->vtc = 0x60; - BUF->tcflow = 0x00; - BUF->flow = 0x00; -#else /* NETSTACK_CONF_WITH_IPV6 */ - BUF(buf)->vhl = 0x45; - BUF(buf)->tos = 0; - BUF(buf)->ipoffset[0] = BUF(buf)->ipoffset[1] = 0; - ++ipid; - BUF(buf)->ipid[0] = ipid >> 8; - BUF(buf)->ipid[1] = ipid & 0xff; - /* Calculate IP checksum. */ - BUF(buf)->ipchksum = 0; - BUF(buf)->ipchksum = ~(uip_ipchksum(buf)); - PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum(buf)); -#endif /* NETSTACK_CONF_WITH_IPV6 */ -#if UIP_TCP - UIP_STAT(++uip_stat.tcp.sent); -#endif -#if NETSTACK_CONF_WITH_IPV6 - send: -#endif /* NETSTACK_CONF_WITH_IPV6 */ - PRINTF("Sending packet with length %d (%d)\n", uip_len(buf), - (BUF(buf)->len[0] << 8) | BUF(buf)->len[1]); - - UIP_STAT(++uip_stat.ip.sent); - /* Return and let the caller do the actual transmission. */ - uip_flags(buf) = 0; - return 1; - - drop: - uip_len(buf) = 0; - uip_flags(buf) = 0; - -#if UIP_TCP - /* Clear any pending packet */ - if (uip_connr && uip_connr->buf) { - tcp_cancel_retrans_timer(uip_connr); - switch (uip_connr->tcpstateflags & UIP_TS_MASK) { - case UIP_FIN_WAIT_1: - case UIP_FIN_WAIT_2: - case UIP_CLOSING: - case UIP_TIME_WAIT: - ip_buf_unref(uip_connr->buf); - uip_connr->buf = NULL; - } - } -#endif - - return 0; -} -/*---------------------------------------------------------------------------*/ -uint16_t -uip_htons(uint16_t val) -{ - return UIP_HTONS(val); -} - -uint32_t -uip_htonl(uint32_t val) -{ - return UIP_HTONL(val); -} -/*---------------------------------------------------------------------------*/ -#if UIP_TCP -void -uip_send(struct net_buf *buf, const void *data, int len) -{ - int copylen; -#define MIN(a,b) ((a) < (b)? (a): (b)) - - uip_sappdata(buf) = ip_buf_appdata(buf); - - if(uip_sappdata(buf) != NULL) { - copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN - - (int)((char *)uip_sappdata(buf) - - (char *)&uip_buf(buf)[UIP_LLH_LEN + UIP_TCPIP_HLEN])); - } else { - copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN); - } - if(copylen > 0) { - uip_slen(buf) = copylen; - if(data != uip_sappdata(buf)) { - if(uip_sappdata(buf) == NULL) { - memmove((char *)&uip_buf(buf)[UIP_LLH_LEN + UIP_TCPIP_HLEN], - (data), uip_slen(buf)); - } else { - memmove(uip_sappdata(buf), (data), uip_slen(buf)); - } - } - if (uip_process(&buf, UIP_TCP_SEND_CONN)) { - int ret = tcpip_output(buf, NULL); - if (!ret) { - PRINTF("Packet %p sending failed.\n", buf); - ip_buf_sent_status(buf) = -EAGAIN; - } - } - } -} -#endif - -#if UIP_UDP -void -uip_send_udp(struct net_buf *buf, const void *data, int len) -{ - uip_slen(buf) = len; - - if (uip_process(&buf, UIP_UDP_SEND_CONN)) { - int ret = tcpip_output(buf, NULL); - if (!ret) { - PRINTF("Packet %p sending failed.\n", buf); - ip_buf_unref(buf); - } - } -} -#endif -/*---------------------------------------------------------------------------*/ -/** @}*/ diff --git a/net/ip/contiki/ipv4/uip_arp.c b/net/ip/contiki/ipv4/uip_arp.c deleted file mode 100644 index 097d4ee41074ec29a99ee4998249ad6fc4218ac5..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv4/uip_arp.c +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack. - * - * - */ - -/** - * \file - * Implementation of the ARP Address Resolution Protocol. - * \author Adam Dunkels - * - */ - -/** - * \addtogroup uip - * @{ - */ - -/** - * \defgroup uiparp uIP Address Resolution Protocol - * @{ - * - * The Address Resolution Protocol ARP is used for mapping between IP - * addresses and link level addresses such as the Ethernet MAC - * addresses. ARP uses broadcast queries to ask for the link level - * address of a known IP address and the host which is configured with - * the IP address for which the query was meant, will respond with its - * link level address. - * - * \note This ARP implementation only supports Ethernet. - */ - -#include "contiki/ipv4/uip_arp.h" - -#include -#include - -struct arp_hdr { - struct uip_eth_hdr ethhdr; - uint16_t hwtype; - uint16_t protocol; - uint8_t hwlen; - uint8_t protolen; - uint16_t opcode; - struct uip_eth_addr shwaddr; - uip_ipaddr_t sipaddr; - struct uip_eth_addr dhwaddr; - uip_ipaddr_t dipaddr; -} PACK_ALIAS_STRUCT; - -struct ethip_hdr { - struct uip_eth_hdr ethhdr; - /* IP header. */ - uint8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; - uint16_t ipchksum; - uip_ipaddr_t srcipaddr, destipaddr; -} PACK_ALIAS_STRUCT; - -#define ARP_REQUEST 1 -#define ARP_REPLY 2 - -#define ARP_HWTYPE_ETH 1 - -struct arp_entry { - uip_ipaddr_t ipaddr; - struct uip_eth_addr ethaddr; - uint8_t time; -}; - -static const struct uip_eth_addr broadcast_ethaddr = - {{0xff,0xff,0xff,0xff,0xff,0xff}}; - -static struct arp_entry arp_table[UIP_ARPTAB_SIZE]; -static uip_ipaddr_t ipaddr; -static uint8_t i, c; - -static uint8_t arptime; -static uint8_t tmpage; - -#define BUF(buf) ((struct arp_hdr *)&uip_buf(buf)[0]) -#define IPBUF(buf) ((struct ethip_hdr *)&uip_buf(buf)[0]) - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_IPV4_ARP -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -/*-----------------------------------------------------------------------------------*/ -/** - * Initialize the ARP module. - * - */ -/*-----------------------------------------------------------------------------------*/ -void -uip_arp_init(void) -{ - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - memset(&arp_table[i].ipaddr, 0, 4); - } -} -/*-----------------------------------------------------------------------------------*/ -/** - * Periodic ARP processing function. - * - * This function performs periodic timer processing in the ARP module - * and should be called at regular intervals. The recommended interval - * is 10 seconds between the calls. - * - */ -/*-----------------------------------------------------------------------------------*/ -void -uip_arp_timer(void) -{ - struct arp_entry *tabptr; - - ++arptime; - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - tabptr = &arp_table[i]; - if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr) && - arptime - tabptr->time >= UIP_ARP_MAXAGE) { - memset(&tabptr->ipaddr, 0, 4); - } - } - -} - -/*-----------------------------------------------------------------------------------*/ -static void -uip_arp_update(uip_ipaddr_t *ipaddr, struct uip_eth_addr *ethaddr) -{ - register struct arp_entry *tabptr = arp_table; - - /* Walk through the ARP mapping table and try to find an entry to - update. If none is found, the IP -> MAC address mapping is - inserted in the ARP table. */ - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - tabptr = &arp_table[i]; - - /* Only check those entries that are actually in use. */ - if(!uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) { - - /* Check if the source IP address of the incoming packet matches - the IP address in this ARP table entry. */ - if(uip_ipaddr_cmp(ipaddr, &tabptr->ipaddr)) { - - /* An old entry found, update this and return. */ - memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); - tabptr->time = arptime; - - return; - } - } - tabptr++; - } - - /* If we get here, no existing ARP table entry was found, so we - create one. */ - - /* First, we try to find an unused entry in the ARP table. */ - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - tabptr = &arp_table[i]; - if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) { - break; - } - } - - /* If no unused entry is found, we try to find the oldest entry and - throw it away. */ - if(i == UIP_ARPTAB_SIZE) { - tmpage = 0; - c = 0; - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - tabptr = &arp_table[i]; - if(arptime - tabptr->time > tmpage) { - tmpage = arptime - tabptr->time; - c = i; - } - } - i = c; - tabptr = &arp_table[i]; - } - - /* Now, i is the ARP table entry which we will fill with the new - information. */ - uip_ipaddr_copy(&tabptr->ipaddr, ipaddr); - memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); - tabptr->time = arptime; -} -/*-----------------------------------------------------------------------------------*/ -/** - * ARP processing for incoming IP packets - * - * This function should be called by the device driver when an IP - * packet has been received. The function will check if the address is - * in the ARP cache, and if so the ARP cache entry will be - * refreshed. If no ARP cache entry was found, a new one is created. - * - * This function expects an IP packet with a prepended Ethernet header - * in the uip_buf[] buffer, and the length of the packet in the global - * variable uip_len. - */ -/*-----------------------------------------------------------------------------------*/ -#if 0 -void -uip_arp_ipin(void) -{ - uip_len -= sizeof(struct uip_eth_hdr); - - /* Only insert/update an entry if the source IP address of the - incoming IP packet comes from a host on the local network. */ - if((IPBUF->srcipaddr[0] & uip_netmask[0]) != - (uip_hostaddr[0] & uip_netmask[0])) { - return; - } - if((IPBUF->srcipaddr[1] & uip_netmask[1]) != - (uip_hostaddr[1] & uip_netmask[1])) { - return; - } - uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src)); - - return; -} -#endif /* 0 */ -/*-----------------------------------------------------------------------------------*/ -/** - * ARP processing for incoming ARP packets. - * - * This function should be called by the device driver when an ARP - * packet has been received. The function will act differently - * depending on the ARP packet type: if it is a reply for a request - * that we previously sent out, the ARP cache will be filled in with - * the values from the ARP reply. If the incoming ARP packet is an ARP - * request for our IP address, an ARP reply packet is created and put - * into the uip_buf[] buffer. - * - * When the function returns, the value of the global variable uip_len - * indicates whether the device driver should send out a packet or - * not. If uip_len is zero, no packet should be sent. If uip_len is - * non-zero, it contains the length of the outbound packet that is - * present in the uip_buf[] buffer. - * - * This function expects an ARP packet with a prepended Ethernet - * header in the uip_buf[] buffer, and the length of the packet in the - * global variable uip_len. - */ -/*-----------------------------------------------------------------------------------*/ -void -uip_arp_arpin(struct net_buf *buf) -{ - - if(uip_len(buf) < sizeof(struct arp_hdr)) { - uip_len(buf) = 0; - return; - } - uip_len(buf) = 0; - - switch(BUF(buf)->opcode) { - case UIP_HTONS(ARP_REQUEST): - /* ARP request. If it asked for our address, we send out a - reply. */ - /* if(BUF->dipaddr[0] == uip_hostaddr[0] && - BUF->dipaddr[1] == uip_hostaddr[1]) {*/ - PRINTF("uip_arp_arpin: request for %d.%d.%d.%d (we are %d.%d.%d.%d)\n", - BUF(buf)->dipaddr.u8[0], BUF(buf)->dipaddr.u8[1], - BUF(buf)->dipaddr.u8[2], BUF(buf)->dipaddr.u8[3], - uip_hostaddr.u8[0], uip_hostaddr.u8[1], - uip_hostaddr.u8[2], uip_hostaddr.u8[3]); - if(uip_ipaddr_cmp(&BUF(buf)->dipaddr, &uip_hostaddr)) { - /* First, we register the one who made the request in our ARP - table, since it is likely that we will do more communication - with this host in the future. */ - uip_arp_update(&BUF(buf)->sipaddr, &BUF(buf)->shwaddr); - - BUF(buf)->opcode = UIP_HTONS(ARP_REPLY); - - memcpy(BUF(buf)->dhwaddr.addr, BUF(buf)->shwaddr.addr, 6); - memcpy(BUF(buf)->shwaddr.addr, uip_lladdr.addr, 6); - memcpy(BUF(buf)->ethhdr.src.addr, uip_lladdr.addr, 6); - memcpy(BUF(buf)->ethhdr.dest.addr, BUF(buf)->dhwaddr.addr, 6); - - uip_ipaddr_copy(&BUF(buf)->dipaddr, &BUF(buf)->sipaddr); - uip_ipaddr_copy(&BUF(buf)->sipaddr, &uip_hostaddr); - - BUF(buf)->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_ARP); - uip_len(buf) = sizeof(struct arp_hdr); - } - break; - case UIP_HTONS(ARP_REPLY): - /* ARP reply. We insert or update the ARP table if it was meant - for us. */ - if(uip_ipaddr_cmp(&BUF(buf)->dipaddr, &uip_hostaddr)) { - uip_arp_update(&BUF(buf)->sipaddr, &BUF(buf)->shwaddr); - } - break; - } - - return; -} -/*-----------------------------------------------------------------------------------*/ -/** - * Prepend Ethernet header to an outbound IP packet and see if we need - * to send out an ARP request. - * - * This function should be called before sending out an IP packet. The - * function checks the destination IP address of the IP packet to see - * what Ethernet MAC address that should be used as a destination MAC - * address on the Ethernet. - * - * If the destination IP address is in the local network (determined - * by logical ANDing of netmask and our IP address), the function - * checks the ARP cache to see if an entry for the destination IP - * address is found. If so, an Ethernet header is prepended and the - * function returns. If no ARP cache entry is found for the - * destination IP address, the packet in the uip_buf[] is replaced by - * an ARP request packet for the IP address. The IP packet is dropped - * and it is assumed that they higher level protocols (e.g., TCP) - * eventually will retransmit the dropped packet. - * - * If the destination IP address is not on the local network, the IP - * address of the default router is used instead. - * - * When the function returns, a packet is present in the uip_buf[] - * buffer, and the length of the packet is in the global variable - * uip_len. - */ -/*-----------------------------------------------------------------------------------*/ -void -uip_arp_out(struct net_buf *buf) -{ - struct arp_entry *tabptr = arp_table; - - /* Find the destination IP address in the ARP table and construct - the Ethernet header. If the destination IP addres isn't on the - local network, we use the default router's IP address instead. - - If not ARP table entry is found, we overwrite the original IP - packet with an ARP request for the IP address. */ - - /* First check if destination is a local broadcast. */ - if(uip_ipaddr_cmp(&IPBUF(buf)->destipaddr, &uip_broadcast_addr)) { - memcpy(IPBUF(buf)->ethhdr.dest.addr, broadcast_ethaddr.addr, 6); - } else if(IPBUF(buf)->destipaddr.u8[0] == 224) { - /* Multicast. */ - IPBUF(buf)->ethhdr.dest.addr[0] = 0x01; - IPBUF(buf)->ethhdr.dest.addr[1] = 0x00; - IPBUF(buf)->ethhdr.dest.addr[2] = 0x5e; - IPBUF(buf)->ethhdr.dest.addr[3] = IPBUF(buf)->destipaddr.u8[1]; - IPBUF(buf)->ethhdr.dest.addr[4] = IPBUF(buf)->destipaddr.u8[2]; - IPBUF(buf)->ethhdr.dest.addr[5] = IPBUF(buf)->destipaddr.u8[3]; - } else { - /* Check if the destination address is on the local network. */ - if(!uip_ipaddr_maskcmp(&IPBUF(buf)->destipaddr, &uip_hostaddr, &uip_netmask)) { - /* Destination address was not on the local network, so we need to - use the default router's IP address instead of the destination - address when determining the MAC address. */ - uip_ipaddr_copy(&ipaddr, &uip_draddr); - } else { - /* Else, we use the destination IP address. */ - uip_ipaddr_copy(&ipaddr, &IPBUF(buf)->destipaddr); - } - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - if(uip_ipaddr_cmp(&ipaddr, &tabptr->ipaddr)) { - break; - } - tabptr++; - } - - if(i == UIP_ARPTAB_SIZE) { - /* The destination address was not in our ARP table, so we - overwrite the IP packet with an ARP request. */ - - memset(BUF(buf)->ethhdr.dest.addr, 0xff, 6); - memset(BUF(buf)->dhwaddr.addr, 0x00, 6); - memcpy(BUF(buf)->ethhdr.src.addr, uip_lladdr.addr, 6); - memcpy(BUF(buf)->shwaddr.addr, uip_lladdr.addr, 6); - - uip_ipaddr_copy(&BUF(buf)->dipaddr, &ipaddr); - uip_ipaddr_copy(&BUF(buf)->sipaddr, &uip_hostaddr); - BUF(buf)->opcode = UIP_HTONS(ARP_REQUEST); /* ARP request. */ - BUF(buf)->hwtype = UIP_HTONS(ARP_HWTYPE_ETH); - BUF(buf)->protocol = UIP_HTONS(UIP_ETHTYPE_IP); - BUF(buf)->hwlen = 6; - BUF(buf)->protolen = 4; - BUF(buf)->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_ARP); - - uip_appdata(buf) = &uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN]; - - uip_len(buf) = sizeof(struct arp_hdr); - return; - } - - /* Build an ethernet header. */ - memcpy(IPBUF(buf)->ethhdr.dest.addr, tabptr->ethaddr.addr, 6); - } - memcpy(IPBUF(buf)->ethhdr.src.addr, uip_lladdr.addr, 6); - - IPBUF(buf)->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_IP); - - uip_len(buf) += sizeof(struct uip_eth_hdr); -} -/*-----------------------------------------------------------------------------------*/ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/ipv4/uip_arp.h b/net/ip/contiki/ipv4/uip_arp.h deleted file mode 100644 index e9c32c068fa120321bd07e07370e42394c6b3d67..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv4/uip_arp.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack. - * - * - */ - -/** - * \file - * Macros and definitions for the ARP module. - * \author Adam Dunkels - */ - -/** - * \addtogroup uip - * @{ - */ - -/** - * \addtogroup uiparp - * @{ - */ - -#ifndef UIP_ARP_H_ -#define UIP_ARP_H_ - -#include "contiki/ip/uip.h" - - - -/** - * The Ethernet header. - */ -struct uip_eth_hdr { - struct uip_eth_addr dest; - struct uip_eth_addr src; - uint16_t type; -}; - -#define UIP_ETHTYPE_ARP 0x0806 -#define UIP_ETHTYPE_IP 0x0800 -#define UIP_ETHTYPE_IPV6 0x86dd - - -/* The uip_arp_init() function must be called before any of the other - ARP functions. */ -void uip_arp_init(void); - -/* The uip_arp_ipin() function should be called whenever an IP packet - arrives from the Ethernet. This function refreshes the ARP table or - inserts a new mapping if none exists. The function assumes that an - IP packet with an Ethernet header is present in the uip_buf buffer - and that the length of the packet is in the uip_len variable. */ -/*void uip_arp_ipin(void);*/ -#define uip_arp_ipin() - -/* The uip_arp_arpin() should be called when an ARP packet is received - by the Ethernet driver. This function also assumes that the - Ethernet frame is present in the uip_buf buffer. When the - uip_arp_arpin() function returns, the contents of the uip_buf - buffer should be sent out on the Ethernet if the uip_len variable - is > 0. */ -void uip_arp_arpin(struct net_buf *buf); - -/* The uip_arp_out() function should be called when an IP packet - should be sent out on the Ethernet. This function creates an - Ethernet header before the IP header in the uip_buf buffer. The - Ethernet header will have the correct Ethernet MAC destination - address filled in if an ARP table entry for the destination IP - address (or the IP address of the default router) is present. If no - such table entry is found, the IP packet is overwritten with an ARP - request and we rely on TCP to retransmit the packet that was - overwritten. In any case, the uip_len variable holds the length of - the Ethernet frame that should be transmitted. */ -void uip_arp_out(struct net_buf *buf); - -/* The uip_arp_timer() function should be called every ten seconds. It - is responsible for flushing old entries in the ARP table. */ -void uip_arp_timer(void); - -/** @} */ - -/** - * \addtogroup uipconffunc - * @{ - */ - - -/** - * Specifiy the Ethernet MAC address. - * - * The ARP code needs to know the MAC address of the Ethernet card in - * order to be able to respond to ARP queries and to generate working - * Ethernet headers. - * - * \note This macro only specifies the Ethernet MAC address to the ARP - * code. It cannot be used to change the MAC address of the Ethernet - * card. - * - * \param eaddr A pointer to a struct uip_eth_addr containing the - * Ethernet MAC address of the Ethernet card. - * - * \hideinitializer - */ -#define uip_setethaddr(eaddr) do {uip_lladdr.addr[0] = eaddr.addr[0]; \ - uip_lladdr.addr[1] = eaddr.addr[1];\ - uip_lladdr.addr[2] = eaddr.addr[2];\ - uip_lladdr.addr[3] = eaddr.addr[3];\ - uip_lladdr.addr[4] = eaddr.addr[4];\ - uip_lladdr.addr[5] = eaddr.addr[5];} while(0) - -/** @} */ - - -#endif /* UIP_ARP_H_ */ -/** @} */ diff --git a/net/ip/contiki/ipv6/multicast/README.md b/net/ip/contiki/ipv6/multicast/README.md deleted file mode 100644 index 0aea775529f734ec858e18fc81ff8a149a4ff8f5..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/multicast/README.md +++ /dev/null @@ -1,114 +0,0 @@ -README file for Contiki's IPv6 multicast core - -Author: George Oikonomou - -What does it do -=============== -These files, alongside some core modifications, add support for IPv6 multicast -to contiki's uIPv6 engine. - -Currently, two modes are supported: - - * 'Stateless Multicast RPL Forwarding' (SMRF) - RPL in MOP 3 handles group management as per the RPL docs, - SMRF is a lightweight engine which handles datagram forwarding. - SMRF is documented here: - http://dx.doi.org/10.1007/s11277-013-1250-5 - and here: - http://dx.doi.org/10.1109/PerComW.2012.6197494 - * 'Multicast Forwarding with Trickle' according to the algorithm described - in the internet draft: - http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast - The version of this draft that's currently implementated is documented - in `roll-tm.h` - -More engines can (and hopefully will) be added in the future. The first -addition is most likely going to be an updated implementation of MPL - -The Big Gotcha -============== -Currently we only support traffic originating and destined inside a single 6LoWPAN -To be able to send multicast traffic from the internet to 6LoWPAN nodes or the other -way round, we need border routers or other gateway devices to be able to achieve -the following: - - * Add/Remove Trickle Multicast, RPL or other HBHO headers as necessary for datagrams - entering / exiting the 6LoWPAN - * Advertise multicast group membership to the internet (e.g. with MLD) - -These are currently not implemented and are in the ToDo list. Contributions welcome. - -Where to Start -============== -The best place in `examples/ipv6/multicast` - -There is a cooja example demonstrating basic functionality - -How to Use -========== -Look in `core/net/ipv6/multicast/uip-mcast6-engines.h` for a list of supported -multicast engines. - -To turn on multicast support, add this line in your `project-` or `contiki-conf.h` - - #define UIP_MCAST6_CONF_ENGINE xyz - - where xyz is a value from `uip-mcast6-engines.h` - -To disable: - - #define UIP_MCAST6_CONF_ENGINE 0 - -You also need to make sure the multicast code gets built. Your example's -(or platform's) Makefile should include this: - - MODULES += core/net/ipv6/multicast - -How to extend -============= -Let's assume you want to write an engine called foo. -The multicast API defines a multicast engine driver in a fashion similar to -the various NETSTACK layer drivers. This API defines functions for basic -multicast operations (init, in, out). -In order to extend multicast with a new engine, perform the following steps: - -- Open `uip-mcast6-engines.h` and assign a unique integer code to your engine - - #define UIP_MCAST6_ENGINE_FOO xyz - - - Include your engine's `foo.h` - -- In `foo.c`, implement: - * `init()` - * `in()` - * `out()` - * Define your driver like so: - - `const struct uip_mcast6_driver foo_driver = { ... }` - -- If you want to maintain stats: - * Standard multicast stats are maintained in `uip_mcast6_stats`. Don't access - this struct directly, use the macros provided in `uip-mcast6-stats.h` instead - * You can add your own stats extensions. To do so, declare your own stats - struct in your engine's module, e.g `struct foo_stats` - * When you initialise the stats module with `UIP_MCAST6_STATS_INIT`, pass - a pointer to your stats variable as the macro's argument. - An example of how to extend multicast stats, look at the ROLL TM engine - -- Open `uip-mcast6.h` and add a section in the `#if` spree. This aims to - configure the uIPv6 core. More specifically, you need to: - * Specify if you want to put RPL in MOP3 by defining - `RPL_CONF_MULTICAST`: 1: MOP 3, 0: non-multicast MOP - * Define your engine details - - #define UIP_MCAST6 foo_driver - #define UIP_MCAST6_STATS foo_stats - typedef struct foo_stats uip_mcast6_stats_t; - - * Optionally, add a configuration check block to stop builds when the - configuration is not sane. - -If you need your engine to perform operations not supported by the generic -UIP_MCAST6 API, you will have to hook those in the uip core manually. As an -example, see how the core is modified so that it can deliver ICMPv6 datagrams -to the ROLL TM engine. diff --git a/net/ip/contiki/ipv6/multicast/roll-tm.c b/net/ip/contiki/ipv6/multicast/roll-tm.c deleted file mode 100644 index d9fe5dbc687ac429bc7b6719df8130d50dab7dee..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/multicast/roll-tm.c +++ /dev/null @@ -1,1448 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \addtogroup roll-tm - * @{ - */ -/** - * \file - * Implementation of the ROLL TM multicast engine - * \author - * George Oikonomou - - */ - -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" -#include "contiki/ipv6/uip-icmp6.h" -#include "contiki/ipv6/multicast/uip-mcast6.h" -#include "contiki/ipv6/multicast/roll-tm.h" -#include "dev/watchdog.h" -#include - -#define DEBUG DEBUG_NONE -#include "contiki/ip/uip-debug.h" - -#define TRICKLE_VERBOSE 0 - -#if DEBUG && TRICKLE_VERBOSE -#define VERBOSE_PRINTF(...) PRINTF(__VA_ARGS__) -#define VERBOSE_PRINT_SEED(s) PRINT_SEED(s) -#else -#define VERBOSE_PRINTF(...) -#define VERBOSE_PRINT_SEED(...) -#endif - -/*---------------------------------------------------------------------------*/ -/* Data Representation */ -/*---------------------------------------------------------------------------*/ -#if ROLL_TM_SHORT_SEEDS -typedef union seed_id_u { - uint8_t u8[2]; - uint16_t id; /* Big Endian */ -} seed_id_t; - -#define seed_is_null(s) ((s)->id == 0) -#define PRINT_SEED(s) PRINTF("0x%02x%02x", (s)->u8[0], (s)->u8[1]) -#else /* ROLL_TM_SHORT_SEEDS */ -typedef uip_ip6addr_t seed_id_t; - -#define seed_is_null(s) uip_is_addr_unspecified(s) -#define PRINT_SEED(s) PRINT6ADDR(s) -#endif /* ROLL_TM_SHORT_SEEDS */ -#define seed_id_cmp(a, b) (memcmp((a), (b), sizeof(seed_id_t)) == 0) -#define seed_id_cpy(a, b) (memcpy((a), (b), sizeof(seed_id_t))) - -/* Trickle Timers */ -struct trickle_param { - clock_time_t i_min; /* Clock ticks */ - clock_time_t t_start; /* Start of the interval (absolute clock_time) */ - clock_time_t t_end; /* End of the interval (absolute clock_time) */ - clock_time_t t_next; /* Clock ticks, randomised in [I/2, I) */ - clock_time_t t_last_trigger; - struct ctimer ct; - uint8_t i_current; /* Current doublings from i_min */ - uint8_t i_max; /* Max number of doublings */ - uint8_t k; /* Redundancy Constant */ - uint8_t t_active; /* Units of Imax */ - uint8_t t_dwell; /* Units of Imax */ - uint8_t c; /* Consistency Counter */ - uint8_t inconsistency; -}; - -/** - * \brief Convert a timer to a sane clock_time_t value after d doublings - * m is a value of Imin, d is a number of doublings - * Careful of overflows - */ -#define TRICKLE_TIME(m, d) ((clock_time_t)((m) << (d))) - -/** - * \brief Convert Imax from number of doublings to clock_time_t units for - * trickle_param t. Again, watch out for overflows */ -#define TRICKLE_IMAX(t) ((uint32_t)((t)->i_min << (t)->i_max)) - -/** - * \brief Convert Tactive for a trickle timer to a sane clock_time_t value - * t is a pointer to the timer - * Careful of overflows - */ -#define TRICKLE_ACTIVE(t) ((uint32_t)(TRICKLE_IMAX(t) * t->t_active)) - -/** - * \brief Convert Tdwell for a trickle timer to a sane clock_time_t value - * t is a pointer to the timer - * Careful of overflows - */ -#define TRICKLE_DWELL(t) ((uint32_t)(TRICKLE_IMAX(t) * t->t_dwell)) - -/** - * \brief Check if suppression is enabled for trickle_param t - * t is a pointer to the timer - */ -#define SUPPRESSION_ENABLED(t) ((t)->k != ROLL_TM_INFINITE_REDUNDANCY) - -/** - * \brief Check if suppression is disabled for trickle_param t - * t is a pointer to the timer - */ -#define SUPPRESSION_DISABLED(t) ((t)->k == ROLL_TM_INFINITE_REDUNDANCY) - -/** - * \brief Init trickle_timer[m] - */ -#define TIMER_CONFIGURE(m) do { \ - t[m].i_min = ROLL_TM_IMIN_##m; \ - t[m].i_max = ROLL_TM_IMAX_##m; \ - t[m].k = ROLL_TM_K_##m; \ - t[m].t_active = ROLL_TM_T_ACTIVE_##m; \ - t[m].t_dwell = ROLL_TM_T_DWELL_##m; \ - t[m].t_last_trigger = clock_time(); \ -} while(0) -/*---------------------------------------------------------------------------*/ -/* Sequence Values and Serial Number Arithmetic - * - * Sequence Number Comparisons as per RFC1982 "Serial Number Arithmetic" - * Our 'SERIAL_BITS' value is 15 here - * - * NOTE: There can be pairs of sequence numbers s1 and s2 with an undefined - * ordering. All three macros would evaluate as 0, as in: - * SEQ_VAL_IS_EQUAL(s1, s2) == 0 and - * SEQ_VAL_IS_GT(s1, s2) == 0 and - * SEQ_VAL_IS_LT(s1, s2) == 0 - * - * This is not a bug of this implementation, it's an RFC design choice - */ - -/** - * \brief s1 is said to be equal s2 iif SEQ_VAL_IS_EQ(s1, s2) == 1 - */ -#define SEQ_VAL_IS_EQ(i1, i2) ((i1) == (i2)) - -/** - * \brief s1 is said to be less than s2 iif SEQ_VAL_IS_LT(s1, s2) == 1 - */ -#define SEQ_VAL_IS_LT(i1, i2) \ - ( \ - ((i1) != (i2)) && \ - ((((i1) < (i2)) && ((int16_t)((i2) - (i1)) < 0x4000)) || \ - (((i1) > (i2)) && ((int16_t)((i1) - (i2)) > 0x4000))) \ - ) - -/** - * \brief s1 is said to be greater than s2 iif SEQ_VAL_IS_LT(s1, s2) == 1 - */ -#define SEQ_VAL_IS_GT(i1, i2) \ -( \ - ((i1) != (i2)) && \ - ((((i1) < (i2)) && ((int16_t)((i2) - (i1)) > 0x4000)) || \ - (((i1) > (i2)) && ((int16_t)((i1) - (i2)) < 0x4000))) \ -) - -/** - * \brief Add n to s: (s + n) modulo (2 ^ SERIAL_BITS) => ((s + n) % 0x8000) - */ -#define SEQ_VAL_ADD(s, n) (((s) + (n)) % 0x8000) -/*---------------------------------------------------------------------------*/ -/* Sliding Windows */ -struct sliding_window { - seed_id_t seed_id; - int16_t lower_bound; /* lolipop */ - int16_t upper_bound; /* lolipop */ - int16_t min_listed; /* lolipop */ - uint8_t flags; /* Is used, Trickle param, Is listed */ - uint8_t count; -}; - -#define SLIDING_WINDOW_U_BIT 0x80 /* Is used */ -#define SLIDING_WINDOW_M_BIT 0x40 /* Window trickle parametrization */ -#define SLIDING_WINDOW_L_BIT 0x20 /* Current ICMP message lists us */ -#define SLIDING_WINDOW_B_BIT 0x10 /* Used when updating bounds */ - -/** - * \brief Is Occupied sliding window location w - * w: pointer to a sliding window - */ -#define SLIDING_WINDOW_IS_USED(w) ((w)->flags & SLIDING_WINDOW_U_BIT) - -/** - * \brief Set 'Is Used' bit for window w - * w: pointer to a sliding window - */ -#define SLIDING_WINDOW_IS_USED_SET(w) ((w)->flags |= SLIDING_WINDOW_U_BIT) - -/** - * \brief Clear 'Is Used' bit for window w - * w: pointer to a sliding window - */ -#define SLIDING_WINDOW_IS_USED_CLR(w) ((w)->flags &= ~SLIDING_WINDOW_U_BIT) -#define window_free(w) SLIDING_WINDOW_IS_USED_CLR(w) - -/** - * \brief Set 'Is Seen' bit for window w - * w: pointer to a sliding window - */ -#define SLIDING_WINDOW_LISTED_SET(w) ((w)->flags |= SLIDING_WINDOW_L_BIT) - -/** - * \brief Clear 'Is Seen' bit for window w - * w: pointer to a sliding window - */ -#define SLIDING_WINDOW_LISTED_CLR(w) ((w)->flags &= ~SLIDING_WINDOW_L_BIT) - -/** - * \brief Is the sliding window at location w listed in current ICMP message? - * w: pointer to a sliding window - */ -#define SLIDING_WINDOW_IS_LISTED(w) ((w)->flags & SLIDING_WINDOW_L_BIT) - -/** - * \brief Set M bit for window w - * w: pointer to a sliding window - */ -#define SLIDING_WINDOW_M_SET(w) ((w)->flags |= SLIDING_WINDOW_M_BIT) - -/** - * \brief Clear M bit for window w - * w: pointer to a sliding window - */ -#define SLIDING_WINDOW_M_CLR(w) ((w)->flags &= ~SLIDING_WINDOW_M_BIT) - -/** - * \brief Retrieve trickle parametrization for sliding window at location w - * w: pointer to a sliding window - */ -#define SLIDING_WINDOW_GET_M(w) \ - ((uint8_t)(((w)->flags & SLIDING_WINDOW_M_BIT) == SLIDING_WINDOW_M_BIT)) -/*---------------------------------------------------------------------------*/ -/* Multicast Packet Buffers */ -struct mcast_packet { -#if ROLL_TM_SHORT_SEEDS - /* Short seeds are stored inside the message */ - seed_id_t seed_id; -#endif - uint32_t active; /* Starts at 0 and increments */ - uint32_t dwell; /* Starts at 0 and increments */ - uint16_t buff_len; - uint16_t seq_val; /* host-byte order */ - struct sliding_window *sw; /* Pointer to the SW this packet belongs to */ - uint8_t flags; /* Is-Used, Must Send, Is Listed */ - uint8_t buff[UIP_BUFSIZE - UIP_LLH_LEN]; -}; - -/* Flag bits */ -#define MCAST_PACKET_U_BIT 0x80 /* Is Used */ -#define MCAST_PACKET_S_BIT 0x20 /* Must Send Next Pass */ -#define MCAST_PACKET_L_BIT 0x10 /* Is listed in ICMP message */ - -/* Fetch a pointer to the Seed ID of a buffered message p */ -#if ROLL_TM_SHORT_SEEDS -#define MCAST_PACKET_GET_SEED(p) ((seed_id_t *)&((p)->seed_id)) -#else -#define MCAST_PACKET_GET_SEED(p) \ - ((seed_id_t *)&((struct uip_ip_hdr *)&(p)->buff[UIP_LLH_LEN])->srcipaddr) -#endif - -/** - * \brief Get the TTL of a buffered packet - * p: pointer to a packet buffer - */ -#define MCAST_PACKET_TTL(p) \ - (((struct uip_ip_hdr *)(p)->buff)->ttl) - -/** - * \brief Set 'Is Used' bit for packet p - * p: pointer to a packet buffer - */ -#define MCAST_PACKET_USED_SET(p) ((p)->flags |= MCAST_PACKET_U_BIT) - -/** - * \brief Clear 'Is Used' bit for packet p - * p: pointer to a packet buffer - */ -#define MCAST_PACKET_USED_CLR(p) ((p)->flags &= ~MCAST_PACKET_U_BIT) - -/** - * \brief Is Occupied buffer location p - */ -#define MCAST_PACKET_IS_USED(p) ((p)->flags & MCAST_PACKET_U_BIT) - -/** - * \brief Must we send this message this pass? - */ -#define MCAST_PACKET_MUST_SEND(p) ((p)->flags & MCAST_PACKET_S_BIT) - -/** - * \brief Set 'Must Send' bit for message p - * p: pointer to a struct mcast_packet - */ -#define MCAST_PACKET_SEND_SET(p) ((p)->flags |= MCAST_PACKET_S_BIT) - -/** - * \brief Clear 'Must Send' bit for message p - * p: pointer to a struct mcast_packet - */ -#define MCAST_PACKET_SEND_CLR(p) ((p)->flags &= ~MCAST_PACKET_S_BIT) - -/** - * \brief Is the message p listed in current ICMP message? - * p: pointer to a struct mcast_packet - */ -#define MCAST_PACKET_IS_LISTED(p) ((p)->flags & MCAST_PACKET_L_BIT) - -/** - * \brief Set 'Is Listed' bit for message p - * p: pointer to a struct mcast_packet - */ -#define MCAST_PACKET_LISTED_SET(p) ((p)->flags |= MCAST_PACKET_L_BIT) - -/** - * \brief Clear 'Is Listed' bit for message p - * p: pointer to a struct mcast_packet - */ -#define MCAST_PACKET_LISTED_CLR(p) ((p)->flags &= ~MCAST_PACKET_L_BIT) - -/** - * \brief Free a multicast packet buffer - * p: pointer to a struct mcast_packet - */ -#define MCAST_PACKET_FREE(p) ((p)->flags = 0) -/*---------------------------------------------------------------------------*/ -/* Sequence Lists in Multicast Trickle ICMP messages */ -struct sequence_list_header { - uint8_t flags; /* S: Seed ID length, M: Trickle parametrization */ - uint8_t seq_len; - seed_id_t seed_id; -}; - -#define SEQUENCE_LIST_S_BIT 0x80 -#define SEQUENCE_LIST_M_BIT 0x40 -#define SEQUENCE_LIST_RES 0x3F - -/** - * \brief Get the Trickle Parametrization for an ICMPv6 sequence list - * l: pointer to a sequence list structure - */ -#define SEQUENCE_LIST_GET_M(l) \ - ((uint8_t)(((l)->flags & SEQUENCE_LIST_M_BIT) == SEQUENCE_LIST_M_BIT)) - -/** - * \brief Get the Seed ID Length for an ICMPv6 sequence list - * l: pointer to a sequence list structure - */ -#define SEQUENCE_LIST_GET_S(l) \ - ((uint8_t)(((l)->flags & SEQUENCE_LIST_S_BIT) == SEQUENCE_LIST_S_BIT)) -/*---------------------------------------------------------------------------*/ -/* Trickle Multicast HBH Option */ -struct hbho_mcast { - uint8_t type; - uint8_t len; -#if ROLL_TM_SHORT_SEEDS - seed_id_t seed_id; -#endif - uint8_t flags; /* M, Seq ID MSB */ - uint8_t seq_id_lsb; -#if !ROLL_TM_SHORT_SEEDS - /* Need to Pad to 8 bytes with PadN */ - uint8_t padn_type; /* 1: PadN */ - uint8_t padn_len; /* 0->2 bytes */ -#endif -}; - -#define HBHO_OPT_TYPE_TRICKLE 0x0C -#define HBHO_LEN_LONG_SEED 2 -#define HBHO_LEN_SHORT_SEED 4 -#define HBHO_TOTAL_LEN 8 -/** - * \brief Get the Trickle Parametrization for a multicast HBHO header - * m: pointer to the HBHO header - */ -#define HBH_GET_M(h) (((h)->flags & 0x80) == 0x80) - -/** - * \brief Set the Trickle Parametrization bit for a multicast HBHO header - * m: pointer to the HBHO header - */ -#define HBH_SET_M(h) ((h)->flags |= 0x80) - -/** - * \brief Retrieve the Sequence Value MSB from a multicast HBHO header - * m: pointer to the HBHO header - */ -#define HBH_GET_SV_MSB(h) ((h)->flags & 0x7F) -/*---------------------------------------------------------------------------*/ -/* Destination for our ICMPv6 datagrams */ -#if ROLL_TM_CONF_DEST_ALL_NODES -#define roll_tm_create_dest(a) uip_create_linklocal_allnodes_mcast(a) -#else -#define roll_tm_create_dest(a) uip_create_linklocal_allrouters_mcast(a) -#endif -/*---------------------------------------------------------------------------*/ -/* Maintain Stats */ -#if UIP_MCAST6_STATS -static struct roll_tm_stats stats; - -#define ROLL_TM_STATS_ADD(x) stats.x++ -#define ROLL_TM_STATS_INIT() do { memset(&stats, 0, sizeof(stats)); } while(0) -#else /* UIP_MCAST6_STATS */ -#define ROLL_TM_STATS_ADD(x) -#define ROLL_TM_STATS_INIT() -#endif -/*---------------------------------------------------------------------------*/ -/* Internal Data Structures */ -/*---------------------------------------------------------------------------*/ -static struct trickle_param t[2]; -static struct sliding_window windows[ROLL_TM_WINS]; -static struct mcast_packet buffered_msgs[ROLL_TM_BUFF_NUM]; -/*---------------------------------------------------------------------------*/ -/* Temporary Stores */ -/*---------------------------------------------------------------------------*/ -static struct trickle_param *loctpptr; -static struct sequence_list_header *locslhptr; -static struct sliding_window *locswptr; -static struct sliding_window *iterswptr; -static struct mcast_packet *locmpptr; -static struct hbho_mcast *lochbhmptr; -static uint16_t last_seq; -/*---------------------------------------------------------------------------*/ -/* uIPv6 Pointers */ -/*---------------------------------------------------------------------------*/ -#define UIP_DATA_BUF ((uint8_t *)&uip_buf[uip_l2_l3_hdr_len + UIP_UDPH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) -#define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN]) -#define UIP_EXT_BUF_NEXT ((uint8_t *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN + HBHO_TOTAL_LEN]) -#define UIP_EXT_OPT_FIRST ((struct hbho_mcast *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN + 2]) -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) -#define UIP_ICMP_PAYLOAD ((unsigned char *)&uip_buf[uip_l2_l3_icmp_hdr_len]) -extern uint16_t uip_slen; -/*---------------------------------------------------------------------------*/ -/* Local function prototypes */ -/*---------------------------------------------------------------------------*/ -static void icmp_input(void); -static void icmp_output(void); -static void window_update_bounds(void); -static void reset_trickle_timer(uint8_t); -static void handle_timer(void *); -/*---------------------------------------------------------------------------*/ -/* ROLL TM ICMPv6 handler declaration */ -UIP_ICMP6_HANDLER(roll_tm_icmp_handler, ICMP6_ROLL_TM, - UIP_ICMP6_HANDLER_CODE_ANY, icmp_input); -/*---------------------------------------------------------------------------*/ -/* Return a random number in [I/2, I), for a timer with Imin when the timer's - * current number of doublings is d */ -static clock_time_t -random_interval(clock_time_t i_min, uint8_t d) -{ - clock_time_t min = TRICKLE_TIME(i_min >> 1, d); - - VERBOSE_PRINTF("ROLL TM: Random [%lu, %lu)\n", (unsigned long)min, - (unsigned long)(TRICKLE_TIME(i_min, d))); - - return min + (random_rand() % (TRICKLE_TIME(i_min, d) - 1 - min)); -} -/*---------------------------------------------------------------------------*/ -/* Called at the end of the current interval for timer ptr */ -static void -double_interval(void *ptr) -{ - struct trickle_param *param = (struct trickle_param *)ptr; - int16_t offset; - clock_time_t next; - - /* - * If we got called long past our expiration, store the offset and try to - * compensate this period - */ - offset = (int16_t)(clock_time() - param->t_end); - - /* Calculate next interval */ - if(param->i_current < param->i_max) { - param->i_current++; - } - - param->t_start = param->t_end; - param->t_end = param->t_start + (param->i_min << param->i_current); - - next = random_interval(param->i_min, param->i_current); - if(next > offset) { - next -= offset; - } else { - next = 0; - } - param->t_next = next; - ctimer_set(¶m->ct, param->t_next, handle_timer, (void *)param); - - VERBOSE_PRINTF("ROLL TM: Doubling at %lu (offset %d), Start %lu, End %lu," - " Periodic in %lu\n", clock_time(), offset, - (unsigned long)param->t_start, - (unsigned long)param->t_end, (unsigned long)param->t_next); -} -/*---------------------------------------------------------------------------*/ -/* - * Called at a random point in [I/2,I) of the current interval for ptr - * PARAM is a pointer to the timer that triggered the callback (&t[index]) - */ -static void -handle_timer(void *ptr) -{ - struct trickle_param *param; - clock_time_t diff_last; /* Time diff from last pass */ - clock_time_t diff_start; /* Time diff from interval start */ - uint8_t m; - - param = (struct trickle_param *)ptr; - if(param == &t[0]) { - m = 0; - } else if(param == &t[1]) { - m = 1; - } else { - /* This is an ooops and a serious one too */ - return; - } - - /* Bail out pronto if our uIPv6 stack is not ready to send messages */ - if(uip_ds6_get_link_local(ADDR_PREFERRED) == NULL) { - VERBOSE_PRINTF - ("ROLL TM: Suppressing timer processing. Stack not ready\n"); - reset_trickle_timer(m); - return; - } - - VERBOSE_PRINTF("ROLL TM: M=%u Periodic at %lu, last=%lu\n", - m, (unsigned long)clock_time(), - (unsigned long)param->t_last_trigger); - - /* Temporarily store 'now' in t_next and calculate diffs */ - param->t_next = clock_time(); - diff_last = param->t_next - param->t_last_trigger; - diff_start = param->t_next - param->t_start; - param->t_last_trigger = param->t_next; - - VERBOSE_PRINTF - ("ROLL TM: M=%u Periodic diff from last %lu, from start %lu\n", m, - (unsigned long)diff_last, (unsigned long)diff_start); - - /* Handle all buffered messages */ - for(locmpptr = &buffered_msgs[ROLL_TM_BUFF_NUM - 1]; - locmpptr >= buffered_msgs; locmpptr--) { - if(MCAST_PACKET_IS_USED(locmpptr) - && (SLIDING_WINDOW_GET_M(locmpptr->sw) == m)) { - - /* - * if() - * If the packet was received during the last interval, its reception - * caused an inconsistency (and thus a timer reset). This means that - * the packet was received at about t_start, we increment by diff_start - * - * else() - * If the packet was not received during the last window, it is safe to - * increase its lifetime counters by the time diff from last pass - * - * if active == dwell == 0 but i_current != 0, this is an oops - * (new packet that didn't reset us). We don't handle it - */ - if(locmpptr->active == 0) { - locmpptr->active += diff_start; - locmpptr->dwell += diff_start; - } else { - locmpptr->active += diff_last; - locmpptr->dwell += diff_last; - } - - VERBOSE_PRINTF("ROLL TM: M=%u Packet %u active %lu of %lu\n", - m, locmpptr->seq_val, locmpptr->active, - TRICKLE_ACTIVE(param)); - - if(locmpptr->dwell > TRICKLE_DWELL(param)) { - locmpptr->sw->count--; - PRINTF("ROLL TM: M=%u Free Packet %u (%lu > %lu), Window now at %u\n", - m, locmpptr->seq_val, locmpptr->dwell, - TRICKLE_DWELL(param), locmpptr->sw->count); - if(locmpptr->sw->count == 0) { - PRINTF("ROLL TM: M=%u Free Window ", m); - PRINT_SEED(&locmpptr->sw->seed_id); - PRINTF("\n"); - window_free(locmpptr->sw); - } - MCAST_PACKET_FREE(locmpptr); - } else if(MCAST_PACKET_TTL(locmpptr) > 0) { - /* Handle multicast transmissions */ - if(locmpptr->active < TRICKLE_ACTIVE(param) && - ((SUPPRESSION_ENABLED(param) && MCAST_PACKET_MUST_SEND(locmpptr)) || - SUPPRESSION_DISABLED(param))) { - PRINTF("ROLL TM: M=%u Periodic - Sending packet from Seed ", m); - PRINT_SEED(&locmpptr->sw->seed_id); - PRINTF(" seq %u\n", locmpptr->seq_val); - uip_len = locmpptr->buff_len; - memcpy(UIP_IP_BUF, &locmpptr->buff, uip_len); - - UIP_MCAST6_STATS_ADD(mcast_fwd); - tcpip_output(NULL); - MCAST_PACKET_SEND_CLR(locmpptr); - watchdog_periodic(); - } - } - } - } - - /* Suppression Enabled - Send an ICMP */ - if(SUPPRESSION_ENABLED(param)) { - if(param->c < param->k) { - icmp_output(); - } - } - - /* Done handling inconsistencies for this timer */ - param->inconsistency = 0; - param->c = 0; - - window_update_bounds(); - - /* Temporarily store 'now' in t_next */ - param->t_next = clock_time(); - if(param->t_next >= param->t_end) { - /* took us too long to process things, double interval asap */ - param->t_next = 0; - } else { - param->t_next = param->t_end - param->t_next; - } - VERBOSE_PRINTF - ("ROLL TM: M=%u Periodic at %lu, Interval End at %lu in %lu\n", m, - (unsigned long)clock_time(), (unsigned long)param->t_end, - (unsigned long)param->t_next); - ctimer_set(¶m->ct, param->t_next, double_interval, (void *)param); - - return; -} -/*---------------------------------------------------------------------------*/ -static void -reset_trickle_timer(uint8_t index) -{ - t[index].t_start = clock_time(); - t[index].t_end = t[index].t_start + (t[index].i_min); - t[index].i_current = 0; - t[index].c = 0; - t[index].t_next = random_interval(t[index].i_min, t[index].i_current); - - VERBOSE_PRINTF - ("ROLL TM: M=%u Reset at %lu, Start %lu, End %lu, New Interval %lu\n", - index, (unsigned long)t[index].t_start, (unsigned long)t[index].t_start, - (unsigned long)t[index].t_end, (unsigned long)t[index].t_next); - - ctimer_set(&t[index].ct, t[index].t_next, handle_timer, (void *)&t[index]); -} -/*---------------------------------------------------------------------------*/ -static struct sliding_window * -window_allocate() -{ - for(iterswptr = &windows[ROLL_TM_WINS - 1]; iterswptr >= windows; - iterswptr--) { - if(!SLIDING_WINDOW_IS_USED(iterswptr)) { - iterswptr->count = 0; - iterswptr->lower_bound = -1; - iterswptr->upper_bound = -1; - iterswptr->min_listed = -1; - return iterswptr; - } - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -static struct sliding_window * -window_lookup(seed_id_t *s, uint8_t m) -{ - for(iterswptr = &windows[ROLL_TM_WINS - 1]; iterswptr >= windows; - iterswptr--) { - VERBOSE_PRINTF("ROLL TM: M=%u (%u) ", SLIDING_WINDOW_GET_M(iterswptr), m); - VERBOSE_PRINT_SEED(&iterswptr->seed_id); - VERBOSE_PRINTF("\n"); - if(seed_id_cmp(s, &iterswptr->seed_id) && - SLIDING_WINDOW_GET_M(iterswptr) == m) { - return iterswptr; - } - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -static void -window_update_bounds() -{ - for(iterswptr = &windows[ROLL_TM_WINS - 1]; iterswptr >= windows; - iterswptr--) { - iterswptr->lower_bound = -1; - } - - for(locmpptr = &buffered_msgs[ROLL_TM_BUFF_NUM - 1]; - locmpptr >= buffered_msgs; locmpptr--) { - if(MCAST_PACKET_IS_USED(locmpptr)) { - iterswptr = locmpptr->sw; - VERBOSE_PRINTF("ROLL TM: Update Bounds: [%d - %d] vs %u\n", - iterswptr->lower_bound, iterswptr->upper_bound, - locmpptr->seq_val); - if(iterswptr->lower_bound < 0 - || SEQ_VAL_IS_LT(locmpptr->seq_val, iterswptr->lower_bound)) { - iterswptr->lower_bound = locmpptr->seq_val; - } - if(iterswptr->upper_bound < 0 || - SEQ_VAL_IS_GT(locmpptr->seq_val, iterswptr->upper_bound)) { - iterswptr->upper_bound = locmpptr->seq_val; - } - } - } -} -/*---------------------------------------------------------------------------*/ -static struct mcast_packet * -buffer_reclaim() -{ - struct sliding_window *largest = windows; - struct mcast_packet *rv; - - for(iterswptr = &windows[ROLL_TM_WINS - 1]; iterswptr >= windows; - iterswptr--) { - if(iterswptr->count > largest->count) { - largest = iterswptr; - } - } - - if(largest->count == 1) { - /* Can't reclaim last entry for a window and this is the largest window */ - return NULL; - } - - PRINTF("ROLL TM: Reclaim from Seed "); - PRINT_SEED(&largest->seed_id); - PRINTF(" M=%u, count was %u\n", - SLIDING_WINDOW_GET_M(largest), largest->count); - /* Find the packet at the lowest bound for the largest window */ - for(locmpptr = &buffered_msgs[ROLL_TM_BUFF_NUM - 1]; - locmpptr >= buffered_msgs; locmpptr--) { - if(MCAST_PACKET_IS_USED(locmpptr) && (locmpptr->sw == largest) && - SEQ_VAL_IS_EQ(locmpptr->seq_val, largest->lower_bound)) { - rv = locmpptr; - PRINTF("ROLL TM: Reclaim seq. val %u\n", locmpptr->seq_val); - MCAST_PACKET_FREE(rv); - largest->count--; - window_update_bounds(); - VERBOSE_PRINTF("ROLL TM: Reclaim - new bounds [%u , %u]\n", - largest->lower_bound, largest->upper_bound); - return rv; - } - } - - /* oops */ - return NULL; -} -/*---------------------------------------------------------------------------*/ -static struct mcast_packet * -buffer_allocate() -{ - for(locmpptr = &buffered_msgs[ROLL_TM_BUFF_NUM - 1]; - locmpptr >= buffered_msgs; locmpptr--) { - if(!MCAST_PACKET_IS_USED(locmpptr)) { - return locmpptr; - } - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -static void -icmp_output() -{ - struct sequence_list_header *sl; - uint8_t *buffer; - uint16_t payload_len; - - PRINTF("ROLL TM: ICMPv6 Out\n"); - - UIP_IP_BUF->vtc = 0x60; - UIP_IP_BUF->tcflow = 0; - UIP_IP_BUF->flow = 0; - UIP_IP_BUF->proto = UIP_PROTO_ICMP6; - UIP_IP_BUF->ttl = ROLL_TM_IP_HOP_LIMIT; - - sl = (struct sequence_list_header *)UIP_ICMP_PAYLOAD; - payload_len = 0; - - VERBOSE_PRINTF("ROLL TM: ICMPv6 Out - Hdr @ %p, payload @ %p\n", UIP_ICMP_BUF, sl); - - for(iterswptr = &windows[ROLL_TM_WINS - 1]; iterswptr >= windows; - iterswptr--) { - if(SLIDING_WINDOW_IS_USED(iterswptr) && iterswptr->count > 0) { - memset(sl, 0, sizeof(struct sequence_list_header)); -#if ROLL_TM_SHORT_SEEDS - sl->flags = SEQUENCE_LIST_S_BIT; -#endif - if(SLIDING_WINDOW_GET_M(iterswptr)) { - sl->flags |= SEQUENCE_LIST_M_BIT; - } - seed_id_cpy(&sl->seed_id, &iterswptr->seed_id); - - PRINTF("ROLL TM: ICMPv6 Out - Seq. F=0x%02x, Seed ID=", sl->flags); - PRINT_SEED(&sl->seed_id); - - buffer = (uint8_t *)sl + sizeof(struct sequence_list_header); - - for(locmpptr = &buffered_msgs[ROLL_TM_BUFF_NUM - 1]; - locmpptr >= buffered_msgs; locmpptr--) { - if(MCAST_PACKET_IS_USED(locmpptr) && - locmpptr->active < TRICKLE_ACTIVE((&t[SLIDING_WINDOW_GET_M(iterswptr)]))) { - if(locmpptr->sw == iterswptr) { - sl->seq_len++; - PRINTF(", %u", locmpptr->seq_val); - *buffer = (uint8_t)(locmpptr->seq_val >> 8); - buffer++; - *buffer = (uint8_t)(locmpptr->seq_val & 0xFF); - buffer++; - } - } - } - PRINTF(", Len=%u\n", sl->seq_len); - - /* Scrap the entire window if it has no content */ - if(sl->seq_len > 0) { - payload_len += sizeof(struct sequence_list_header) + sl->seq_len * 2; - sl = (struct sequence_list_header *)buffer; - } - } - } - - if(payload_len == 0) { - VERBOSE_PRINTF("ROLL TM: ICMPv6 Out - nothing to send\n"); - return; - } - - roll_tm_create_dest(&UIP_IP_BUF->destipaddr); - uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); - - UIP_IP_BUF->len[0] = (UIP_ICMPH_LEN + payload_len) >> 8; - UIP_IP_BUF->len[1] = (UIP_ICMPH_LEN + payload_len) & 0xff; - - UIP_ICMP_BUF->type = ICMP6_ROLL_TM; - UIP_ICMP_BUF->icode = ROLL_TM_ICMP_CODE; - - UIP_ICMP_BUF->icmpchksum = 0; - UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); - - uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + payload_len; - - VERBOSE_PRINTF("ROLL TM: ICMPv6 Out - %u bytes\n", payload_len); - - tcpip_ipv6_output(); - ROLL_TM_STATS_ADD(icmp_out); - return; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Processes an incoming or outgoing multicast message and determines - * whether it should be dropped or accepted - * - * \param in 1: Incoming packet, 0: Outgoing (we are the seed) - * - * \return 0: Drop, 1: Accept - */ -static uint8_t -accept(uint8_t in) -{ - seed_id_t *seed_ptr; - uint8_t m; - uint16_t seq_val; - - PRINTF("ROLL TM: Multicast I/O\n"); - -#if UIP_CONF_IPV6_CHECKS - if(uip_is_addr_mcast_non_routable(&UIP_IP_BUF->destipaddr)) { - PRINTF("ROLL TM: Mcast I/O, bad destination\n"); - UIP_MCAST6_STATS_ADD(mcast_bad); - return UIP_MCAST6_DROP; - } - /* - * Abort transmission if the v6 src is unspecified. This may happen if the - * seed tries to TX while it's still performing DAD or waiting for a prefix - */ - if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) { - PRINTF("ROLL TM: Mcast I/O, bad source\n"); - UIP_MCAST6_STATS_ADD(mcast_bad); - return UIP_MCAST6_DROP; - } -#endif - - /* Check the Next Header field: Must be HBHO */ - if(UIP_IP_BUF->proto != UIP_PROTO_HBHO) { - PRINTF("ROLL TM: Mcast I/O, bad proto\n"); - UIP_MCAST6_STATS_ADD(mcast_bad); - return UIP_MCAST6_DROP; - } else { - /* Check the Option Type */ - if(UIP_EXT_OPT_FIRST->type != HBHO_OPT_TYPE_TRICKLE) { - PRINTF("ROLL TM: Mcast I/O, bad HBHO type\n"); - UIP_MCAST6_STATS_ADD(mcast_bad); - return UIP_MCAST6_DROP; - } - } - lochbhmptr = UIP_EXT_OPT_FIRST; - - PRINTF("ROLL TM: HBHO T=%u, L=%u, M=%u, S=0x%02x%02x\n", - lochbhmptr->type, lochbhmptr->len, HBH_GET_M(lochbhmptr), - HBH_GET_SV_MSB(lochbhmptr), lochbhmptr->seq_id_lsb); - - /* Drop unsupported Seed ID Lengths. S bit: 0->short, 1->long */ -#if ROLL_TM_SHORT_SEEDS - /* Short Seed ID: Len MUST be 4 */ - if(lochbhmptr->len != HBHO_LEN_SHORT_SEED) { - PRINTF("ROLL TM: Mcast I/O, bad length\n"); - UIP_MCAST6_STATS_ADD(mcast_bad); - return UIP_MCAST6_DROP; - } -#else - /* Long Seed ID: Len MUST be 2 (Seed ID is elided) */ - if(lochbhmptr->len != HBHO_LEN_LONG_SEED) { - PRINTF("ROLL TM: Mcast I/O, bad length\n"); - UIP_MCAST6_STATS_ADD(mcast_bad); - return UIP_MCAST6_DROP; - } -#endif - -#if UIP_MCAST6_STATS - if(in == ROLL_TM_DGRAM_IN) { - UIP_MCAST6_STATS_ADD(mcast_in_all); - } -#endif - - /* Is this for a known window? */ -#if ROLL_TM_SHORT_SEEDS - seed_ptr = &lochbhmptr->seed_id; -#else - seed_ptr = &UIP_IP_BUF->srcipaddr; -#endif - m = HBH_GET_M(lochbhmptr); - - locswptr = window_lookup(seed_ptr, m); - - seq_val = lochbhmptr->seq_id_lsb; - seq_val |= HBH_GET_SV_MSB(lochbhmptr) << 8; - - if(locswptr) { - if(SEQ_VAL_IS_LT(seq_val, locswptr->lower_bound)) { - /* Too old, drop */ - PRINTF("ROLL TM: Too old\n"); - UIP_MCAST6_STATS_ADD(mcast_dropped); - return UIP_MCAST6_DROP; - } - for(locmpptr = &buffered_msgs[ROLL_TM_BUFF_NUM - 1]; - locmpptr >= buffered_msgs; locmpptr--) { - if(MCAST_PACKET_IS_USED(locmpptr) && - locmpptr->sw == locswptr && - SLIDING_WINDOW_GET_M(locmpptr->sw) == m && - SEQ_VAL_IS_EQ(seq_val, locmpptr->seq_val)) { - /* Seen before , drop */ - PRINTF("ROLL TM: Seen before\n"); - UIP_MCAST6_STATS_ADD(mcast_dropped); - return UIP_MCAST6_DROP; - } - } - } - - PRINTF("ROLL TM: New message\n"); - - /* We have not seen this message before */ - /* Allocate a window if we have to */ - if(!locswptr) { - locswptr = window_allocate(); - PRINTF("ROLL TM: New seed\n"); - } - if(!locswptr) { - /* Couldn't allocate window, drop */ - PRINTF("ROLL TM: Failed to allocate window\n"); - UIP_MCAST6_STATS_ADD(mcast_dropped); - return UIP_MCAST6_DROP; - } - - /* Allocate a buffer */ - locmpptr = buffer_allocate(); - if(!locmpptr) { - PRINTF("ROLL TM: Buffer allocation failed, reclaiming\n"); - locmpptr = buffer_reclaim(); - } - - if(!locmpptr) { - /* Failed to allocate / reclaim a buffer. If the window has only just been - * allocated, free it before dropping */ - PRINTF("ROLL TM: Buffer reclaim failed\n"); - if(locswptr->count == 0) { - window_free(locswptr); - UIP_MCAST6_STATS_ADD(mcast_dropped); - return UIP_MCAST6_DROP; - } - } -#if UIP_MCAST6_STATS - if(in == ROLL_TM_DGRAM_IN) { - UIP_MCAST6_STATS_ADD(mcast_in_unique); - } -#endif - - /* We have a window and we have a buffer. Accept this message */ - /* Set the seed ID and correct M for this window */ - SLIDING_WINDOW_M_CLR(locswptr); - if(m) { - SLIDING_WINDOW_M_SET(locswptr); - } - SLIDING_WINDOW_IS_USED_SET(locswptr); - seed_id_cpy(&locswptr->seed_id, seed_ptr); - PRINTF("ROLL TM: Window for seed "); - PRINT_SEED(&locswptr->seed_id); - PRINTF(" M=%u, count=%u\n", - SLIDING_WINDOW_GET_M(locswptr), locswptr->count); - - /* If this window was previously empty, set its lower bound to this packet */ - if(locswptr->count == 0) { - locswptr->lower_bound = seq_val; - VERBOSE_PRINTF("ROLL TM: New Lower Bound %u\n", locswptr->lower_bound); - } - - /* If this is a new Seq Num, update the window upper bound */ - if(locswptr->count == 0 || SEQ_VAL_IS_GT(seq_val, locswptr->upper_bound)) { - locswptr->upper_bound = seq_val; - VERBOSE_PRINTF("ROLL TM: New Upper Bound %u\n", locswptr->upper_bound); - } - - locswptr->count++; - - memset(locmpptr, 0, sizeof(struct mcast_packet)); - memcpy(&locmpptr->buff, UIP_IP_BUF, uip_len); - locmpptr->sw = locswptr; - locmpptr->buff_len = uip_len; - locmpptr->seq_val = seq_val; - MCAST_PACKET_USED_SET(locmpptr); - - PRINTF("ROLL TM: Window for seed "); - PRINT_SEED(&locswptr->seed_id); - PRINTF(" M=%u, %u values within [%u , %u]\n", - SLIDING_WINDOW_GET_M(locswptr), locswptr->count, - locswptr->lower_bound, locswptr->upper_bound); - - /* - * If this is an incoming packet, it is inconsistent and we need to decrement - * its TTL before we start forwarding it. - * If on the other hand we are the seed, the caller will trigger a - * transmission so we don't flag inconsistency and we leave the TTL alone - */ - if(in == ROLL_TM_DGRAM_IN) { - MCAST_PACKET_SEND_SET(locmpptr); - MCAST_PACKET_TTL(locmpptr)--; - - t[m].inconsistency = 1; - - PRINTF("ROLL TM: Inconsistency. Reset T%u\n", m); - reset_trickle_timer(m); - } - - /* Deliver if necessary */ - return UIP_MCAST6_ACCEPT; -} -/*---------------------------------------------------------------------------*/ -/* ROLL TM ICMPv6 Input Handler */ -static void -icmp_input() -{ - uint8_t inconsistency; - uint16_t *seq_ptr; - uint16_t *end_ptr; - uint16_t val; - -#if UIP_CONF_IPV6_CHECKS - if(!uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)) { - PRINTF("ROLL TM: ICMPv6 In, bad source "); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF(" to "); - PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF("\n"); - ROLL_TM_STATS_ADD(icmp_bad); - return; - } - - if(!uip_is_addr_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr) - && !uip_is_addr_linklocal_allrouters_mcast(&UIP_IP_BUF->destipaddr)) { - PRINTF("ROLL TM: ICMPv6 In, bad destination\n"); - ROLL_TM_STATS_ADD(icmp_bad); - return; - } - - if(UIP_ICMP_BUF->icode != ROLL_TM_ICMP_CODE) { - PRINTF("ROLL TM: ICMPv6 In, bad ICMP code\n"); - ROLL_TM_STATS_ADD(icmp_bad); - return; - } - - if(UIP_IP_BUF->ttl != ROLL_TM_IP_HOP_LIMIT) { - PRINTF("ROLL TM: ICMPv6 In, bad TTL\n"); - ROLL_TM_STATS_ADD(icmp_bad); - return; - } -#endif - - PRINTF("ROLL TM: ICMPv6 In from "); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF(" len %u, ext %u\n", uip_len, uip_ext_len); - - ROLL_TM_STATS_ADD(icmp_in); - - /* Reset Is-Listed bit for all windows */ - for(iterswptr = &windows[ROLL_TM_WINS - 1]; iterswptr >= windows; - iterswptr--) { - SLIDING_WINDOW_LISTED_CLR(iterswptr); - } - - /* Reset Is-Listed bit for all cached packets */ - for(locmpptr = &buffered_msgs[ROLL_TM_BUFF_NUM - 1]; - locmpptr >= buffered_msgs; locmpptr--) { - MCAST_PACKET_LISTED_CLR(locmpptr); - } - - locslhptr = (struct sequence_list_header *)UIP_ICMP_PAYLOAD; - - VERBOSE_PRINTF("ROLL TM: ICMPv6 In, parse from %p to %p\n", - UIP_ICMP_PAYLOAD, - (uint8_t *)UIP_ICMP_PAYLOAD + uip_len - - uip_l2_l3_icmp_hdr_len); - while(locslhptr < - (struct sequence_list_header *)((uint8_t *)UIP_ICMP_PAYLOAD + - uip_len - uip_l2_l3_icmp_hdr_len)) { - VERBOSE_PRINTF("ROLL TM: ICMPv6 In, seq hdr @ %p\n", locslhptr); - - if((locslhptr->flags & SEQUENCE_LIST_RES) != 0) { - PRINTF("ROLL TM: ICMPv6 In, non-zero reserved bits\n"); - goto drop; - } - - /* Drop unsupported Seed ID Lengths. S bit: 0->short, 1->long */ -#if ROLL_TM_SHORT_SEEDS - if(!SEQUENCE_LIST_GET_S(locslhptr)) { - ROLL_TM_STATS_ADD(icmp_bad); - goto drop; - } -#else - if(SEQUENCE_LIST_GET_S(locslhptr)) { - ROLL_TM_STATS_ADD(icmp_bad); - goto drop; - } -#endif - - PRINTF("ROLL TM: ICMPv6 In, Sequence List for Seed ID "); - PRINT_SEED(&locslhptr->seed_id); - PRINTF(" M=%u, S=%u, Len=%u\n", SEQUENCE_LIST_GET_M(locslhptr), - SEQUENCE_LIST_GET_S(locslhptr), locslhptr->seq_len); - - seq_ptr = (uint16_t *)((uint8_t *)locslhptr - + sizeof(struct sequence_list_header)); - end_ptr = (uint16_t *)((uint8_t *)locslhptr - + sizeof(struct sequence_list_header) + - locslhptr->seq_len * 2); - - /* Fetch a pointer to the corresponding trickle timer */ - loctpptr = &t[SEQUENCE_LIST_GET_M(locslhptr)]; - - locswptr = NULL; - - /* Find the sliding window for this Seed ID */ - locswptr = window_lookup(&locslhptr->seed_id, - SEQUENCE_LIST_GET_M(locslhptr)); - - /* If we have a window, iterate sequence values and check consistency */ - if(locswptr) { - SLIDING_WINDOW_LISTED_SET(locswptr); - locswptr->min_listed = -1; - PRINTF("ROLL TM: ICMPv6 In, Window bounds [%u , %u]\n", - locswptr->lower_bound, locswptr->upper_bound); - for(; seq_ptr < end_ptr; seq_ptr++) { - /* Check for "They have new" */ - /* If an advertised seq. val is GT our upper bound */ - val = uip_htons(*seq_ptr); - PRINTF("ROLL TM: ICMPv6 In, Check seq %u @ %p\n", val, seq_ptr); - if(SEQ_VAL_IS_GT(val, locswptr->upper_bound)) { - PRINTF("ROLL TM: Inconsistency - Advertised Seq. ID %u GT upper" - " bound %u\n", val, locswptr->upper_bound); - loctpptr->inconsistency = 1; - } - - /* If an advertised seq. val is within our bounds */ - if((SEQ_VAL_IS_LT(val, locswptr->upper_bound) || - SEQ_VAL_IS_EQ(val, locswptr->upper_bound)) && - (SEQ_VAL_IS_GT(val, locswptr->lower_bound) || - SEQ_VAL_IS_EQ(val, locswptr->lower_bound))) { - - inconsistency = 1; - /* Check if the advertised sequence is in our buffer */ - for(locmpptr = &buffered_msgs[ROLL_TM_BUFF_NUM - 1]; - locmpptr >= buffered_msgs; locmpptr--) { - if(MCAST_PACKET_IS_USED(locmpptr) && locmpptr->sw == locswptr) { - if(SEQ_VAL_IS_EQ(locmpptr->seq_val, val)) { - - inconsistency = 0; - MCAST_PACKET_LISTED_SET(locmpptr); - PRINTF("ROLL TM: ICMPv6 In, %u listed\n", locmpptr->seq_val); - - /* Update lowest seq. num listed for this window - * We need this to check for "we have new" */ - if(locswptr->min_listed == -1 || - SEQ_VAL_IS_LT(val, locswptr->min_listed)) { - locswptr->min_listed = val; - } - break; - } - } - } - if(inconsistency) { - PRINTF("ROLL TM: Inconsistency - "); - PRINTF("Advertised Seq. ID %u within bounds", val); - PRINTF(" [%u, %u] but no matching entry\n", - locswptr->lower_bound, locswptr->upper_bound); - loctpptr->inconsistency = 1; - } - } - } - } else { - /* A new sliding window in an ICMP message is not explicitly stated - * in the draft as inconsistency. Until this is clarified, we consider - * this to be a point where we diverge from the draft for performance - * improvement reasons (or as some would say, 'this is an extension') */ - PRINTF("ROLL TM: Inconsistency - Advertised window unknown to us\n"); - loctpptr->inconsistency = 1; - } - locslhptr = (struct sequence_list_header *)(((uint8_t *)locslhptr) + - sizeof(struct sequence_list_header) + (2 * locslhptr->seq_len)); - } - /* Done parsing the message */ - - /* Check for "We have new */ - PRINTF("ROLL TM: ICMPv6 In, Check our buffer\n"); - for(locmpptr = &buffered_msgs[ROLL_TM_BUFF_NUM - 1]; - locmpptr >= buffered_msgs; locmpptr--) { - if(MCAST_PACKET_IS_USED(locmpptr)) { - locswptr = locmpptr->sw; - PRINTF("ROLL TM: ICMPv6 In, "); - PRINTF("Check %u, Seed L: %u, This L: %u Min L: %d\n", - locmpptr->seq_val, SLIDING_WINDOW_IS_LISTED(locswptr), - MCAST_PACKET_IS_LISTED(locmpptr), locswptr->min_listed); - - /* Point to the sliding window's trickle param */ - loctpptr = &t[SLIDING_WINDOW_GET_M(locswptr)]; - if(!SLIDING_WINDOW_IS_LISTED(locswptr)) { - /* If a buffered packet's Seed ID was not listed */ - PRINTF("ROLL TM: Inconsistency - Seed ID "); - PRINT_SEED(&locswptr->seed_id); - PRINTF(" was not listed\n"); - loctpptr->inconsistency = 1; - MCAST_PACKET_SEND_SET(locmpptr); - } else { - /* This packet was not listed but a prior one was */ - if(!MCAST_PACKET_IS_LISTED(locmpptr) && - (locswptr->min_listed >= 0) && - SEQ_VAL_IS_GT(locmpptr->seq_val, locswptr->min_listed)) { - PRINTF("ROLL TM: Inconsistency - "); - PRINTF("Seq. %u was not listed but %u was\n", - locmpptr->seq_val, locswptr->min_listed); - loctpptr->inconsistency = 1; - MCAST_PACKET_SEND_SET(locmpptr); - } - } - } - } - -drop: - - if(t[0].inconsistency) { - reset_trickle_timer(0); - } else { - t[0].c++; - } - if(t[1].inconsistency) { - reset_trickle_timer(1); - } else { - t[1].c++; - } - - return; -} -/*---------------------------------------------------------------------------*/ -static void -out() -{ - - if(uip_len + HBHO_TOTAL_LEN > UIP_BUFSIZE) { - PRINTF("ROLL TM: Multicast Out can not add HBHO. Packet too long\n"); - goto drop; - } - - /* Slide 'right' by HBHO_TOTAL_LEN bytes */ - memmove(UIP_EXT_BUF_NEXT, UIP_EXT_BUF, uip_len - UIP_IPH_LEN); - memset(UIP_EXT_BUF, 0, HBHO_TOTAL_LEN); - - UIP_EXT_BUF->next = UIP_IP_BUF->proto; - UIP_EXT_BUF->len = 0; - - lochbhmptr = UIP_EXT_OPT_FIRST; - lochbhmptr->type = HBHO_OPT_TYPE_TRICKLE; - - /* Set the sequence ID */ - last_seq = SEQ_VAL_ADD(last_seq, 1); - lochbhmptr->flags = last_seq >> 8; - lochbhmptr->seq_id_lsb = last_seq & 0xFF; -#if ROLL_TM_SHORT_SEEDS - seed_id_cpy(&lochbhmptr->seed_id, &uip_lladdr.addr[UIP_LLADDR_LEN - 2]); - lochbhmptr->len = HBHO_LEN_SHORT_SEED; -#else - lochbhmptr->len = HBHO_LEN_LONG_SEED; - /* PadN */ - lochbhmptr->padn_type = UIP_EXT_HDR_OPT_PADN; - lochbhmptr->padn_len = 0; -#endif - - /* Set the M bit for our outgoing messages, if necessary */ -#if ROLL_TM_SET_M_BIT - HBH_SET_M(lochbhmptr); -#endif - - uip_ext_len += HBHO_TOTAL_LEN; - uip_len += HBHO_TOTAL_LEN; - - /* Update the proto and length field in the v6 header */ - UIP_IP_BUF->proto = UIP_PROTO_HBHO; - UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); - UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); - - PRINTF("ROLL TM: Multicast Out, HBHO: T=%u, L=%u, M=%u, S=0x%02x%02x\n", - lochbhmptr->type, lochbhmptr->len, HBH_GET_M(lochbhmptr), - HBH_GET_SV_MSB(lochbhmptr), lochbhmptr->seq_id_lsb); - - /* - * We need to remember this message and advertise it in subsequent ICMP - * messages. Otherwise, our neighs will think we are inconsistent and will - * bounce it back to us. - * - * Queue this message but don't set its MUST_SEND flag. We reset the trickle - * timer and we send it immediately. We then set uip_len = 0 to stop the core - * from re-sending it. - */ - if(accept(ROLL_TM_DGRAM_OUT)) { - tcpip_output(NULL); - UIP_MCAST6_STATS_ADD(mcast_out); - } - -drop: - uip_slen = 0; - uip_len = 0; - uip_ext_len = 0; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -in() -{ - /* - * We call accept() which will sort out caching and forwarding. Depending - * on accept()'s return value, we then need to signal the core - * whether to deliver this to higher layers - */ - if(accept(ROLL_TM_DGRAM_IN) == UIP_MCAST6_DROP) { - return UIP_MCAST6_DROP; - } - - if(!uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) { - PRINTF("ROLL TM: Not a group member. No further processing\n"); - return UIP_MCAST6_DROP; - } else { - PRINTF("ROLL TM: Ours. Deliver to upper layers\n"); - UIP_MCAST6_STATS_ADD(mcast_in_ours); - return UIP_MCAST6_ACCEPT; - } -} -/*---------------------------------------------------------------------------*/ -static void -init() -{ - PRINTF("ROLL TM: ROLL Multicast - Draft #%u\n", ROLL_TM_VER); - - memset(windows, 0, sizeof(windows)); - memset(buffered_msgs, 0, sizeof(buffered_msgs)); - memset(t, 0, sizeof(t)); - - ROLL_TM_STATS_INIT(); - UIP_MCAST6_STATS_INIT(&stats); - - /* Register the ICMPv6 input handler */ - uip_icmp6_register_input_handler(&roll_tm_icmp_handler); - - for(iterswptr = &windows[ROLL_TM_WINS - 1]; iterswptr >= windows; - iterswptr--) { - iterswptr->lower_bound = -1; - iterswptr->upper_bound = -1; - iterswptr->min_listed = -1; - } - - TIMER_CONFIGURE(0); - reset_trickle_timer(0); - TIMER_CONFIGURE(1); - reset_trickle_timer(1); - return; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief The ROLL TM engine driver - */ -const struct uip_mcast6_driver roll_tm_driver = { - "ROLL TM", - init, - out, - in, -}; -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/ipv6/multicast/roll-tm.h b/net/ip/contiki/ipv6/multicast/roll-tm.h deleted file mode 100644 index 1d90bbc07912e45796a1fc30098e1af8ee348811..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/multicast/roll-tm.h +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (c) 2011, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \addtogroup uip6-multicast - * @{ - */ -/** - * \defgroup roll-tm ROLL Trickle Multicast - * - * IPv6 multicast according to the algorithm in the - * "MCAST Forwarding Using Trickle" internet draft. - * - * The current version of the draft can always be found in - * http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast - * - * This implementation is based on the draft version stored in - * ROLL_TM_VER. - * - * In draft v2, the document was renamed to - * "Multicast Protocol for Low power and Lossy Networks (MPL)" - * Due to very significant changes between draft versions 1 and 2, - * MPL will be implemented as a separate engine and this file here - * will provide legacy support for Draft v1. - * @{ - */ -/** - * \file - * Header file for the implementation of the ROLL-TM multicast engine - * \author - * George Oikonomou - - */ - -#ifndef ROLL_TM_H_ -#define ROLL_TM_H_ - -#include "contiki-conf.h" -#include "contiki/ipv6/multicast/uip-mcast6-stats.h" - -#include -/*---------------------------------------------------------------------------*/ -/* Protocol Constants */ -/*---------------------------------------------------------------------------*/ -#define ROLL_TM_VER 1 /**< Supported Draft Version */ -#define ROLL_TM_ICMP_CODE 0 /**< ROLL TM ICMPv6 code field */ -#define ROLL_TM_IP_HOP_LIMIT 0xFF /**< Hop limit for ICMP messages */ -#define ROLL_TM_INFINITE_REDUNDANCY 0xFF -#define ROLL_TM_DGRAM_OUT 0 -#define ROLL_TM_DGRAM_IN 1 - -/* - * The draft does not currently specify a default number for the trickle - * interval nor a way to derive it. Examples however hint at 100 msec. - * - * In draft terminology, we use an 'aggressive' policy (M=0) and a conservative - * one (M=1). - * - * When experimenting with the two policies on the sky platform, - * an interval of 125ms proves to be way too low: When we have traffic, - * doublings happen after the interval end and periodics fire after point T - * within the interval (and sometimes even after interval end). When traffic - * settles down, the code compensates the offsets. - * - * We consider 125, 250ms etc because they are nice divisors of 1 sec - * (quotient is power of two). For some machines (e.g sky/msp430, - * sensinode/cc243x), this is also a nice number of clock ticks - * - * After experimentation, the values of Imin leading to best performance are: - * ContikiMAC: Imin=64 (500ms) - * Null RDC: imin=16 (125ms) - */ - -/* Configuration for Timer with M=0 (aggressive) */ -#ifdef ROLL_TM_CONF_IMIN_0 -#define ROLL_TM_IMIN_0 ROLL_TM_CONF_IMIN_0 -#else -#define ROLL_TM_IMIN_0 32 /* 250 msec */ -#endif - -#ifdef ROLL_TM_CONF_IMAX_0 -#define ROLL_TM_IMAX_0 ROLL_TM_CONF_IMAX_0 -#else -#define ROLL_TM_IMAX_0 1 /* Imax = 500ms */ -#endif - -#ifdef ROLL_TM_CONF_K_0 -#define ROLL_TM_K_0 ROLL_TM_CONF_K_0 -#else -#define ROLL_TM_K_0 ROLL_TM_INFINITE_REDUNDANCY -#endif - -#ifdef ROLL_TM_CONF_T_ACTIVE_0 -#define ROLL_TM_T_ACTIVE_0 ROLL_TM_CONF_T_ACTIVE_0 -#else -#define ROLL_TM_T_ACTIVE_0 3 -#endif - -#ifdef ROLL_TM_CONF_T_DWELL_0 -#define ROLL_TM_T_DWELL_0 ROLL_TM_CONF_T_DWELL_0 -#else -#define ROLL_TM_T_DWELL_0 11 -#endif - -/* Configuration for Timer with M=1 (conservative) */ -#ifdef ROLL_TM_CONF_IMIN_1 -#define ROLL_TM_IMIN_1 ROLL_TM_CONF_IMIN_1 -#else -#define ROLL_TM_IMIN_1 64 /* 500 msec */ -#endif - -#ifdef ROLL_TM_CONF_IMAX_1 -#define ROLL_TM_IMAX_1 ROLL_TM_CONF_IMAX_1 -#else -#define ROLL_TM_IMAX_1 9 /* Imax = 256 secs */ -#endif - -#ifdef ROLL_TM_CONF_K_1 -#define ROLL_TM_K_1 ROLL_TM_CONF_K_1 -#else -#define ROLL_TM_K_1 1 -#endif - -#ifdef ROLL_TM_CONF_T_ACTIVE_1 -#define ROLL_TM_T_ACTIVE_1 ROLL_TM_CONF_T_ACTIVE_1 -#else -#define ROLL_TM_T_ACTIVE_1 3 -#endif - -#ifdef ROLL_TM_CONF_T_DWELL_1 -#define ROLL_TM_T_DWELL_1 ROLL_TM_CONF_T_DWELL_1 -#else -#define ROLL_TM_T_DWELL_1 12 -#endif -/*---------------------------------------------------------------------------*/ -/* Configuration */ -/*---------------------------------------------------------------------------*/ -/** - * Number of Sliding Windows - * In essence: How many unique sources of simultaneous multicast traffic do we - * want to support for our lowpan - * If a node is seeding two multicast streams, parametrized on different M - * values, then this seed will occupy two different sliding windows - */ -#ifdef ROLL_TM_CONF_WINS -#define ROLL_TM_WINS ROLL_TM_CONF_WINS -#else -#define ROLL_TM_WINS 2 -#endif -/*---------------------------------------------------------------------------*/ -/** - * Maximum Number of Buffered Multicast Messages - * This buffer is shared across all Seed IDs, therefore a new very active Seed - * may eventually occupy all slots. It would make little sense (if any) to - * define support for fewer buffered messages than seeds*2 - */ -#ifdef ROLL_TM_CONF_BUFF_NUM -#define ROLL_TM_BUFF_NUM ROLL_TM_CONF_BUFF_NUM -#else -#define ROLL_TM_BUFF_NUM 6 -#endif -/*---------------------------------------------------------------------------*/ -/** - * Use Short Seed IDs [short: 2, long: 16 (default)] - * It can be argued that we should (and it would be easy to) support both at - * the same time but the draft doesn't list this as a MUST so we opt for - * code/ram savings - */ -#ifdef ROLL_TM_CONF_SHORT_SEEDS -#define ROLL_TM_SHORT_SEEDS ROLL_TM_CONF_SHORT_SEEDS -#else -#define ROLL_TM_SHORT_SEEDS 0 -#endif -/*---------------------------------------------------------------------------*/ -/** - * Destination address for our ICMPv6 advertisements. The draft gives us a - * choice between LL all-nodes or LL all-routers - * - * We use allrouters unless a conf directive chooses otherwise - */ -#ifdef ROLL_TM_CONF_DEST_ALL_NODES -#define ROLL_TM_DEST_ALL_NODES ROLL_TM_CONF_DEST_ALL_NODES -#else -#define ROLL_TM_DEST_ALL_NODES 0 -#endif -/*---------------------------------------------------------------------------*/ -/** - * M param for our outgoing messages - * By default, we set the M bit (conservative). Define this as 0 to clear the - * M bit in our outgoing messages (aggressive) - */ -#ifdef ROLL_TM_CONF_SET_M_BIT -#define ROLL_TM_SET_M_BIT ROLL_TM_CONF_SET_M_BIT -#else -#define ROLL_TM_SET_M_BIT 1 -#endif -/*---------------------------------------------------------------------------*/ -/* Stats datatype */ -/*---------------------------------------------------------------------------*/ -/** - * \brief Multicast stats extension for the ROLL TM engine - */ -struct roll_tm_stats { - /** Number of received ICMP datagrams */ - UIP_MCAST6_STATS_DATATYPE icmp_in; - - /** Number of ICMP datagrams sent */ - UIP_MCAST6_STATS_DATATYPE icmp_out; - - /** Number of malformed ICMP datagrams seen by us */ - UIP_MCAST6_STATS_DATATYPE icmp_bad; -}; -/*---------------------------------------------------------------------------*/ -#endif /* ROLL_TM_H_ */ -/*---------------------------------------------------------------------------*/ -/** @} */ -/** @} */ diff --git a/net/ip/contiki/ipv6/multicast/smrf.c b/net/ip/contiki/ipv6/multicast/smrf.c deleted file mode 100644 index 4f0a50025266269b9d97069fa6bb20b1c726787c..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/multicast/smrf.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \addtogroup smrf-multicast - * @{ - */ -/** - * \file - * This file implements 'Stateless Multicast RPL Forwarding' (SMRF) - * - * \author - * George Oikonomou - - */ - -#include - -#include "contiki.h" -#include "contiki-net.h" -#include "contiki/ipv6/multicast/uip-mcast6.h" -#include "contiki/ipv6/multicast/uip-mcast6-route.h" -#include "contiki/ipv6/multicast/uip-mcast6-stats.h" -#include "contiki/ipv6/multicast/smrf.h" -#include "contiki/rpl/rpl.h" -#include "contiki/netstack.h" -#include "contiki/os/lib/random.h" -#include - -#define DEBUG DEBUG_NONE -#include "contiki/ip/uip-debug.h" - -/*---------------------------------------------------------------------------*/ -/* Macros */ -/*---------------------------------------------------------------------------*/ -/* CCI */ -#define SMRF_FWD_DELAY() NETSTACK_RDC.channel_check_interval() -/* Number of slots in the next 500ms */ -#define SMRF_INTERVAL_COUNT ((CLOCK_SECOND >> 2) / fwd_delay) -/*---------------------------------------------------------------------------*/ -/* Internal Data */ -/*---------------------------------------------------------------------------*/ -static struct ctimer mcast_periodic; -static uint8_t fwd_delay; -static uint8_t fwd_spread; - -/*---------------------------------------------------------------------------*/ -/* uIPv6 Pointers */ -/*---------------------------------------------------------------------------*/ -#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) -/*---------------------------------------------------------------------------*/ -static void -mcast_fwd(struct net_buf *buf, void *p) -{ - UIP_IP_BUF(buf)->ttl--; - tcpip_output(buf, NULL); - uip_len(buf) = 0; - uip_ext_len(buf) = 0; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -in(struct net_buf *buf) -{ - rpl_dag_t *d; /* Our DODAG */ - uip_ipaddr_t *parent_ipaddr; /* Our pref. parent's IPv6 address */ - const uip_lladdr_t *parent_lladdr; /* Our pref. parent's LL address */ - struct net_buf *netbuf; - - /* - * Fetch a pointer to the LL address of our preferred parent - * - * ToDo: This rpl_get_any_dag() call is a dirty replacement of the previous - * rpl_get_dag(RPL_DEFAULT_INSTANCE); - * so that things can compile with the new RPL code. This needs updated to - * read instance ID from the RPL HBHO and use the correct parent accordingly - */ - d = rpl_get_any_dag(); - if(!d) { - UIP_MCAST6_STATS_ADD(mcast_dropped); - return UIP_MCAST6_DROP; - } - - /* Retrieve our preferred parent's LL address */ - parent_ipaddr = rpl_get_parent_ipaddr(d->preferred_parent); - parent_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(parent_ipaddr); - - if(parent_lladdr == NULL) { - UIP_MCAST6_STATS_ADD(mcast_dropped); - return UIP_MCAST6_DROP; - } - - /* - * We accept a datagram if it arrived from our preferred parent, discard - * otherwise. - */ - if(memcmp(parent_lladdr, &ip_buf_ll_src(buf), - UIP_LLADDR_LEN)) { - PRINTF("SMRF: Routable in but SMRF ignored it\n"); - UIP_MCAST6_STATS_ADD(mcast_dropped); - return UIP_MCAST6_DROP; - } - - if(UIP_IP_BUF(buf)->ttl <= 1) { - UIP_MCAST6_STATS_ADD(mcast_dropped); - return UIP_MCAST6_DROP; - } - - UIP_MCAST6_STATS_ADD(mcast_in_all); - UIP_MCAST6_STATS_ADD(mcast_in_unique); - - /* If we have an entry in the mcast routing table, something with - * a higher RPL rank (somewhere down the tree) is a group member */ - if(uip_mcast6_route_lookup(&UIP_IP_BUF(buf)->destipaddr)) { - /* If we enter here, we will definitely forward */ - UIP_MCAST6_STATS_ADD(mcast_fwd); - - /* - * Add a delay (D) of at least SMRF_FWD_DELAY() to compensate for how - * contikimac handles broadcasts. We can't start our TX before the sender - * has finished its own. - */ - fwd_delay = SMRF_FWD_DELAY(); - - /* Finalise D: D = min(SMRF_FWD_DELAY(), SMRF_MIN_FWD_DELAY) */ -#if SMRF_MIN_FWD_DELAY - if(fwd_delay < SMRF_MIN_FWD_DELAY) { - fwd_delay = SMRF_MIN_FWD_DELAY; - } -#endif - - if(fwd_delay == 0) { - /* No delay required, send it, do it now, why wait? */ - UIP_IP_BUF(buf)->ttl--; - tcpip_output(buf, NULL); - UIP_IP_BUF(buf)->ttl++; /* Restore before potential upstack delivery */ - } else { - /* Randomise final delay in [D , D*Spread], step D */ - fwd_spread = SMRF_INTERVAL_COUNT; - if(fwd_spread > SMRF_MAX_SPREAD) { - fwd_spread = SMRF_MAX_SPREAD; - } - if(fwd_spread) { - fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread)); - } - - netbuf = net_buf_clone(buf); - if (netbuf) { - memcpy(net_buf_user_data(netbuf), net_buf_user_data(buf), - buf->user_data_size); - ctimer_set(netbuf, &mcast_periodic, fwd_delay, mcast_fwd, NULL); - } else { - PRINTF("SMRF: cannot clone net buffer\n"); - } - } - PRINTF("SMRF: %u bytes: fwd in %u [%u]\n", - uip_len(buf), fwd_delay, fwd_spread); - } - - /* Done with this packet unless we are a member of the mcast group */ - if(!uip_ds6_is_my_maddr(&UIP_IP_BUF(buf)->destipaddr)) { - PRINTF("SMRF: Not a group member. No further processing\n"); - return UIP_MCAST6_DROP; - } else { - PRINTF("SMRF: Ours. Deliver to upper layers\n"); - UIP_MCAST6_STATS_ADD(mcast_in_ours); - return UIP_MCAST6_ACCEPT; - } -} -/*---------------------------------------------------------------------------*/ -static void -init() -{ - UIP_MCAST6_STATS_INIT(NULL); - - uip_mcast6_route_init(); -} -/*---------------------------------------------------------------------------*/ -static void -out() -{ - return; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief The SMRF engine driver - */ -const struct uip_mcast6_driver smrf_driver = { - "SMRF", - init, - out, - in, -}; -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/ipv6/multicast/smrf.h b/net/ip/contiki/ipv6/multicast/smrf.h deleted file mode 100644 index 51dcf216e29d473edd46ddc43245f20f3b7c79ef..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/multicast/smrf.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2011, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \addtogroup uip6-multicast - * @{ - */ -/** - * \defgroup smrf-multicast 'Stateless Multicast RPL Forwarding' (SMRF) - * - * SMRF will only work in RPL networks in MOP 3 "Storing with Multicast" - * @{ - */ -/** - * \file - * Header file for the SMRF forwarding engine - * - * \author - * George Oikonomou - - */ - -#ifndef SMRF_H_ -#define SMRF_H_ - -#include "contiki-conf.h" - -#include -/*---------------------------------------------------------------------------*/ -/* Configuration */ -/*---------------------------------------------------------------------------*/ -/* Fmin */ -#ifdef SMRF_CONF_MIN_FWD_DELAY -#define SMRF_MIN_FWD_DELAY SMRF_CONF_MIN_FWD_DELAY -#else -#define SMRF_MIN_FWD_DELAY 4 -#endif - -/* Max Spread */ -#ifdef SMRF_CONF_MAX_SPREAD -#define SMRF_MAX_SPREAD SMRF_CONF_MAX_SPREAD -#else -#define SMRF_MAX_SPREAD 4 -#endif -/*---------------------------------------------------------------------------*/ -/* Stats datatype */ -/*---------------------------------------------------------------------------*/ -struct smrf_stats { - uint16_t mcast_in_unique; - uint16_t mcast_in_all; /* At layer 3 */ - uint16_t mcast_in_ours; /* Unique and we are a group member */ - uint16_t mcast_fwd; /* Forwarded by us but we are not the seed */ - uint16_t mcast_out; /* We are the seed */ - uint16_t mcast_bad; - uint16_t mcast_dropped; -}; -/*---------------------------------------------------------------------------*/ -#endif /* SMRF_H_ */ -/*---------------------------------------------------------------------------*/ -/** @} */ -/** @} */ diff --git a/net/ip/contiki/ipv6/multicast/uip-mcast6-engines.h b/net/ip/contiki/ipv6/multicast/uip-mcast6-engines.h deleted file mode 100644 index f4bff657aae8144e71b2b9eea29a9db70b93419e..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/multicast/uip-mcast6-engines.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2011, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \addtogroup uip6-multicast - * @{ - */ -/** - * \file - * Header file with definition of multicast engine constants - * - * When writing a new engine, add it here with a unique number and - * then modify uip-mcast6.h accordingly - * - * \author - * George Oikonomou - - */ - -#ifndef UIP_MCAST6_ENGINES_H_ -#define UIP_MCAST6_ENGINES_H_ - -#define UIP_MCAST6_ENGINE_NONE 0 /**< Selecting this disables mcast */ -#define UIP_MCAST6_ENGINE_SMRF 1 /**< The SMRF engine */ -#define UIP_MCAST6_ENGINE_ROLL_TM 2 /**< The ROLL TM engine */ - -#endif /* UIP_MCAST6_ENGINES_H_ */ -/** @} */ diff --git a/net/ip/contiki/ipv6/multicast/uip-mcast6-route.c b/net/ip/contiki/ipv6/multicast/uip-mcast6-route.c deleted file mode 100644 index cd6606d0db7d975f0fff80d6becdf793b65362fb..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/multicast/uip-mcast6-route.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2011, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/** - * \addtogroup uip6-multicast - * @{ - */ -/** - * \file - * Multicast routing table manipulation - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" -#include "lib/list.h" -#include "lib/memb.h" -#include "contiki/ip/uip.h" -#include "contiki/ipv6/multicast/uip-mcast6-route.h" - -#include -#include - -/*---------------------------------------------------------------------------*/ -/* Size of the multicast routing table */ -#ifdef UIP_MCAST6_ROUTE_CONF_ROUTES -#define UIP_MCAST6_ROUTE_ROUTES UIP_MCAST6_ROUTE_CONF_ROUTES -#else -#define UIP_MCAST6_ROUTE_ROUTES 1 -#endif /* UIP_CONF_DS6_MCAST_ROUTES */ -/*---------------------------------------------------------------------------*/ -LIST(mcast_route_list); -MEMB(mcast_route_memb, uip_mcast6_route_t, UIP_MCAST6_ROUTE_ROUTES); - -static uip_mcast6_route_t *locmcastrt; -/*---------------------------------------------------------------------------*/ -uip_mcast6_route_t * -uip_mcast6_route_lookup(uip_ipaddr_t *group) -{ - locmcastrt = NULL; - for(locmcastrt = list_head(mcast_route_list); - locmcastrt != NULL; - locmcastrt = list_item_next(locmcastrt)) { - if(uip_ipaddr_cmp(&locmcastrt->group, group)) { - return locmcastrt; - } - } - - return NULL; -} -/*---------------------------------------------------------------------------*/ -uip_mcast6_route_t * -uip_mcast6_route_add(uip_ipaddr_t *group) -{ - /* _lookup must return NULL, i.e. the prefix does not exist in our table */ - locmcastrt = uip_mcast6_route_lookup(group); - if(locmcastrt == NULL) { - /* Allocate an entry and add the group to the list */ - locmcastrt = memb_alloc(&mcast_route_memb); - if(locmcastrt == NULL) { - return NULL; - } - list_add(mcast_route_list, locmcastrt); - } - - /* Reaching here means we either found the prefix or allocated a new one */ - - uip_ipaddr_copy(&(locmcastrt->group), group); - - return locmcastrt; -} -/*---------------------------------------------------------------------------*/ -void -uip_mcast6_route_rm(uip_mcast6_route_t *route) -{ - /* Make sure it's actually in the list */ - for(locmcastrt = list_head(mcast_route_list); - locmcastrt != NULL; - locmcastrt = list_item_next(locmcastrt)) { - if(locmcastrt == route) { - list_remove(mcast_route_list, route); - memb_free(&mcast_route_memb, route); - return; - } - } -} -/*---------------------------------------------------------------------------*/ -uip_mcast6_route_t * -uip_mcast6_route_list_head(void) -{ - return list_head(mcast_route_list); -} -/*---------------------------------------------------------------------------*/ -int -uip_mcast6_route_count(void) -{ - return list_length(mcast_route_list); -} -/*---------------------------------------------------------------------------*/ -void -uip_mcast6_route_init() -{ - memb_init(&mcast_route_memb); - list_init(mcast_route_list); -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/ipv6/multicast/uip-mcast6-route.h b/net/ip/contiki/ipv6/multicast/uip-mcast6-route.h deleted file mode 100644 index e0ecd70c733fa86a852db2148c2174ac5d0a605d..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/multicast/uip-mcast6-route.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2011, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/** - * \addtogroup uip6-multicast - * @{ - */ -/** - * \file - * Header file for multicast routing table manipulation - * - * \author - * George Oikonomou - - */ -#ifndef UIP_MCAST6_ROUTE_H_ -#define UIP_MCAST6_ROUTE_H_ - -#include "contiki.h" -#include "contiki/ip/uip.h" - -#include -/*---------------------------------------------------------------------------*/ -/** \brief An entry in the multicast routing table */ -typedef struct uip_mcast6_route { - struct uip_mcast6_route *next; /**< Routes are arranged in a linked list */ - uip_ipaddr_t group; /**< The multicast group */ - uint32_t lifetime; /**< Entry lifetime seconds */ - void *dag; /**< Pointer to an rpl_dag_t struct */ -} uip_mcast6_route_t; -/*---------------------------------------------------------------------------*/ -/** \name Multicast Routing Table Manipulation */ -/** @{ */ - -/** - * \brief Lookup a multicast route - * \param group A pointer to the multicast group to be searched for - * \return A pointer to the new routing entry, or NULL if the route could not - * be found - */ -uip_mcast6_route_t *uip_mcast6_route_lookup(uip_ipaddr_t *group); - -/** - * \brief Add a multicast route - * \param group A pointer to the multicast group to be added - * \return A pointer to the new route, or NULL if the route could not be added - */ -uip_mcast6_route_t *uip_mcast6_route_add(uip_ipaddr_t *group); - -/** - * \brief Remove a multicast route - * \param route A pointer to the route to be removed - */ -void uip_mcast6_route_rm(uip_mcast6_route_t *route); - -/** - * \brief Retrieve the count of multicast routes - * \return The number of multicast routes - */ -int uip_mcast6_route_count(void); - -/** - * \brief Retrieve a pointer to the start of the multicast routes list - * \return A pointer to the start of the multicast routes - * - * If the multicast routes list is empty, this function will return NULL - */ -uip_mcast6_route_t *uip_mcast6_route_list_head(void); -/*---------------------------------------------------------------------------*/ -/** - * \brief Multicast routing table init routine - * - * Multicast routing tables are not necessarily required by all - * multicast engines. For instance, trickle multicast does not rely on - * the existence of a routing table. Therefore, this function here - * should be invoked by each engine's init routine only if the relevant - * functionality is required. This is also why this function should not - * get hooked into the uip-ds6 core. - */ -void uip_mcast6_route_init(void); -/** @} */ - -#endif /* UIP_MCAST6_ROUTE_H_ */ -/** @} */ diff --git a/net/ip/contiki/ipv6/multicast/uip-mcast6-stats.c b/net/ip/contiki/ipv6/multicast/uip-mcast6-stats.c deleted file mode 100644 index 9b4ac02b0908f6cbd58de6f80c6ff90859f099bc..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/multicast/uip-mcast6-stats.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2014, University of Bristol - http://www.bris.ac.uk - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/** - * \addtogroup uip6-multicast - * @{ - */ -/** - * \file - * IPv6 multicast forwarding stats maintenance - * - * \author - * George Oikonomou - - */ -#include "contiki/ipv6/multicast/uip-mcast6-stats.h" - -#include -/*---------------------------------------------------------------------------*/ -uip_mcast6_stats_t uip_mcast6_stats; -/*---------------------------------------------------------------------------*/ -void -uip_mcast6_stats_init(void *stats) -{ - memset(&uip_mcast6_stats, 0, sizeof(uip_mcast6_stats)); - uip_mcast6_stats.engine_stats = stats; -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/ipv6/multicast/uip-mcast6-stats.h b/net/ip/contiki/ipv6/multicast/uip-mcast6-stats.h deleted file mode 100644 index 263758b66085904714ff4702dc5d84a6ffa7cd8c..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/multicast/uip-mcast6-stats.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2014, University of Bristol - http://www.bris.ac.uk - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/** - * \addtogroup uip6-multicast - * @{ - */ -/** - * \file - * Header file for IPv6 multicast forwarding stats maintenance - * - * \author - * George Oikonomou - - */ -#ifndef UIP_MCAST6_STATS_H_ -#define UIP_MCAST6_STATS_H_ -/*---------------------------------------------------------------------------*/ -#include "contiki-conf.h" - -#include -/*---------------------------------------------------------------------------*/ -/* The platform can override the stats datatype */ -#ifdef UIP_MCAST6_CONF_STATS_DATATYPE -#define UIP_MCAST6_STATS_DATATYPE UIP_MCAST6_CONF_STATS_DATATYPE -#else -#define UIP_MCAST6_STATS_DATATYPE uint16_t -#endif -/*---------------------------------------------------------------------------*/ -#ifdef UIP_MCAST6_CONF_STATS -#define UIP_MCAST6_STATS UIP_MCAST6_CONF_STATS -#else -#define UIP_MCAST6_STATS 0 -#endif -/*---------------------------------------------------------------------------*/ -/* Stats datatype */ -/*---------------------------------------------------------------------------*/ -/** - * \brief A data structure used to maintain multicast stats - * - * Each engine can extend this structure via the engine_stats field - */ -typedef struct uip_mcast6_stats { - /** Count of unique datagrams received */ - UIP_MCAST6_STATS_DATATYPE mcast_in_unique; - - /** Count of all datagrams received */ - UIP_MCAST6_STATS_DATATYPE mcast_in_all; - - /** Count of datagrams received for a group that we have joined */ - UIP_MCAST6_STATS_DATATYPE mcast_in_ours; - - /** Count of datagrams forwarded by us but we are not the seed */ - UIP_MCAST6_STATS_DATATYPE mcast_fwd; - - /** Count of multicast datagrams originated by us */ - UIP_MCAST6_STATS_DATATYPE mcast_out; - - /** Count of malformed multicast datagrams seen by us */ - UIP_MCAST6_STATS_DATATYPE mcast_bad; - - /** Count of multicast datagrams correclty formed but dropped by us */ - UIP_MCAST6_STATS_DATATYPE mcast_dropped; - - /** Opaque pointer to an engine's additional stats */ - void *engine_stats; -} uip_mcast6_stats_t; -/*---------------------------------------------------------------------------*/ -/* Access macros */ -/*---------------------------------------------------------------------------*/ -#if UIP_MCAST6_STATS -/* Don't access this variable directly, use the macros below */ -extern uip_mcast6_stats_t uip_mcast6_stats; - -#define UIP_MCAST6_STATS_ADD(x) uip_mcast6_stats.x++ -#define UIP_MCAST6_STATS_GET(x) uip_mcast6_stats.x -#define UIP_MCAST6_STATS_INIT(s) uip_mcast6_stats_init(s) -#else /* UIP_MCAST6_STATS */ -#define UIP_MCAST6_STATS_ADD(x) -#define UIP_MCAST6_STATS_GET(x) 0 -#define UIP_MCAST6_STATS_INIT(s) -#endif /* UIP_MCAST6_STATS */ -/*---------------------------------------------------------------------------*/ -/** - * \brief Initialise multicast stats - * \param stats A pointer to a struct holding an engine's additional statistics - */ -void uip_mcast6_stats_init(void *stats); -/*---------------------------------------------------------------------------*/ -#endif /* UIP_MCAST6_STATS_H_ */ -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/ipv6/multicast/uip-mcast6.h b/net/ip/contiki/ipv6/multicast/uip-mcast6.h deleted file mode 100644 index aa439f740a4495766b0840f5d3fc317b471a263d..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/multicast/uip-mcast6.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2011, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \addtogroup uip6 - * @{ - */ -/** - * \defgroup uip6-multicast IPv6 Multicast Forwarding - * - * We currently support 2 engines: - * - 'Stateless Multicast RPL Forwarding' (SMRF) - * RPL does group management as per the RPL docs, SMRF handles datagram - * forwarding - * - 'Multicast Forwarding with Trickle' according to the algorithm described - * in the internet draft: - * http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast - * - * @{ - */ - -/** - * \file - * This header file contains configuration directives for uIPv6 - * multicast support. - * - * \author - * George Oikonomou - - */ - -#ifndef UIP_MCAST6_H_ -#define UIP_MCAST6_H_ - -#include - -#include "contiki-conf.h" -#include "contiki/ipv6/multicast/uip-mcast6-engines.h" -#include "contiki/ipv6/multicast/uip-mcast6-route.h" -#include "contiki/ipv6/multicast/smrf.h" -#include "contiki/ipv6/multicast/roll-tm.h" - -#include -/*---------------------------------------------------------------------------*/ -/* Constants */ -/*---------------------------------------------------------------------------*/ -#define UIP_MCAST6_DROP 0 -#define UIP_MCAST6_ACCEPT 1 -/*---------------------------------------------------------------------------*/ -/* Multicast Address Scopes (RFC 4291 & draft-ietf-6man-multicast-scopes) */ -#define UIP_MCAST6_SCOPE_INTERFACE 0x01 -#define UIP_MCAST6_SCOPE_LINK_LOCAL 0x02 -#define UIP_MCAST6_SCOPE_REALM_LOCAL 0x03 /* draft-ietf-6man-multicast-scopes */ -#define UIP_MCAST6_SCOPE_ADMIN_LOCAL 0x04 -#define UIP_MCAST6_SCOPE_SITE_LOCAL 0x05 -#define UIP_MCAST6_SCOPE_ORG_LOCAL 0x08 -#define UIP_MCAST6_SCOPE_GLOBAL 0x0E -/*---------------------------------------------------------------------------*/ -/* Choose an engine or turn off based on user configuration */ -/*---------------------------------------------------------------------------*/ -#ifdef UIP_MCAST6_CONF_ENGINE -#define UIP_MCAST6_ENGINE UIP_MCAST6_CONF_ENGINE -#else -#define UIP_MCAST6_ENGINE UIP_MCAST6_ENGINE_NONE -#endif -/*---------------------------------------------------------------------------*/ -/* - * Multicast API. Similar to NETSTACK, each engine must define a driver and - * populate the fields with suitable function pointers - */ -/** - * \brief The data structure used to represent a multicast engine - */ -struct uip_mcast6_driver { - /** The driver's name */ - char *name; - - /** Initialize the multicast engine */ - void (* init)(void); - - /** - * \brief Process an outgoing datagram with a multicast IPv6 destination - * address - * - * This may be needed if the multicast engine needs to, for example, - * add IPv6 extension headers to the datagram, cache it, decide it - * needs dropped etc. - * - * It is sometimes desirable to let the engine handle datagram - * dispatch instead of letting the networking core do it. If the - * engine decides to send the datagram itself, it must afterwards - * set uip_len = 0 to prevent the networking core from sending too - */ - void (* out)(void); - - /** - * \brief Process an incoming multicast datagram and determine whether it - * should be delivered up the stack or not. - * - * \return 0: Drop, 1: Deliver - * - * - * When a datagram with a multicast destination address is received, - * the forwarding logic in core is bypassed. Instead, we let the - * multicast engine handle forwarding internally if and as necessary. - * This function is where forwarding logic must be hooked in. - * - * Once the engine is done with forwarding, it must signal via the - * return value whether the datagram needs delivered up the network - * stack. - */ - uint8_t (* in)(struct net_buf *buf); -}; -/*---------------------------------------------------------------------------*/ -/** - * \brief Get a multicast address' scope. - * a is of type uip_ip6addr_t* - */ -#define uip_mcast6_get_address_scope(a) ((a)->u8[1] & 0x0F) -/*---------------------------------------------------------------------------*/ -/* Configure multicast and core/net to play nicely with the selected engine */ -#if UIP_MCAST6_ENGINE - -/* Enable Multicast hooks in the uip6 core */ -#define UIP_CONF_IPV6_MULTICAST 1 - -#if UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_ROLL_TM -#define RPL_CONF_MULTICAST 0 /* Not used by trickle */ -#define UIP_CONF_IPV6_ROLL_TM 1 /* ROLL Trickle ICMP type support */ - -#define UIP_MCAST6 roll_tm_driver -#elif UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_SMRF -#define RPL_CONF_MULTICAST 1 - -#define UIP_MCAST6 smrf_driver -#else -#error "Multicast Enabled with an Unknown Engine." -#error "Check the value of UIP_MCAST6_CONF_ENGINE in conf files." -#endif -#endif /* UIP_MCAST6_ENGINE */ - -extern const struct uip_mcast6_driver UIP_MCAST6; -/*---------------------------------------------------------------------------*/ -/* Configuration Checks */ -/*---------------------------------------------------------------------------*/ -#if RPL_CONF_MULTICAST && (!UIP_CONF_IPV6_RPL) -#error "The selected Multicast mode requires UIP_CONF_IPV6_RPL != 0" -#error "Check the value of UIP_CONF_IPV6_RPL in conf files." -#endif -/*---------------------------------------------------------------------------*/ -#endif /* UIP_MCAST6_H_ */ -/*---------------------------------------------------------------------------*/ -/** @} */ -/** @} */ diff --git a/net/ip/contiki/ipv6/uip-ds6-nbr.c b/net/ip/contiki/ipv6/uip-ds6-nbr.c deleted file mode 100644 index 660b15e22a357871bc544918f275f94596c4fc28..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/uip-ds6-nbr.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (c) 2013, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * - */ - -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * IPv6 Neighbor cache (link-layer/IPv6 address mapping) - * \author Mathilde Durvy - * \author Julien Abeille - * \author Simon Duquennoy - * - */ - -#include -#include -#include -#include "lib/list.h" -#include "contiki/linkaddr.h" -#include "contiki/packetbuf.h" -#include "contiki/ipv6/uip-ds6-nbr.h" - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_IPV6_NBR_CACHE -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#ifdef UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED -#define NEIGHBOR_STATE_CHANGED(n) UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED(n) -void NEIGHBOR_STATE_CHANGED(uip_ds6_nbr_t *n); -#else -#define NEIGHBOR_STATE_CHANGED(n) -#endif /* UIP_DS6_CONF_NEIGHBOR_STATE_CHANGED */ - -#ifdef UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK -#define LINK_NEIGHBOR_CALLBACK(addr, status, numtx) UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK(addr, status, numtx) -void LINK_NEIGHBOR_CALLBACK(const linkaddr_t *addr, int status, int numtx); -#else -#define LINK_NEIGHBOR_CALLBACK(addr, status, numtx) -#endif /* UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK */ - -NBR_TABLE_GLOBAL(uip_ds6_nbr_t, ds6_neighbors); - -/*---------------------------------------------------------------------------*/ -void -uip_ds6_neighbors_init(void) -{ - nbr_table_register(ds6_neighbors, (nbr_table_callback *)uip_ds6_nbr_rm); -} -/*---------------------------------------------------------------------------*/ -uip_ds6_nbr_t * -uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr, - uint8_t isrouter, uint8_t state) -{ - uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr); - if(nbr) { - uip_ipaddr_copy(&nbr->ipaddr, ipaddr); - nbr->isrouter = isrouter; - nbr->state = state; - #if UIP_CONF_IPV6_QUEUE_PKT - uip_packetqueue_new(&nbr->packethandle); - #endif /* UIP_CONF_IPV6_QUEUE_PKT */ - /* timers are set separately, for now we put them in expired state */ - stimer_set(&nbr->reachable, 0); - stimer_set(&nbr->sendns, 0); - nbr->nscount = 0; - PRINTF("Adding neighbor with ip addr "); - PRINT6ADDR(ipaddr); - PRINTF(" link addr "); - PRINTLLADDR(lladdr); - PRINTF(" state %u\n", state); - NEIGHBOR_STATE_CHANGED(nbr); - return nbr; - } else { - PRINTF("uip_ds6_nbr_add drop ip addr "); - PRINT6ADDR(ipaddr); - PRINTF(" link addr (%p) ", lladdr); - PRINTLLADDR(lladdr); - PRINTF(" state %u\n", state); - return NULL; - } -} - -/*---------------------------------------------------------------------------*/ -void -uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr) -{ - if(nbr != NULL) { -#if UIP_CONF_IPV6_QUEUE_PKT - uip_packetqueue_free(&nbr->packethandle); -#endif /* UIP_CONF_IPV6_QUEUE_PKT */ - NEIGHBOR_STATE_CHANGED(nbr); - nbr_table_remove(ds6_neighbors, nbr); - } - return; -} - -/*---------------------------------------------------------------------------*/ -const uip_ipaddr_t * -uip_ds6_nbr_get_ipaddr(const uip_ds6_nbr_t *nbr) -{ - return (nbr != NULL) ? &nbr->ipaddr : NULL; -} - -/*---------------------------------------------------------------------------*/ -const uip_lladdr_t * -uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr) -{ - return (const uip_lladdr_t *)nbr_table_get_lladdr(ds6_neighbors, nbr); -} -/*---------------------------------------------------------------------------*/ -int -uip_ds6_nbr_num(void) -{ - uip_ds6_nbr_t *nbr; - int num; - - num = 0; - for(nbr = nbr_table_head(ds6_neighbors); - nbr != NULL; - nbr = nbr_table_next(ds6_neighbors, nbr)) { - num++; - } - return num; -} -/*---------------------------------------------------------------------------*/ -uip_ds6_nbr_t * -uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr) -{ - uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors); - if(ipaddr != NULL) { - while(nbr != NULL) { - if(uip_ipaddr_cmp(&nbr->ipaddr, ipaddr)) { - return nbr; - } - nbr = nbr_table_next(ds6_neighbors, nbr); - } - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -uip_ds6_nbr_t * -uip_ds6_nbr_ll_lookup(const uip_lladdr_t *lladdr) -{ - return nbr_table_get_from_lladdr(ds6_neighbors, (linkaddr_t*)lladdr); -} - -/*---------------------------------------------------------------------------*/ -uip_ipaddr_t * -uip_ds6_nbr_ipaddr_from_lladdr(const uip_lladdr_t *lladdr) -{ - uip_ds6_nbr_t *nbr = uip_ds6_nbr_ll_lookup(lladdr); - return nbr ? &nbr->ipaddr : NULL; -} - -/*---------------------------------------------------------------------------*/ -const uip_lladdr_t * -uip_ds6_nbr_lladdr_from_ipaddr(const uip_ipaddr_t *ipaddr) -{ - uip_ds6_nbr_t *nbr = uip_ds6_nbr_lookup(ipaddr); - return nbr ? uip_ds6_nbr_get_ll(nbr) : NULL; -} -/*---------------------------------------------------------------------------*/ -void -uip_ds6_link_neighbor_callback(const linkaddr_t *dest, int status, int numtx) -{ - if(linkaddr_cmp(dest, &linkaddr_null)) { - return; - } - - LINK_NEIGHBOR_CALLBACK(dest, status, numtx); - -#if UIP_DS6_LL_NUD - /* From RFC4861, page 72, last paragraph of section 7.3.3: - * - * "In some cases, link-specific information may indicate that a path to - * a neighbor has failed (e.g., the resetting of a virtual circuit). In - * such cases, link-specific information may be used to purge Neighbor - * Cache entries before the Neighbor Unreachability Detection would do - * so. However, link-specific information MUST NOT be used to confirm - * the reachability of a neighbor; such information does not provide - * end-to-end confirmation between neighboring IP layers." - * - * However, we assume that receiving a link layer ack ensures the delivery - * of the transmitted packed to the IP stack of the neighbour. This is a - * fair assumption and allows battery powered nodes save some battery by - * not re-testing the state of a neighbour periodically if it - * acknowledges link packets. */ - if(status == MAC_TX_OK) { - uip_ds6_nbr_t *nbr; - nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest); - if(nbr != NULL && nbr->state != NBR_INCOMPLETE) { - nbr->state = NBR_REACHABLE; - stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000); - PRINTF("uip-ds6-neighbor : received a link layer ACK : "); - PRINTLLADDR((uip_lladdr_t *)dest); - PRINTF(" is reachable.\n"); - } - } -#endif /* UIP_DS6_LL_NUD */ - -} -/*---------------------------------------------------------------------------*/ -void -uip_ds6_neighbor_periodic(struct net_buf *buf) -{ - /* Periodic processing on neighbors */ - uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors); - while(nbr != NULL) { - switch(nbr->state) { - case NBR_REACHABLE: - if(stimer_expired(&nbr->reachable)) { -#if UIP_CONF_IPV6_RPL - /* when a neighbor leave it's REACHABLE state and is a default router, - instead of going to STALE state it enters DELAY state in order to - force a NUD on it. Otherwise, if there is no upward traffic, the - node never knows if the default router is still reachable. This - mimics the 6LoWPAN-ND behavior. - */ - if(uip_ds6_defrt_lookup(&nbr->ipaddr) != NULL) { - PRINTF("REACHABLE: defrt moving to DELAY ("); - PRINT6ADDR(&nbr->ipaddr); - PRINTF(")\n"); - nbr->state = NBR_DELAY; - stimer_set(&nbr->reachable, UIP_ND6_DELAY_FIRST_PROBE_TIME); - nbr->nscount = 0; - } else { - PRINTF("REACHABLE: moving to STALE ("); - PRINT6ADDR(&nbr->ipaddr); - PRINTF(")\n"); - nbr->state = NBR_STALE; - } -#else /* UIP_CONF_IPV6_RPL */ - PRINTF("REACHABLE: moving to STALE ("); - PRINT6ADDR(&nbr->ipaddr); - PRINTF(")\n"); - nbr->state = NBR_STALE; -#endif /* UIP_CONF_IPV6_RPL */ - } - break; -#if UIP_ND6_SEND_NA - case NBR_INCOMPLETE: - if(nbr->nscount >= UIP_ND6_MAX_MULTICAST_SOLICIT) { - uip_ds6_nbr_rm(nbr); - } else if(stimer_expired(&nbr->sendns) && (!buf || uip_len(buf) == 0)) { - nbr->nscount++; - PRINTF("NBR_INCOMPLETE: NS %u\n", nbr->nscount); - uip_nd6_ns_output(buf, NULL, NULL, &nbr->ipaddr); - stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000); - } - break; - case NBR_DELAY: - if(stimer_expired(&nbr->reachable)) { - nbr->state = NBR_PROBE; - nbr->nscount = 0; - PRINTF("DELAY: moving to PROBE\n"); - stimer_set(&nbr->sendns, 0); - } - break; - case NBR_PROBE: - if(nbr->nscount >= UIP_ND6_MAX_UNICAST_SOLICIT) { - uip_ds6_defrt_t *locdefrt; - PRINTF("PROBE END\n"); - if((locdefrt = uip_ds6_defrt_lookup(&nbr->ipaddr)) != NULL) { - if (!locdefrt->isinfinite) { - uip_ds6_defrt_rm(locdefrt); - } - } - uip_ds6_nbr_rm(nbr); - } else if(stimer_expired(&nbr->sendns) && (!buf || uip_len(buf) == 0)) { - nbr->nscount++; - PRINTF("PROBE: NS %u\n", nbr->nscount); - uip_nd6_ns_output(buf, NULL, &nbr->ipaddr, &nbr->ipaddr); - stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000); - } - break; -#endif /* UIP_ND6_SEND_NA */ - default: - break; - } - nbr = nbr_table_next(ds6_neighbors, nbr); - } -} -/*---------------------------------------------------------------------------*/ -uip_ds6_nbr_t * -uip_ds6_get_least_lifetime_neighbor(void) -{ - uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors); - uip_ds6_nbr_t *nbr_expiring = NULL; - while(nbr != NULL) { - if(nbr_expiring != NULL) { - clock_time_t curr = stimer_remaining(&nbr->reachable); - if(curr < stimer_remaining(&nbr->reachable)) { - nbr_expiring = nbr; - } - } else { - nbr_expiring = nbr; - } - nbr = nbr_table_next(ds6_neighbors, nbr); - } - return nbr_expiring; -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/ipv6/uip-ds6-nbr.h b/net/ip/contiki/ipv6/uip-ds6-nbr.h deleted file mode 100644 index 71a2757c2bd284f5607c3a301f796687da25c30e..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/uip-ds6-nbr.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2013, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * - */ - -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * IPv6 Neighbor cache (link-layer/IPv6 address mapping) - * \author Mathilde Durvy - * \author Julien Abeille - * \author Simon Duquennoy - * - */ - -#include - -#include "contiki/ip/uip.h" -#include "contiki/nbr-table.h" -#include "sys/stimer.h" -#include "contiki/ipv6/uip-ds6.h" -#include "contiki/nbr-table.h" - -#if UIP_CONF_IPV6_QUEUE_PKT -#include "contiki/ip/uip-packetqueue.h" -#endif /*UIP_CONF_QUEUE_PKT */ - -#ifndef UIP_DS6_NEIGHBOR_H_ -#define UIP_DS6_NEIGHBOR_H_ - -/*--------------------------------------------------*/ -/** \brief Possible states for the nbr cache entries */ -#define NBR_INCOMPLETE 0 -#define NBR_REACHABLE 1 -#define NBR_STALE 2 -#define NBR_DELAY 3 -#define NBR_PROBE 4 - -NBR_TABLE_DECLARE(ds6_neighbors); - -/** \brief An entry in the nbr cache */ -typedef struct uip_ds6_nbr { - uip_ipaddr_t ipaddr; - struct stimer reachable; - struct stimer sendns; - uint8_t nscount; - uint8_t isrouter; - uint8_t state; - uint16_t link_metric; -#if UIP_CONF_IPV6_QUEUE_PKT - struct uip_packetqueue_handle packethandle; -#define UIP_DS6_NBR_PACKET_LIFETIME CLOCK_SECOND * 4 -#endif /*UIP_CONF_QUEUE_PKT */ -} uip_ds6_nbr_t; - -void uip_ds6_neighbors_init(void); - -/** \brief Neighbor Cache basic routines */ -uip_ds6_nbr_t *uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr, - uint8_t isrouter, uint8_t state); -void uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr); -const uip_lladdr_t *uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr); -const uip_ipaddr_t *uip_ds6_nbr_get_ipaddr(const uip_ds6_nbr_t *nbr); -uip_ds6_nbr_t *uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr); -uip_ds6_nbr_t *uip_ds6_nbr_ll_lookup(const uip_lladdr_t *lladdr); -uip_ipaddr_t *uip_ds6_nbr_ipaddr_from_lladdr(const uip_lladdr_t *lladdr); -const uip_lladdr_t *uip_ds6_nbr_lladdr_from_ipaddr(const uip_ipaddr_t *ipaddr); -void uip_ds6_link_neighbor_callback(const linkaddr_t *dest, int status, int numtx); -void uip_ds6_neighbor_periodic(struct net_buf *buf); -int uip_ds6_nbr_num(void); - -/** - * \brief - * This searches inside the neighbor table for the neighbor that is about to - * expire the next. - * - * \return - * A reference to the neighbor about to expire the next or NULL if - * table is empty. - */ -uip_ds6_nbr_t *uip_ds6_get_least_lifetime_neighbor(void); - -#endif /* UIP_DS6_NEIGHBOR_H_ */ -/** @} */ diff --git a/net/ip/contiki/ipv6/uip-ds6-route.c b/net/ip/contiki/ipv6/uip-ds6-route.c deleted file mode 100644 index 6b78e8d226789162033fc653256026d6930636fc..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/uip-ds6-route.c +++ /dev/null @@ -1,649 +0,0 @@ -/* - * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * Routing table manipulation - */ -#include "contiki/ipv6/uip-ds6.h" -#include "contiki/ip/uip.h" - -#include "lib/list.h" -#include "lib/memb.h" -#include "contiki/nbr-table.h" - -#include - -/* The nbr_routes holds a neighbor table to be able to maintain - information about what routes go through what neighbor. This - neighbor table is registered with the central nbr-table repository - so that it will be maintained along with the rest of the neighbor - tables in the system. */ -NBR_TABLE(struct uip_ds6_route_neighbor_routes, nbr_routes); -MEMB(neighborroutememb, struct uip_ds6_route_neighbor_route, UIP_DS6_ROUTE_NB); - -/* Each route is repressented by a uip_ds6_route_t structure and - memory for each route is allocated from the routememb memory - block. These routes are maintained on the routelist. */ -LIST(routelist); -MEMB(routememb, uip_ds6_route_t, UIP_DS6_ROUTE_NB); - -/* Default routes are held on the defaultrouterlist and their - structures are allocated from the defaultroutermemb memory block.*/ -LIST(defaultrouterlist); -MEMB(defaultroutermemb, uip_ds6_defrt_t, UIP_DS6_DEFRT_NB); - -#if UIP_DS6_NOTIFICATIONS -LIST(notificationlist); -#endif - -static int num_routes = 0; - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_IPV6_ROUTE -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -static void rm_routelist_callback(nbr_table_item_t *ptr); -/*---------------------------------------------------------------------------*/ -#if DEBUG != DEBUG_NONE -static void -assert_nbr_routes_list_sane(void) -{ - uip_ds6_route_t *r; - int count; - - /* Check if the route list has an infinite loop. */ - for(r = uip_ds6_route_head(), - count = 0; - r != NULL && - count < UIP_DS6_ROUTE_NB * 2; - r = uip_ds6_route_next(r), - count++); - - if(count > UIP_DS6_ROUTE_NB) { - printf("uip-ds6-route.c: assert_nbr_routes_list_sane route list is in infinite loop\n"); - } - - /* Make sure that the route list has as many entries as the - num_routes vairable. */ - if(count < num_routes) { - printf("uip-ds6-route.c: assert_nbr_routes_list_sane too few entries on route list: should be %d, is %d, max %d\n", - num_routes, count, UIP_CONF_MAX_ROUTES); - } -} -#endif /* DEBUG != DEBUG_NONE */ -/*---------------------------------------------------------------------------*/ -#if UIP_DS6_NOTIFICATIONS -static void -call_route_callback(int event, uip_ipaddr_t *route, - uip_ipaddr_t *nexthop) -{ - int num; - struct uip_ds6_notification *n; - for(n = list_head(notificationlist); - n != NULL; - n = list_item_next(n)) { - if(event == UIP_DS6_NOTIFICATION_DEFRT_ADD || - event == UIP_DS6_NOTIFICATION_DEFRT_RM) { - num = list_length(defaultrouterlist); - } else { - num = num_routes; - } - n->callback(event, route, nexthop, num); - } -} -/*---------------------------------------------------------------------------*/ -void -uip_ds6_notification_add(struct uip_ds6_notification *n, - uip_ds6_notification_callback c) -{ - if(n != NULL && c != NULL) { - n->callback = c; - list_add(notificationlist, n); - } -} -/*---------------------------------------------------------------------------*/ -void -uip_ds6_notification_rm(struct uip_ds6_notification *n) -{ - list_remove(notificationlist, n); -} -#endif -/*---------------------------------------------------------------------------*/ -void -uip_ds6_route_init(void) -{ - memb_init(&routememb); - list_init(routelist); - nbr_table_register(nbr_routes, - (nbr_table_callback *)rm_routelist_callback); - - memb_init(&defaultroutermemb); - list_init(defaultrouterlist); - -#if UIP_DS6_NOTIFICATIONS - list_init(notificationlist); -#endif -} -/*---------------------------------------------------------------------------*/ -static uip_lladdr_t * -uip_ds6_route_nexthop_lladdr(uip_ds6_route_t *route) -{ - if(route != NULL) { - return (uip_lladdr_t *)nbr_table_get_lladdr(nbr_routes, - route->neighbor_routes); - } else { - return NULL; - } -} -/*---------------------------------------------------------------------------*/ -uip_ipaddr_t * -uip_ds6_route_nexthop(uip_ds6_route_t *route) -{ - if(route != NULL) { - return uip_ds6_nbr_ipaddr_from_lladdr(uip_ds6_route_nexthop_lladdr(route)); - } else { - return NULL; - } -} -/*---------------------------------------------------------------------------*/ -uip_ds6_route_t * -uip_ds6_route_head(void) -{ - return list_head(routelist); -} -/*---------------------------------------------------------------------------*/ -uip_ds6_route_t * -uip_ds6_route_next(uip_ds6_route_t *r) -{ - if(r != NULL) { - uip_ds6_route_t *n = list_item_next(r); - return n; - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -int -uip_ds6_route_num_routes(void) -{ - return num_routes; -} -/*---------------------------------------------------------------------------*/ -uip_ds6_route_t * -uip_ds6_route_lookup(uip_ipaddr_t *addr) -{ - uip_ds6_route_t *r; - uip_ds6_route_t *found_route; - uint8_t longestmatch; - - PRINTF("uip-ds6-route: Looking up route for "); - PRINT6ADDR(addr); - PRINTF("\n"); - - - found_route = NULL; - longestmatch = 0; - for(r = uip_ds6_route_head(); - r != NULL; - r = uip_ds6_route_next(r)) { - if(r->length >= longestmatch && - uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) { - longestmatch = r->length; - found_route = r; - /* check if total match - e.g. all 128 bits do match */ - if(longestmatch == 128) { - break; - } - } - } - - if(found_route != NULL) { - PRINTF("uip-ds6-route: Found route: "); - PRINT6ADDR(addr); - PRINTF(" via "); - PRINT6ADDR(uip_ds6_route_nexthop(found_route)); - PRINTF("\n"); - } else { - PRINTF("uip-ds6-route: No route found\n"); - } - - if(found_route != NULL && found_route != list_head(routelist)) { - /* If we found a route, we put it at the start of the routeslist - list. The list is ordered by how recently we looked them up: - the least recently used route will be at the end of the - list - for fast lookups (assuming multiple packets to the same node). */ - - list_remove(routelist, found_route); - list_push(routelist, found_route); - } - - return found_route; -} -/*---------------------------------------------------------------------------*/ -uip_ds6_route_t * -uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, - uip_ipaddr_t *nexthop) -{ - uip_ds6_route_t *r; - struct uip_ds6_route_neighbor_route *nbrr; - -#if DEBUG != DEBUG_NONE - assert_nbr_routes_list_sane(); -#endif /* DEBUG != DEBUG_NONE */ - - /* Get link-layer address of next hop, make sure it is in neighbor table */ - const uip_lladdr_t *nexthop_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(nexthop); - if(nexthop_lladdr == NULL) { - PRINTF("uip_ds6_route_add: neighbor link-local address unknown for "); - PRINT6ADDR(nexthop); - PRINTF("\n"); - return NULL; - } - - /* First make sure that we don't add a route twice. If we find an - existing route for our destination, we'll delete the old - one first. */ - r = uip_ds6_route_lookup(ipaddr); - if(r != NULL) { - uip_ipaddr_t *current_nexthop; - current_nexthop = uip_ds6_route_nexthop(r); - if(current_nexthop != NULL && uip_ipaddr_cmp(nexthop, current_nexthop)) { - /* no need to update route - already correct! */ - return r; - } - PRINTF("uip_ds6_route_add: old route for "); - PRINT6ADDR(ipaddr); - PRINTF(" found, deleting it\n"); - - uip_ds6_route_rm(r); - } - { - struct uip_ds6_route_neighbor_routes *routes; - /* If there is no routing entry, create one. We first need to - check if we have room for this route. If not, we remove the - least recently used one we have. */ - - if(uip_ds6_route_num_routes() == UIP_DS6_ROUTE_NB) { - /* Removing the oldest route entry from the route table. The - least recently used route is the first route on the list. */ - uip_ds6_route_t *oldest; - - oldest = list_tail(routelist); /* uip_ds6_route_head(); */ - PRINTF("uip_ds6_route_add: dropping route to "); - PRINT6ADDR(&oldest->ipaddr); - PRINTF("\n"); - uip_ds6_route_rm(oldest); - } - - - /* Every neighbor on our neighbor table holds a struct - uip_ds6_route_neighbor_routes which holds a list of routes that - go through the neighbor. We add our route entry to this list. - - We first check to see if we already have this neighbor in our - nbr_route table. If so, the neighbor already has a route entry - list. - */ - routes = nbr_table_get_from_lladdr(nbr_routes, - (linkaddr_t *)nexthop_lladdr); - - if(routes == NULL) { - /* If the neighbor did not have an entry in our neighbor table, - we create one. The nbr_table_add_lladdr() function returns a - pointer to a pointer that we may use for our own purposes. We - initialize this pointer with the list of routing entries that - are attached to this neighbor. */ - routes = nbr_table_add_lladdr(nbr_routes, - (linkaddr_t *)nexthop_lladdr); - if(routes == NULL) { - /* This should not happen, as we explicitly deallocated one - route table entry above. */ - PRINTF("uip_ds6_route_add: could not allocate neighbor table entry\n"); - return NULL; - } - LIST_STRUCT_INIT(routes, route_list); - } - - /* Allocate a routing entry and populate it. */ - r = memb_alloc(&routememb); - - if(r == NULL) { - /* This should not happen, as we explicitly deallocated one - route table entry above. */ - PRINTF("uip_ds6_route_add: could not allocate route\n"); - return NULL; - } - - /* add new routes first - assuming that there is a reason to add this - and that there is a packet coming soon. */ - list_push(routelist, r); - - nbrr = memb_alloc(&neighborroutememb); - if(nbrr == NULL) { - /* This should not happen, as we explicitly deallocated one - route table entry above. */ - PRINTF("uip_ds6_route_add: could not allocate neighbor route list entry\n"); - memb_free(&routememb, r); - return NULL; - } - - nbrr->route = r; - /* Add the route to this neighbor */ - list_add(routes->route_list, nbrr); - r->neighbor_routes = routes; - num_routes++; - - PRINTF("uip_ds6_route_add num %d\n", num_routes); - } - - uip_ipaddr_copy(&(r->ipaddr), ipaddr); - r->length = length; - -#ifdef UIP_DS6_ROUTE_STATE_TYPE - memset(&r->state, 0, sizeof(UIP_DS6_ROUTE_STATE_TYPE)); -#endif - - PRINTF("uip_ds6_route_add: adding route: "); - PRINT6ADDR(ipaddr); - PRINTF(" via "); - PRINT6ADDR(nexthop); - PRINTF("\n"); - ANNOTATE("#L %u 1;blue\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]); - -#if UIP_DS6_NOTIFICATIONS - call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_ADD, ipaddr, nexthop); -#endif - -#if DEBUG != DEBUG_NONE - assert_nbr_routes_list_sane(); -#endif /* DEBUG != DEBUG_NONE */ - return r; -} - -/*---------------------------------------------------------------------------*/ -void -uip_ds6_route_rm(uip_ds6_route_t *route) -{ - struct uip_ds6_route_neighbor_route *neighbor_route; -#if DEBUG != DEBUG_NONE - assert_nbr_routes_list_sane(); -#endif /* DEBUG != DEBUG_NONE */ - if(route != NULL && route->neighbor_routes != NULL) { - - PRINTF("uip_ds6_route_rm: removing route: "); - PRINT6ADDR(&route->ipaddr); - PRINTF("\n"); - - /* Remove the route from the route list */ - list_remove(routelist, route); - - /* Find the corresponding neighbor_route and remove it. */ - for(neighbor_route = list_head(route->neighbor_routes->route_list); - neighbor_route != NULL && neighbor_route->route != route; - neighbor_route = list_item_next(neighbor_route)); - - if(neighbor_route == NULL) { - PRINTF("uip_ds6_route_rm: neighbor_route was NULL for "); - uip_debug_ipaddr_print(&route->ipaddr); - PRINTF("\n"); - } - list_remove(route->neighbor_routes->route_list, neighbor_route); - if(list_head(route->neighbor_routes->route_list) == NULL) { - /* If this was the only route using this neighbor, remove the - neibhor from the table */ - PRINTF("uip_ds6_route_rm: removing neighbor too\n"); - nbr_table_remove(nbr_routes, route->neighbor_routes->route_list); - } - memb_free(&routememb, route); - memb_free(&neighborroutememb, neighbor_route); - - num_routes--; - - PRINTF("uip_ds6_route_rm num %d\n", num_routes); - -#if UIP_DS6_NOTIFICATIONS - call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM, - &route->ipaddr, uip_ds6_route_nexthop(route)); -#endif -#if 0 //(DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE - /* we need to check if this was the last route towards "nexthop" */ - /* if so - remove that link (annotation) */ - uip_ds6_route_t *r; - for(r = uip_ds6_route_head(); - r != NULL; - r = uip_ds6_route_next(r)) { - uip_ipaddr_t *nextr, *nextroute; - nextr = uip_ds6_route_nexthop(r); - nextroute = uip_ds6_route_nexthop(route); - if(nextr != NULL && - nextroute != NULL && - uip_ipaddr_cmp(nextr, nextroute)) { - /* we found another link using the specific nexthop, so keep the #L */ - return; - } - } - ANNOTATE("#L %u 0\n", uip_ds6_route_nexthop(route)->u8[sizeof(uip_ipaddr_t) - 1]); -#endif - } - -#if DEBUG != DEBUG_NONE - assert_nbr_routes_list_sane(); -#endif /* DEBUG != DEBUG_NONE */ - return; -} -/*---------------------------------------------------------------------------*/ -static void -rm_routelist(struct uip_ds6_route_neighbor_routes *routes) -{ -#if DEBUG != DEBUG_NONE - assert_nbr_routes_list_sane(); -#endif /* DEBUG != DEBUG_NONE */ - PRINTF("uip_ds6_route_rm_routelist\n"); - if(routes != NULL && routes->route_list != NULL) { - struct uip_ds6_route_neighbor_route *r; - r = list_head(routes->route_list); - while(r != NULL) { - uip_ds6_route_rm(r->route); - r = list_head(routes->route_list); - } - nbr_table_remove(nbr_routes, routes); - } -#if DEBUG != DEBUG_NONE - assert_nbr_routes_list_sane(); -#endif /* DEBUG != DEBUG_NONE */ -} -/*---------------------------------------------------------------------------*/ -static void -rm_routelist_callback(nbr_table_item_t *ptr) -{ - rm_routelist((struct uip_ds6_route_neighbor_routes *)ptr); -} -/*---------------------------------------------------------------------------*/ -void -uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop) -{ - /* Get routing entry list of this neighbor */ - const uip_lladdr_t *nexthop_lladdr; - struct uip_ds6_route_neighbor_routes *routes; - - nexthop_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(nexthop); - routes = nbr_table_get_from_lladdr(nbr_routes, - (linkaddr_t *)nexthop_lladdr); - rm_routelist(routes); -} -/*---------------------------------------------------------------------------*/ -uip_ds6_defrt_t * -uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval) -{ - uip_ds6_defrt_t *d; - -#if DEBUG != DEBUG_NONE - assert_nbr_routes_list_sane(); -#endif /* DEBUG != DEBUG_NONE */ - - PRINTF("uip_ds6_defrt_add\n"); - d = uip_ds6_defrt_lookup(ipaddr); - if(d == NULL) { - d = memb_alloc(&defaultroutermemb); - if(d == NULL) { - PRINTF("uip_ds6_defrt_add: could not add default route to "); - PRINT6ADDR(ipaddr); - PRINTF(", out of memory\n"); - return NULL; - } else { - PRINTF("uip_ds6_defrt_add: adding default route to "); - PRINT6ADDR(ipaddr); - PRINTF("\n"); - } - - list_push(defaultrouterlist, d); - } - - uip_ipaddr_copy(&d->ipaddr, ipaddr); - if(interval != 0) { - stimer_set(&d->lifetime, interval); - d->isinfinite = 0; - } else { - d->isinfinite = 1; - } - - ANNOTATE("#L %u 1\n", ipaddr->u8[sizeof(uip_ipaddr_t) - 1]); - -#if UIP_DS6_NOTIFICATIONS - call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr); -#endif - -#if DEBUG != DEBUG_NONE - assert_nbr_routes_list_sane(); -#endif /* DEBUG != DEBUG_NONE */ - - return d; -} -/*---------------------------------------------------------------------------*/ -void -uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt) -{ - uip_ds6_defrt_t *d; - -#if DEBUG != DEBUG_NONE - assert_nbr_routes_list_sane(); -#endif /* DEBUG != DEBUG_NONE */ - - /* Make sure that the defrt is in the list before we remove it. */ - for(d = list_head(defaultrouterlist); - d != NULL; - d = list_item_next(d)) { - if(d == defrt) { - PRINTF("Removing default route\n"); - list_remove(defaultrouterlist, defrt); - memb_free(&defaultroutermemb, defrt); - ANNOTATE("#L %u 0\n", defrt->ipaddr.u8[sizeof(uip_ipaddr_t) - 1]); -#if UIP_DS6_NOTIFICATIONS - call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_RM, - &defrt->ipaddr, &defrt->ipaddr); -#endif - return; - } - } -#if DEBUG != DEBUG_NONE - assert_nbr_routes_list_sane(); -#endif /* DEBUG != DEBUG_NONE */ - -} -/*---------------------------------------------------------------------------*/ -uip_ds6_defrt_t * -uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr) -{ - uip_ds6_defrt_t *d; - for(d = list_head(defaultrouterlist); - d != NULL; - d = list_item_next(d)) { - if(uip_ipaddr_cmp(&d->ipaddr, ipaddr)) { - return d; - } - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -uip_ipaddr_t * -uip_ds6_defrt_choose(void) -{ - uip_ds6_defrt_t *d; - uip_ds6_nbr_t *bestnbr; - uip_ipaddr_t *addr; - - addr = NULL; - for(d = list_head(defaultrouterlist); - d != NULL; - d = list_item_next(d)) { - PRINTF("Defrt, IP address "); - PRINT6ADDR(&d->ipaddr); - PRINTF("\n"); - bestnbr = uip_ds6_nbr_lookup(&d->ipaddr); - if(bestnbr != NULL && bestnbr->state != NBR_INCOMPLETE) { - PRINTF("Defrt found, IP address "); - PRINT6ADDR(&d->ipaddr); - PRINTF("\n"); - return &d->ipaddr; - } else { - addr = &d->ipaddr; - PRINTF("Defrt INCOMPLETE found, IP address "); - PRINT6ADDR(&d->ipaddr); - PRINTF("\n"); - } - } - return addr; -} -/*---------------------------------------------------------------------------*/ -void -uip_ds6_defrt_periodic(void) -{ - uip_ds6_defrt_t *d; - d = list_head(defaultrouterlist); - while(d != NULL) { - if(!d->isinfinite && - stimer_expired(&d->lifetime)) { - PRINTF("uip_ds6_defrt_periodic: defrt lifetime expired\n"); - uip_ds6_defrt_rm(d); - d = list_head(defaultrouterlist); - } else { - d = list_item_next(d); - } - } -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/ipv6/uip-ds6-route.h b/net/ip/contiki/ipv6/uip-ds6-route.h deleted file mode 100644 index 27cbee79bd006a999b9f2b58e87f5fd163622c41..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/uip-ds6-route.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ -/** - * \addtogroup uip6 - * @{ - */ -/** - * \file - * Header file for routing table manipulation - */ -#ifndef UIP_DS6_ROUTE_H -#define UIP_DS6_ROUTE_H - -#include "sys/stimer.h" -#include "lib/list.h" - -void uip_ds6_route_init(void); - -#ifndef UIP_CONF_UIP_DS6_NOTIFICATIONS -#define UIP_DS6_NOTIFICATIONS 1 -#else -#define UIP_DS6_NOTIFICATIONS UIP_CONF_UIP_DS6_NOTIFICATIONS -#endif - -#if UIP_DS6_NOTIFICATIONS -/* Event constants for the uip-ds6 route notification interface. The - notification interface allows for a user program to be notified via - a callback when a route has been added or removed and when the - system has added or removed a default route. */ -#define UIP_DS6_NOTIFICATION_DEFRT_ADD 0 -#define UIP_DS6_NOTIFICATION_DEFRT_RM 1 -#define UIP_DS6_NOTIFICATION_ROUTE_ADD 2 -#define UIP_DS6_NOTIFICATION_ROUTE_RM 3 - -typedef void (* uip_ds6_notification_callback)(int event, - uip_ipaddr_t *route, - uip_ipaddr_t *nexthop, - int num_routes); -struct uip_ds6_notification { - struct uip_ds6_notification *next; - uip_ds6_notification_callback callback; -}; - -void uip_ds6_notification_add(struct uip_ds6_notification *n, - uip_ds6_notification_callback c); - -void uip_ds6_notification_rm(struct uip_ds6_notification *n); -/*--------------------------------------------------*/ -#endif - -/* Routing table */ -#ifndef UIP_CONF_MAX_ROUTES -#ifdef UIP_CONF_DS6_ROUTE_NBU -#define UIP_DS6_ROUTE_NB UIP_CONF_DS6_ROUTE_NBU -#else /* UIP_CONF_DS6_ROUTE_NBU */ -#define UIP_DS6_ROUTE_NB 4 -#endif /* UIP_CONF_DS6_ROUTE_NBU */ -#else /* UIP_CONF_MAX_ROUTES */ -#define UIP_DS6_ROUTE_NB UIP_CONF_MAX_ROUTES -#endif /* UIP_CONF_MAX_ROUTES */ - -/** \brief define some additional RPL related route state and - * neighbor callback for RPL - if not a DS6_ROUTE_STATE is already set */ -#ifndef UIP_DS6_ROUTE_STATE_TYPE -#define UIP_DS6_ROUTE_STATE_TYPE rpl_route_entry_t -/* Needed for the extended route entry state when using ContikiRPL */ -typedef struct rpl_route_entry { - uint32_t lifetime; - void *dag; - uint8_t learned_from; - uint8_t nopath_received; -} rpl_route_entry_t; -#endif /* UIP_DS6_ROUTE_STATE_TYPE */ - -/** \brief The neighbor routes hold a list of routing table entries - that are attached to a specific neihbor. */ -struct uip_ds6_route_neighbor_routes { - LIST_STRUCT(route_list); -}; - -/** \brief An entry in the routing table */ -typedef struct uip_ds6_route { - struct uip_ds6_route *next; - /* Each route entry belongs to a specific neighbor. That neighbor - holds a list of all routing entries that go through it. The - routes field point to the uip_ds6_route_neighbor_routes that - belong to the neighbor table entry that this routing table entry - uses. */ - struct uip_ds6_route_neighbor_routes *neighbor_routes; - uip_ipaddr_t ipaddr; -#ifdef UIP_DS6_ROUTE_STATE_TYPE - UIP_DS6_ROUTE_STATE_TYPE state; -#endif - uint8_t length; -} uip_ds6_route_t; - -/** \brief A neighbor route list entry, used on the - uip_ds6_route->neighbor_routes->route_list list. */ -struct uip_ds6_route_neighbor_route { - struct uip_ds6_route_neighbor_route *next; - struct uip_ds6_route *route; -}; - -/** \brief An entry in the default router list */ -typedef struct uip_ds6_defrt { - struct uip_ds6_defrt *next; - uip_ipaddr_t ipaddr; - struct stimer lifetime; - uint8_t isinfinite; -} uip_ds6_defrt_t; - -/** \name Default router list basic routines */ -/** @{ */ -uip_ds6_defrt_t *uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, - unsigned long interval); -void uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt); -uip_ds6_defrt_t *uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr); -uip_ipaddr_t *uip_ds6_defrt_choose(void); - -void uip_ds6_defrt_periodic(void); -/** @} */ - - -/** \name Routing Table basic routines */ -/** @{ */ -uip_ds6_route_t *uip_ds6_route_lookup(uip_ipaddr_t *destipaddr); -uip_ds6_route_t *uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, - uip_ipaddr_t *next_hop); -void uip_ds6_route_rm(uip_ds6_route_t *route); -void uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop); - -uip_ipaddr_t *uip_ds6_route_nexthop(uip_ds6_route_t *); -int uip_ds6_route_num_routes(void); -uip_ds6_route_t *uip_ds6_route_head(void); -uip_ds6_route_t *uip_ds6_route_next(uip_ds6_route_t *); - -/** @} */ - -#endif /* UIP_DS6_ROUTE_H */ -/** @} */ diff --git a/net/ip/contiki/ipv6/uip-ds6.c b/net/ip/contiki/ipv6/uip-ds6.c deleted file mode 100644 index a0f60aec34c9b8a8c3fcd05febf9f5d178380be5..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/uip-ds6.c +++ /dev/null @@ -1,737 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * IPv6 data structure manipulation. - * Comprises part of the Neighbor discovery (RFC 4861) - * and auto configuration (RFC 4862) state machines. - * \author Mathilde Durvy - * \author Julien Abeille - */ - -#include -#include -#include -#include "lib/random.h" -#include "contiki/ipv6/uip-nd6.h" -#include "contiki/ipv6/uip-ds6.h" -#include "contiki/ip/uip-packetqueue.h" - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_IPV6_DS -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -struct etimer uip_ds6_timer_periodic; /** \brief Timer for maintenance of data structures */ - -#if UIP_CONF_ROUTER -struct stimer uip_ds6_timer_ra; /** \brief RA timer, to schedule RA sending */ -#if UIP_ND6_SEND_RA -static uint8_t racount; /** \brief number of RA already sent */ -static uint16_t rand_time; /** \brief random time value for timers */ -#endif -#else /* UIP_CONF_ROUTER */ -struct etimer uip_ds6_timer_rs; /** \brief RS timer, to schedule RS sending */ -static uint8_t rscount; /** \brief number of rs already sent */ -#endif /* UIP_CONF_ROUTER */ - -/** \name "DS6" Data structures */ -/** @{ */ -uip_ds6_netif_t uip_ds6_if; /** \brief The single interface */ -uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; /** \brief Prefix list */ - -/* Used by Cooja to enable extraction of addresses from memory.*/ -uint8_t uip_ds6_addr_size; -uint8_t uip_ds6_netif_addr_list_offset; - -/** @} */ - -/* "full" (as opposed to pointer) ip address used in this file, */ -static uip_ipaddr_t loc_fipaddr; - -/* Pointers used in this file */ -/* FIXME - we cannot do this as would prevent re-entrancy */ -static uip_ds6_addr_t *locaddr; -static uip_ds6_maddr_t *locmaddr; -static uip_ds6_aaddr_t *locaaddr; -static uip_ds6_prefix_t *locprefix; - -/*---------------------------------------------------------------------------*/ -void -uip_ds6_init(void) -{ - - uip_ds6_neighbors_init(); - uip_ds6_route_init(); - - PRINTF("Init of IPv6 data structures\n"); - PRINTF("%u neighbors\n%u default routers\n%u prefixes\n%u routes\n%u unicast addresses\n%u multicast addresses\n%u anycast addresses\n", - NBR_TABLE_MAX_NEIGHBORS, UIP_DS6_DEFRT_NB, UIP_DS6_PREFIX_NB, UIP_DS6_ROUTE_NB, - UIP_DS6_ADDR_NB, UIP_DS6_MADDR_NB, UIP_DS6_AADDR_NB); - memset(uip_ds6_prefix_list, 0, sizeof(uip_ds6_prefix_list)); - memset(&uip_ds6_if, 0, sizeof(uip_ds6_if)); - uip_ds6_addr_size = sizeof(struct uip_ds6_addr); - uip_ds6_netif_addr_list_offset = offsetof(struct uip_ds6_netif, addr_list); - - /* Set interface parameters */ - uip_ds6_if.link_mtu = UIP_LINK_MTU; - uip_ds6_if.cur_hop_limit = UIP_TTL; - uip_ds6_if.base_reachable_time = UIP_ND6_REACHABLE_TIME; - uip_ds6_if.reachable_time = uip_ds6_compute_reachable_time(); - uip_ds6_if.retrans_timer = UIP_ND6_RETRANS_TIMER; - uip_ds6_if.maxdadns = UIP_ND6_DEF_MAXDADNS; - - uip_ds6_set_lladdr(&uip_lladdr); - -#if UIP_CONF_ROUTER -#if UIP_ND6_SEND_RA - stimer_set(&uip_ds6_timer_ra, 2); /* wait to have a link local IP address */ -#endif /* UIP_ND6_SEND_RA */ -#else /* UIP_CONF_ROUTER */ - etimer_set(&uip_ds6_timer_rs, - random_rand() % (UIP_ND6_MAX_RTR_SOLICITATION_DELAY * - CLOCK_SECOND), - &tcpip_process); -#endif /* UIP_CONF_ROUTER */ - etimer_set(&uip_ds6_timer_periodic, UIP_DS6_PERIOD, &tcpip_process); - - return; -} - -/*---------------------------------------------------------------------------*/ -void uip_ds6_set_lladdr(uip_lladdr_t *lladdr) -{ - /* First remove the current address from system as this function - * can be called many times. - */ - uip_ds6_addr_rm(uip_ds6_addr_lookup(&loc_fipaddr)); - - /* Create link local address, prefix, multicast addresses, - * anycast addresses - */ - uip_create_linklocal_prefix(&loc_fipaddr); -#if UIP_CONF_ROUTER - uip_ds6_prefix_add(&loc_fipaddr, UIP_DEFAULT_PREFIX_LEN, 0, 0, 0, 0); -#else /* UIP_CONF_ROUTER */ - uip_ds6_prefix_add(&loc_fipaddr, UIP_DEFAULT_PREFIX_LEN, 0); -#endif /* UIP_CONF_ROUTER */ - - memcpy(&uip_lladdr, lladdr, sizeof(uip_lladdr)); - - uip_ds6_set_addr_iid(&loc_fipaddr, &uip_lladdr); - uip_ds6_addr_add(&loc_fipaddr, 0, ADDR_AUTOCONF); - - uip_create_linklocal_allnodes_mcast(&loc_fipaddr); - uip_ds6_maddr_add(&loc_fipaddr); - -#if UIP_CONF_ROUTER - uip_create_linklocal_allrouters_mcast(&loc_fipaddr); - uip_ds6_maddr_add(&loc_fipaddr); -#endif /* UIP_CONF_ROUTER */ -} - -/*---------------------------------------------------------------------------*/ -void -uip_ds6_periodic(struct net_buf *buf) -{ - uip_ds6_addr_t *locaddr; - uip_ds6_prefix_t *locprefix; - - /* Periodic processing on unicast addresses */ - for(locaddr = uip_ds6_if.addr_list; - locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { - if(locaddr->isused) { - if((!locaddr->isinfinite) && (stimer_expired(&locaddr->vlifetime))) { - uip_ds6_addr_rm(locaddr); -#if UIP_ND6_DEF_MAXDADNS > 0 - } else if((locaddr->state == ADDR_TENTATIVE) - && (locaddr->dadnscount <= uip_ds6_if.maxdadns) - && (timer_expired(&locaddr->dadtimer))) { - uip_ds6_dad(NULL, locaddr); -#endif /* UIP_ND6_DEF_MAXDADNS > 0 */ - } - } - } - - /* Periodic processing on default routers */ - uip_ds6_defrt_periodic(); - /* for(locdefrt = uip_ds6_defrt_list; - locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) { - if((locdefrt->isused) && (!locdefrt->isinfinite) && - (stimer_expired(&(locdefrt->lifetime)))) { - uip_ds6_defrt_rm(locdefrt); - } - }*/ - -#if !UIP_CONF_ROUTER - /* Periodic processing on prefixes */ - for(locprefix = uip_ds6_prefix_list; - locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; - locprefix++) { - if(locprefix->isused && !locprefix->isinfinite - && stimer_expired(&(locprefix->vlifetime))) { - uip_ds6_prefix_rm(locprefix); - } - } -#endif /* !UIP_CONF_ROUTER */ - - uip_ds6_neighbor_periodic(buf); - -#if UIP_CONF_ROUTER && UIP_ND6_SEND_RA - /* Periodic RA sending */ - if(stimer_expired(&uip_ds6_timer_ra) && (uip_len == 0)) { - uip_ds6_send_ra_periodic(); - } -#endif /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */ - etimer_reset(&uip_ds6_timer_periodic); - return; -} - -/*---------------------------------------------------------------------------*/ -uint8_t -uip_ds6_list_loop(uip_ds6_element_t *list, uint8_t size, - uint16_t elementsize, uip_ipaddr_t *ipaddr, - uint8_t ipaddrlen, uip_ds6_element_t **out_element) -{ - uip_ds6_element_t *element; - - *out_element = NULL; - - for(element = list; - element < - (uip_ds6_element_t *)((uint8_t *)list + (size * elementsize)); - element = (uip_ds6_element_t *)((uint8_t *)element + elementsize)) { - if(element->isused) { - if(uip_ipaddr_prefixcmp(&element->ipaddr, ipaddr, ipaddrlen)) { - *out_element = element; - return FOUND; - } - } else { - *out_element = element; - } - } - - return *out_element != NULL ? FREESPACE : NOSPACE; -} - -/*---------------------------------------------------------------------------*/ -#if UIP_CONF_ROUTER -/*---------------------------------------------------------------------------*/ -uip_ds6_prefix_t * -uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen, - uint8_t advertise, uint8_t flags, unsigned long vtime, - unsigned long ptime) -{ - if(uip_ds6_list_loop - ((uip_ds6_element_t *)uip_ds6_prefix_list, UIP_DS6_PREFIX_NB, - sizeof(uip_ds6_prefix_t), ipaddr, ipaddrlen, - (uip_ds6_element_t **)&locprefix) == FREESPACE) { - locprefix->isused = 1; - uip_ipaddr_copy(&locprefix->ipaddr, ipaddr); - locprefix->length = ipaddrlen; - locprefix->advertise = advertise; - locprefix->l_a_reserved = flags; - locprefix->vlifetime = vtime; - locprefix->plifetime = ptime; - PRINTF("Adding prefix "); - PRINT6ADDR(&locprefix->ipaddr); - PRINTF(" length %u, flags %x, Valid lifetime %lx, Preffered lifetime %lx\n", - ipaddrlen, flags, vtime, ptime); - return locprefix; - } else { - PRINTF("No more space in Prefix list\n"); - } - return NULL; -} - - -#else /* UIP_CONF_ROUTER */ -uip_ds6_prefix_t * -uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen, - unsigned long interval) -{ - if(uip_ds6_list_loop - ((uip_ds6_element_t *)uip_ds6_prefix_list, UIP_DS6_PREFIX_NB, - sizeof(uip_ds6_prefix_t), ipaddr, ipaddrlen, - (uip_ds6_element_t **)&locprefix) == FREESPACE) { - locprefix->isused = 1; - uip_ipaddr_copy(&locprefix->ipaddr, ipaddr); - locprefix->length = ipaddrlen; - if(interval != 0) { - stimer_set(&(locprefix->vlifetime), interval); - locprefix->isinfinite = 0; - } else { - locprefix->isinfinite = 1; - } - PRINTF("Adding prefix "); - PRINT6ADDR(&locprefix->ipaddr); - PRINTF(" length %u, vlifetime %lu\n", ipaddrlen, interval); - } - return NULL; -} -#endif /* UIP_CONF_ROUTER */ - -/*---------------------------------------------------------------------------*/ -void -uip_ds6_prefix_rm(uip_ds6_prefix_t *prefix) -{ - if(prefix != NULL) { - prefix->isused = 0; - } - return; -} -/*---------------------------------------------------------------------------*/ -uip_ds6_prefix_t * -uip_ds6_prefix_lookup(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen) -{ - if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_prefix_list, - UIP_DS6_PREFIX_NB, sizeof(uip_ds6_prefix_t), - ipaddr, ipaddrlen, - (uip_ds6_element_t **)&locprefix) == FOUND) { - return locprefix; - } - return NULL; -} - -/*---------------------------------------------------------------------------*/ -uint8_t -uip_ds6_is_addr_onlink(uip_ipaddr_t *ipaddr) -{ - for(locprefix = uip_ds6_prefix_list; - locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) { - if(locprefix->isused && - uip_ipaddr_prefixcmp(&locprefix->ipaddr, ipaddr, locprefix->length)) { - return 1; - } - } - return 0; -} - -/*---------------------------------------------------------------------------*/ -uip_ds6_addr_t * -uip_ds6_addr_add(uip_ipaddr_t *ipaddr, unsigned long vlifetime, uint8_t type) -{ - if(uip_ds6_list_loop - ((uip_ds6_element_t *)uip_ds6_if.addr_list, UIP_DS6_ADDR_NB, - sizeof(uip_ds6_addr_t), ipaddr, 128, - (uip_ds6_element_t **)&locaddr) == FREESPACE) { - locaddr->isused = 1; - uip_ipaddr_copy(&locaddr->ipaddr, ipaddr); - locaddr->type = type; - PRINTF("Adding addr "); - PRINT6ADDR(&locaddr->ipaddr); - PRINTF(" lifetime %d type %d\n", vlifetime, type); - if(vlifetime == 0) { - locaddr->isinfinite = 1; - } else { - locaddr->isinfinite = 0; - stimer_set(&(locaddr->vlifetime), vlifetime); - } -#if UIP_ND6_DEF_MAXDADNS > 0 - locaddr->state = ADDR_TENTATIVE; - timer_set(&locaddr->dadtimer, - random_rand() % (UIP_ND6_MAX_RTR_SOLICITATION_DELAY * - CLOCK_SECOND)); - locaddr->dadnscount = 0; -#else /* UIP_ND6_DEF_MAXDADNS > 0 */ - locaddr->state = ADDR_PREFERRED; -#endif /* UIP_ND6_DEF_MAXDADNS > 0 */ - uip_create_solicited_node(ipaddr, &loc_fipaddr); - uip_ds6_maddr_add(&loc_fipaddr); - return locaddr; - } - return NULL; -} - -/*---------------------------------------------------------------------------*/ -void -uip_ds6_addr_rm(uip_ds6_addr_t *addr) -{ - if(addr != NULL) { - uip_create_solicited_node(&addr->ipaddr, &loc_fipaddr); - if((locmaddr = uip_ds6_maddr_lookup(&loc_fipaddr)) != NULL) { - uip_ds6_maddr_rm(locmaddr); - } - addr->isused = 0; - } - return; -} - -/*---------------------------------------------------------------------------*/ -uip_ds6_addr_t * -uip_ds6_addr_lookup(uip_ipaddr_t *ipaddr) -{ - if(uip_ds6_list_loop - ((uip_ds6_element_t *)uip_ds6_if.addr_list, UIP_DS6_ADDR_NB, - sizeof(uip_ds6_addr_t), ipaddr, 128, - (uip_ds6_element_t **)&locaddr) == FOUND) { - return locaddr; - } - return NULL; -} - -/*---------------------------------------------------------------------------*/ -/* - * get a link local address - - * state = -1 => any address is ok. Otherwise state = desired state of addr. - * (TENTATIVE, PREFERRED, DEPRECATED) - */ -uip_ds6_addr_t * -uip_ds6_get_link_local(int8_t state) -{ - for(locaddr = uip_ds6_if.addr_list; - locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { - if(locaddr->isused && (state == -1 || locaddr->state == state) - && (uip_is_addr_link_local(&locaddr->ipaddr))) { - return locaddr; - } - } - return NULL; -} - -/*---------------------------------------------------------------------------*/ -/* - * get a global address - - * state = -1 => any address is ok. Otherwise state = desired state of addr. - * (TENTATIVE, PREFERRED, DEPRECATED) - */ -uip_ds6_addr_t * -uip_ds6_get_global(int8_t state) -{ - for(locaddr = uip_ds6_if.addr_list; - locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { - if(locaddr->isused && (state == -1 || locaddr->state == state) - && !(uip_is_addr_link_local(&locaddr->ipaddr))) { - return locaddr; - } - } - return NULL; -} - -/*---------------------------------------------------------------------------*/ -uip_ds6_maddr_t * -uip_ds6_maddr_add(const uip_ipaddr_t *ipaddr) -{ - if(uip_ds6_list_loop - ((uip_ds6_element_t *)uip_ds6_if.maddr_list, UIP_DS6_MADDR_NB, - sizeof(uip_ds6_maddr_t), (void*)ipaddr, 128, - (uip_ds6_element_t **)&locmaddr) == FREESPACE) { - locmaddr->isused = 1; - uip_ipaddr_copy(&locmaddr->ipaddr, ipaddr); - PRINTF("Adding maddr "); - PRINT6ADDR(&locmaddr->ipaddr); - PRINTF("\n"); - return locmaddr; - } - return NULL; -} - -/*---------------------------------------------------------------------------*/ -void -uip_ds6_maddr_rm(uip_ds6_maddr_t *maddr) -{ - if(maddr != NULL) { - maddr->isused = 0; - } - return; -} - -/*---------------------------------------------------------------------------*/ -uip_ds6_maddr_t * -uip_ds6_maddr_lookup(const uip_ipaddr_t *ipaddr) -{ - if(uip_ds6_list_loop - ((uip_ds6_element_t *)uip_ds6_if.maddr_list, UIP_DS6_MADDR_NB, - sizeof(uip_ds6_maddr_t), (void*)ipaddr, 128, - (uip_ds6_element_t **)&locmaddr) == FOUND) { - return locmaddr; - } - return NULL; -} - - -/*---------------------------------------------------------------------------*/ -uip_ds6_aaddr_t * -uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr) -{ - if(uip_ds6_list_loop - ((uip_ds6_element_t *)uip_ds6_if.aaddr_list, UIP_DS6_AADDR_NB, - sizeof(uip_ds6_aaddr_t), ipaddr, 128, - (uip_ds6_element_t **)&locaaddr) == FREESPACE) { - locaaddr->isused = 1; - uip_ipaddr_copy(&locaaddr->ipaddr, ipaddr); - return locaaddr; - } - return NULL; -} - -/*---------------------------------------------------------------------------*/ -void -uip_ds6_aaddr_rm(uip_ds6_aaddr_t *aaddr) -{ - if(aaddr != NULL) { - aaddr->isused = 0; - } - return; -} - -/*---------------------------------------------------------------------------*/ -uip_ds6_aaddr_t * -uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr) -{ - if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_if.aaddr_list, - UIP_DS6_AADDR_NB, sizeof(uip_ds6_aaddr_t), ipaddr, 128, - (uip_ds6_element_t **)&locaaddr) == FOUND) { - return locaaddr; - } - return NULL; -} - -/*---------------------------------------------------------------------------*/ -void -uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst) -{ - uint8_t best = 0; /* number of bit in common with best match */ - uint8_t n = 0; - uip_ds6_addr_t *matchaddr = NULL; - - if(!uip_is_addr_link_local(dst) && !uip_is_addr_mcast(dst)) { - /* find longest match */ - for(locaddr = uip_ds6_if.addr_list; - locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { - /* Only preferred global (not link-local) addresses */ - if(locaddr->isused && locaddr->state == ADDR_PREFERRED && - !uip_is_addr_link_local(&locaddr->ipaddr)) { - n = get_match_length(dst, &locaddr->ipaddr); - if(n >= best) { - best = n; - matchaddr = locaddr; - } - } - } -#if UIP_IPV6_MULTICAST - } else if(uip_is_addr_mcast_routable(dst)) { - matchaddr = uip_ds6_get_global(ADDR_PREFERRED); -#endif - } else { - matchaddr = uip_ds6_get_link_local(ADDR_PREFERRED); - } - - /* use the :: (unspecified address) as source if no match found */ - if(matchaddr == NULL) { - uip_create_unspecified(src); - } else { - uip_ipaddr_copy(src, &matchaddr->ipaddr); - } -} - -/*---------------------------------------------------------------------------*/ -void -uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr) -{ - /* We consider only links with IEEE EUI-64 identifier or - * IEEE 48-bit MAC addresses */ -#if (UIP_LLADDR_LEN == 8) - memcpy(ipaddr->u8 + 8, lladdr, UIP_LLADDR_LEN); - ipaddr->u8[8] ^= 0x02; -#elif (UIP_LLADDR_LEN == 6) - memcpy(ipaddr->u8 + 8, lladdr, 3); - ipaddr->u8[11] = 0xff; - ipaddr->u8[12] = 0xfe; - memcpy(ipaddr->u8 + 13, (uint8_t *)lladdr + 3, 3); - ipaddr->u8[8] ^= 0x02; -#else -#error uip-ds6.c cannot build interface address when UIP_LLADDR_LEN is not 6 or 8 -#endif -} - -/*---------------------------------------------------------------------------*/ -uint8_t -get_match_length(uip_ipaddr_t *src, uip_ipaddr_t *dst) -{ - uint8_t j, k, x_or; - uint8_t len = 0; - - for(j = 0; j < 16; j++) { - if(src->u8[j] == dst->u8[j]) { - len += 8; - } else { - x_or = src->u8[j] ^ dst->u8[j]; - for(k = 0; k < 8; k++) { - if((x_or & 0x80) == 0) { - len++; - x_or <<= 1; - } else { - break; - } - } - break; - } - } - return len; -} - -/*---------------------------------------------------------------------------*/ -#if UIP_ND6_DEF_MAXDADNS > 0 -void -uip_ds6_dad(struct net_buf *buf, uip_ds6_addr_t *addr) -{ - /* send maxdadns NS for DAD */ - if(addr->dadnscount < uip_ds6_if.maxdadns) { - uip_nd6_ns_output(buf, NULL, NULL, &addr->ipaddr); - addr->dadnscount++; - timer_set(&addr->dadtimer, - uip_ds6_if.retrans_timer / 1000 * CLOCK_SECOND); - return; - } - /* - * If we arrive here it means DAD succeeded, otherwise the dad process - * would have been interrupted in ds6_dad_ns/na_input - */ - PRINTF("DAD succeeded, ipaddr:"); - PRINT6ADDR(&addr->ipaddr); - PRINTF("\n"); - - addr->state = ADDR_PREFERRED; - return; -} - -/*---------------------------------------------------------------------------*/ -/* - * Calling code must handle when this returns 0 (e.g. link local - * address can not be used). - */ -int -uip_ds6_dad_failed(uip_ds6_addr_t *addr) -{ - if(uip_is_addr_link_local(&addr->ipaddr)) { - PRINTF("Contiki shutdown, DAD for link local address failed\n"); - return 0; - } - uip_ds6_addr_rm(addr); - return 1; -} -#endif /*UIP_ND6_DEF_MAXDADNS > 0 */ - -/*---------------------------------------------------------------------------*/ -#if UIP_CONF_ROUTER -#if UIP_ND6_SEND_RA -void -uip_ds6_send_ra_sollicited(void) -{ - /* We have a pb here: RA timer max possible value is 1800s, - * hence we have to use stimers. However, when receiving a RS, we - * should delay the reply by a random value between 0 and 500ms timers. - * stimers are in seconds, hence we cannot do this. Therefore we just send - * the RA (setting the timer to 0 below). We keep the code logic for - * the days contiki will support appropriate timers */ - rand_time = 0; - PRINTF("Solicited RA, random time %u\n", rand_time); - - if(stimer_remaining(&uip_ds6_timer_ra) > rand_time) { - if(stimer_elapsed(&uip_ds6_timer_ra) < UIP_ND6_MIN_DELAY_BETWEEN_RAS) { - /* Ensure that the RAs are rate limited */ -/* stimer_set(&uip_ds6_timer_ra, rand_time + - UIP_ND6_MIN_DELAY_BETWEEN_RAS - - stimer_elapsed(&uip_ds6_timer_ra)); - */ } else { - stimer_set(&uip_ds6_timer_ra, rand_time); - } - } -} - -/*---------------------------------------------------------------------------*/ -void -uip_ds6_send_ra_periodic(void) -{ - if(racount > 0) { - /* send previously scheduled RA */ - uip_nd6_ra_output(NULL); - PRINTF("Sending periodic RA\n"); - } - - rand_time = UIP_ND6_MIN_RA_INTERVAL + random_rand() % - (uint16_t) (UIP_ND6_MAX_RA_INTERVAL - UIP_ND6_MIN_RA_INTERVAL); - PRINTF("Random time 1 = %u\n", rand_time); - - if(racount < UIP_ND6_MAX_INITIAL_RAS) { - if(rand_time > UIP_ND6_MAX_INITIAL_RA_INTERVAL) { - rand_time = UIP_ND6_MAX_INITIAL_RA_INTERVAL; - PRINTF("Random time 2 = %u\n", rand_time); - } - racount++; - } - PRINTF("Random time 3 = %u\n", rand_time); - stimer_set(&uip_ds6_timer_ra, rand_time); -} - -#endif /* UIP_ND6_SEND_RA */ -#else /* UIP_CONF_ROUTER */ -/*---------------------------------------------------------------------------*/ -void -uip_ds6_send_rs(struct net_buf *buf) -{ - if((uip_ds6_defrt_choose() == NULL) - && (rscount < UIP_ND6_MAX_RTR_SOLICITATIONS)) { - PRINTF("Sending RS %u\n", rscount); - uip_nd6_rs_output(buf); - rscount++; - etimer_set(&uip_ds6_timer_rs, - UIP_ND6_RTR_SOLICITATION_INTERVAL * CLOCK_SECOND, - &tcpip_process); - } else { - PRINTF("Router found ? (boolean): %u\n", - (uip_ds6_defrt_choose() != NULL)); - etimer_stop(&uip_ds6_timer_rs); - } - return; -} - -#endif /* UIP_CONF_ROUTER */ -/*---------------------------------------------------------------------------*/ -uint32_t -uip_ds6_compute_reachable_time(void) -{ - return (uint32_t) (UIP_ND6_MIN_RANDOM_FACTOR - (uip_ds6_if.base_reachable_time)) + - ((uint16_t) (random_rand() << 8) + - (uint16_t) random_rand()) % - (uint32_t) (UIP_ND6_MAX_RANDOM_FACTOR(uip_ds6_if.base_reachable_time) - - UIP_ND6_MIN_RANDOM_FACTOR(uip_ds6_if.base_reachable_time)); -} -/*---------------------------------------------------------------------------*/ - -/** @}*/ diff --git a/net/ip/contiki/ipv6/uip-ds6.h b/net/ip/contiki/ipv6/uip-ds6.h deleted file mode 100644 index 7f97633bdf825c4c1190ef8fce2b62d283ab0ee7..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/uip-ds6.h +++ /dev/null @@ -1,350 +0,0 @@ -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * Header file for IPv6-related data structures - * \author Mathilde Durvy - * \author Julien Abeille - * - */ -/* - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * - */ - -#ifndef UIP_DS6_H_ -#define UIP_DS6_H_ - -#include - -#include "contiki/ip/uip.h" -#include "sys/stimer.h" -/* The size of uip_ds6_addr_t depends on UIP_ND6_DEF_MAXDADNS. Include uip-nd6.h to define it. */ -#include "contiki/ipv6/uip-nd6.h" -#include "contiki/ipv6/uip-ds6-route.h" -#include "contiki/ipv6/uip-ds6-nbr.h" - -/*--------------------------------------------------*/ -/** Configuration. For all tables (Neighbor cache, Prefix List, Routing Table, - * Default Router List, Unicast address list, multicast address list, anycast address list), - * we define: - * - the number of elements requested by the user in contiki configuration (name suffixed by _NBU) - * - the number of elements assigned by the system (name suffixed by _NBS) - * - the total number of elements is the sum (name suffixed by _NB) - */ - -/* Default router list */ -#define UIP_DS6_DEFRT_NBS 0 -#ifndef UIP_CONF_DS6_DEFRT_NBU -#define UIP_DS6_DEFRT_NBU 2 -#else -#define UIP_DS6_DEFRT_NBU UIP_CONF_DS6_DEFRT_NBU -#endif -#define UIP_DS6_DEFRT_NB UIP_DS6_DEFRT_NBS + UIP_DS6_DEFRT_NBU - -/* Prefix list */ -#define UIP_DS6_PREFIX_NBS 1 -#ifndef UIP_CONF_DS6_PREFIX_NBU -#define UIP_DS6_PREFIX_NBU 2 -#else -#define UIP_DS6_PREFIX_NBU UIP_CONF_DS6_PREFIX_NBU -#endif -#define UIP_DS6_PREFIX_NB UIP_DS6_PREFIX_NBS + UIP_DS6_PREFIX_NBU - -/* Unicast address list*/ -#define UIP_DS6_ADDR_NBS 1 -#ifndef UIP_CONF_DS6_ADDR_NBU -#define UIP_DS6_ADDR_NBU 2 -#else -#define UIP_DS6_ADDR_NBU UIP_CONF_DS6_ADDR_NBU -#endif -#define UIP_DS6_ADDR_NB UIP_DS6_ADDR_NBS + UIP_DS6_ADDR_NBU - -/* Multicast address list */ -#if UIP_CONF_ROUTER -#define UIP_DS6_MADDR_NBS 2 + UIP_DS6_ADDR_NB /* all routers + all nodes + one solicited per unicast */ -#else -#define UIP_DS6_MADDR_NBS 1 + UIP_DS6_ADDR_NB /* all nodes + one solicited per unicast */ -#endif -#ifndef UIP_CONF_DS6_MADDR_NBU -#define UIP_DS6_MADDR_NBU 0 -#else -#define UIP_DS6_MADDR_NBU UIP_CONF_DS6_MADDR_NBU -#endif -#define UIP_DS6_MADDR_NB UIP_DS6_MADDR_NBS + UIP_DS6_MADDR_NBU - -/* Anycast address list */ -#if UIP_CONF_ROUTER -#define UIP_DS6_AADDR_NBS UIP_DS6_PREFIX_NB - 1 /* One per non link local prefix (subnet prefix anycast address) */ -#else -#define UIP_DS6_AADDR_NBS 0 -#endif -#ifndef UIP_CONF_DS6_AADDR_NBU -#define UIP_DS6_AADDR_NBU 0 -#else -#define UIP_DS6_AADDR_NBU UIP_CONF_DS6_AADDR_NBU -#endif -#define UIP_DS6_AADDR_NB UIP_DS6_AADDR_NBS + UIP_DS6_AADDR_NBU - -/*--------------------------------------------------*/ -/* Should we use LinkLayer acks in NUD ?*/ -#ifndef UIP_CONF_DS6_LL_NUD -#define UIP_DS6_LL_NUD 0 -#else -#define UIP_DS6_LL_NUD UIP_CONF_DS6_LL_NUD -#endif - -/** \brief Possible states for the an address (RFC 4862) */ -#define ADDR_TENTATIVE 0 -#define ADDR_PREFERRED 1 -#define ADDR_DEPRECATED 2 - -/** \brief How the address was acquired: Autoconf, DHCP or manually */ -#define ADDR_ANYTYPE 0 -#define ADDR_AUTOCONF 1 -#define ADDR_DHCP 2 -#define ADDR_MANUAL 3 - -/** \brief General DS6 definitions */ -/** Period for uip-ds6 periodic task*/ -#ifndef UIP_DS6_CONF_PERIOD -#define UIP_DS6_PERIOD (CLOCK_SECOND/10) -#else -#define UIP_DS6_PERIOD UIP_DS6_CONF_PERIOD -#endif - -#define FOUND 0 -#define FREESPACE 1 -#define NOSPACE 2 -/*--------------------------------------------------*/ - -#if UIP_CONF_IPV6_QUEUE_PKT -#include "contiki/ip/uip-packetqueue.h" -#endif /*UIP_CONF_QUEUE_PKT */ - -/** \brief A prefix list entry */ -#if UIP_CONF_ROUTER -typedef struct uip_ds6_prefix { - uint8_t isused; - uip_ipaddr_t ipaddr; - uint8_t length; - uint8_t advertise; - uint32_t vlifetime; - uint32_t plifetime; - uint8_t l_a_reserved; /**< on-link and autonomous flags + 6 reserved bits */ -} uip_ds6_prefix_t; -#else /* UIP_CONF_ROUTER */ -typedef struct uip_ds6_prefix { - uint8_t isused; - uip_ipaddr_t ipaddr; - uint8_t length; - struct stimer vlifetime; - uint8_t isinfinite; -} uip_ds6_prefix_t; -#endif /*UIP_CONF_ROUTER */ - -/** * \brief Unicast address structure */ -typedef struct uip_ds6_addr { - uint8_t isused; - uip_ipaddr_t ipaddr; - uint8_t state; - uint8_t type; - uint8_t isinfinite; - struct stimer vlifetime; -#if UIP_ND6_DEF_MAXDADNS > 0 - struct timer dadtimer; - uint8_t dadnscount; -#endif /* UIP_ND6_DEF_MAXDADNS > 0 */ -} uip_ds6_addr_t; - -/** \brief Anycast address */ -typedef struct uip_ds6_aaddr { - uint8_t isused; - uip_ipaddr_t ipaddr; -} uip_ds6_aaddr_t; - -/** \brief A multicast address */ -typedef struct uip_ds6_maddr { - uint8_t isused; - uip_ipaddr_t ipaddr; -} uip_ds6_maddr_t; - -/* only define the callback if RPL is active */ -#if UIP_CONF_IPV6_RPL -#ifndef UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED -#define UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED rpl_ipv6_neighbor_callback -#endif /* UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED */ -#endif /* UIP_CONF_IPV6_RPL */ - -#if UIP_CONF_IPV6_RPL -#ifndef UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK -#define UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK rpl_link_neighbor_callback -#endif /* UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED */ -#endif /* UIP_CONF_IPV6_RPL */ - - -/** \brief Interface structure (contains all the interface variables) */ -typedef struct uip_ds6_netif { - uint32_t link_mtu; - uint8_t cur_hop_limit; - uint32_t base_reachable_time; /* in msec */ - uint32_t reachable_time; /* in msec */ - uint32_t retrans_timer; /* in msec */ - uint8_t maxdadns; - uip_ds6_addr_t addr_list[UIP_DS6_ADDR_NB]; - uip_ds6_aaddr_t aaddr_list[UIP_DS6_AADDR_NB]; - uip_ds6_maddr_t maddr_list[UIP_DS6_MADDR_NB]; -} uip_ds6_netif_t; - -/** \brief Generic type for a DS6, to use a common loop though all DS */ -typedef struct uip_ds6_element { - uint8_t isused; - uip_ipaddr_t ipaddr; -} uip_ds6_element_t; - - -/*---------------------------------------------------------------------------*/ -extern uip_ds6_netif_t uip_ds6_if; -extern struct etimer uip_ds6_timer_periodic; - -#if UIP_CONF_ROUTER -extern uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; -#else /* UIP_CONF_ROUTER */ -extern struct etimer uip_ds6_timer_rs; -#endif /* UIP_CONF_ROUTER */ - - -/*---------------------------------------------------------------------------*/ -/** \brief Initialize data structures */ -void uip_ds6_init(void); - -/** \brief Periodic processing of data structures */ -void uip_ds6_periodic(struct net_buf *buf); - -/** \brief Generic loop routine on an abstract data structure, which generalizes - * all data structures used in DS6 */ -uint8_t uip_ds6_list_loop(uip_ds6_element_t *list, uint8_t size, - uint16_t elementsize, uip_ipaddr_t *ipaddr, - uint8_t ipaddrlen, - uip_ds6_element_t **out_element); - -/** @} */ - - -/** \name Prefix list basic routines */ -/** @{ */ -#if UIP_CONF_ROUTER -uip_ds6_prefix_t *uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t length, - uint8_t advertise, uint8_t flags, - unsigned long vtime, - unsigned long ptime); -#else /* UIP_CONF_ROUTER */ -uip_ds6_prefix_t *uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t length, - unsigned long interval); -#endif /* UIP_CONF_ROUTER */ -void uip_ds6_prefix_rm(uip_ds6_prefix_t *prefix); -uip_ds6_prefix_t *uip_ds6_prefix_lookup(uip_ipaddr_t *ipaddr, - uint8_t ipaddrlen); -uint8_t uip_ds6_is_addr_onlink(uip_ipaddr_t *ipaddr); - -/** @} */ - -/** \name Unicast address list basic routines */ -/** @{ */ -uip_ds6_addr_t *uip_ds6_addr_add(uip_ipaddr_t *ipaddr, - unsigned long vlifetime, uint8_t type); -void uip_ds6_addr_rm(uip_ds6_addr_t *addr); -uip_ds6_addr_t *uip_ds6_addr_lookup(uip_ipaddr_t *ipaddr); -uip_ds6_addr_t *uip_ds6_get_link_local(int8_t state); -uip_ds6_addr_t *uip_ds6_get_global(int8_t state); - -/** @} */ - -/** \name Multicast address list basic routines */ -/** @{ */ -uip_ds6_maddr_t *uip_ds6_maddr_add(const uip_ipaddr_t *ipaddr); -void uip_ds6_maddr_rm(uip_ds6_maddr_t *maddr); -uip_ds6_maddr_t *uip_ds6_maddr_lookup(const uip_ipaddr_t *ipaddr); - -/** @} */ - -/** \name Anycast address list basic routines */ -/** @{ */ -uip_ds6_aaddr_t *uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr); -void uip_ds6_aaddr_rm(uip_ds6_aaddr_t *aaddr); -uip_ds6_aaddr_t *uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr); - -/** @} */ - -/** \brief Set the link local IPv6 address according to linkaddr */ -void uip_ds6_set_lladdr(uip_lladdr_t *lladdr); - -/** \brief set the last 64 bits of an IP address based on the MAC address */ -void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr); - -/** \brief Get the number of matching bits of two addresses */ -uint8_t get_match_length(uip_ipaddr_t *src, uip_ipaddr_t *dst); - -#if UIP_ND6_DEF_MAXDADNS >0 -/** \brief Perform Duplicate Address Selection on one address */ -void uip_ds6_dad(struct net_buf *buf, uip_ds6_addr_t *ifaddr); - -/** \brief Callback when DAD failed */ -int uip_ds6_dad_failed(uip_ds6_addr_t *ifaddr); -#endif /* UIP_ND6_DEF_MAXDADNS */ - -/** \brief Source address selection, see RFC 3484 */ -void uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst); - -#if UIP_CONF_ROUTER -#if UIP_ND6_SEND_RA -/** \brief Send a RA as an asnwer to a RS */ -void uip_ds6_send_ra_sollicited(void); - -/** \brief Send a periodic RA */ -void uip_ds6_send_ra_periodic(void); -#endif /* UIP_ND6_SEND_RA */ -#else /* UIP_CONF_ROUTER */ -/** \brief Send periodic RS to find router */ -void uip_ds6_send_rs(struct net_buf *buf); -#endif /* UIP_CONF_ROUTER */ - -/** \brief Compute the reachable time based on base reachable time, see RFC 4861*/ -uint32_t uip_ds6_compute_reachable_time(void); /** \brief compute random reachable timer */ - -/** \name Macros to check if an IP address (unicast, multicast or anycast) is mine */ -/** @{ */ -#define uip_ds6_is_my_addr(addr) (uip_ds6_addr_lookup(addr) != NULL) -#define uip_ds6_is_my_maddr(addr) (uip_ds6_maddr_lookup(addr) != NULL) -#define uip_ds6_is_my_aaddr(addr) (uip_ds6_aaddr_lookup(addr) != NULL) -/** @} */ -/** @} */ - -#endif /* UIP_DS6_H_ */ diff --git a/net/ip/contiki/ipv6/uip-icmp6.c b/net/ip/contiki/ipv6/uip-icmp6.c deleted file mode 100644 index dfd5de124bab23694531432d69a19482ee70739a..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/uip-icmp6.c +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack. - * - */ - -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * ICMPv6 (RFC 4443) implementation, with message and error handling - * \author Julien Abeille - * \author Mathilde Durvy - */ - -#include - -#include -#include "contiki/ipv6/uip-ds6.h" -#include "contiki/ipv6/uip-icmp6.h" -#include "contiki-default-conf.h" - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_IPV6_ICMPV6 -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) -#define UIP_ICMP_BUF(buf) ((struct uip_icmp_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)]) -#define UIP_ICMP6_ERROR_BUF(buf) ((struct uip_icmp6_error *)&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf)]) -#define UIP_EXT_BUF(buf) ((struct uip_ext_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)]) -#define UIP_FIRST_EXT_BUF(buf) ((struct uip_ext_hdr *)&uip_buf(buf)[UIP_LLIPH_LEN]) - -#if UIP_CONF_IPV6_RPL -#include "rpl/rpl.h" -#endif /* UIP_CONF_IPV6_RPL */ - -#if 0 -/* Moved this to individual functions to make the API re-entrant */ -/** \brief temporary IP address */ -static uip_ipaddr_t tmp_ipaddr; -#endif - -LIST(echo_reply_callback_list); -/*---------------------------------------------------------------------------*/ -/* List of input handlers */ -LIST(input_handler_list); -/*---------------------------------------------------------------------------*/ -static uip_icmp6_input_handler_t * -input_handler_lookup(uint8_t type, uint8_t icode) -{ - uip_icmp6_input_handler_t *handler = NULL; - - for(handler = list_head(input_handler_list); - handler != NULL; - handler = list_item_next(handler)) { - if(handler->type == type && - (handler->icode == icode || - handler->icode == UIP_ICMP6_HANDLER_CODE_ANY)) { - return handler; - } - } - - return NULL; -} -/*---------------------------------------------------------------------------*/ -uint8_t -uip_icmp6_input(struct net_buf *buf, uint8_t type, uint8_t icode) -{ - uip_icmp6_input_handler_t *handler = input_handler_lookup(type, icode); - - if(handler == NULL) { - return UIP_ICMP6_INPUT_ERROR; - } - - if(handler->handler == NULL) { - return UIP_ICMP6_INPUT_ERROR; - } - - handler->handler(buf); - return UIP_ICMP6_INPUT_SUCCESS; -} -/*---------------------------------------------------------------------------*/ -void -uip_icmp6_register_input_handler(uip_icmp6_input_handler_t *handler) -{ - list_add(input_handler_list, handler); -} -/*---------------------------------------------------------------------------*/ -static void -echo_request_input(struct net_buf *buf) -{ -#if UIP_CONF_IPV6_RPL - uint8_t temp_ext_len; -#endif /* UIP_CONF_IPV6_RPL */ - /* - * we send an echo reply. It is trivial if there was no extension - * headers in the request otherwise we need to remove the extension - * headers and change a few fields - */ - PRINTF("Received Echo Request from "); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF(" to "); - PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr); - PRINTF("\n"); - - /* IP header */ - UIP_IP_BUF(buf)->ttl = uip_ds6_if.cur_hop_limit; - - if(uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr)){ - uip_ipaddr_copy(&UIP_IP_BUF(buf)->destipaddr, &UIP_IP_BUF(buf)->srcipaddr); - uip_ds6_select_src(&UIP_IP_BUF(buf)->srcipaddr, &UIP_IP_BUF(buf)->destipaddr); - } else { - uip_ipaddr_t tmp_ipaddr; - - uip_ipaddr_copy(&tmp_ipaddr, &UIP_IP_BUF(buf)->srcipaddr); - uip_ipaddr_copy(&UIP_IP_BUF(buf)->srcipaddr, &UIP_IP_BUF(buf)->destipaddr); - uip_ipaddr_copy(&UIP_IP_BUF(buf)->destipaddr, &tmp_ipaddr); - } - - if(uip_ext_len(buf) > 0) { -#if UIP_CONF_IPV6_RPL - if((temp_ext_len = rpl_invert_header(buf))) { - /* If there were other extension headers*/ - UIP_FIRST_EXT_BUF(buf)->next = UIP_PROTO_ICMP6; - if (uip_ext_len(buf) != temp_ext_len) { - uip_len(buf) -= (uip_ext_len(buf) - temp_ext_len); - UIP_IP_BUF(buf)->len[0] = ((uip_len(buf) - UIP_IPH_LEN) >> 8); - UIP_IP_BUF(buf)->len[1] = ((uip_len(buf) - UIP_IPH_LEN) & 0xff); - /* move the echo request payload (starting after the icmp header) - * to the new location in the reply. - * The shift is equal to the length of the remaining extension headers present - * Note: UIP_ICMP_BUF still points to the echo request at this stage - */ - memmove((uint8_t *)UIP_ICMP_BUF(buf) + UIP_ICMPH_LEN - (uip_ext_len(buf) - temp_ext_len), - (uint8_t *)UIP_ICMP_BUF(buf) + UIP_ICMPH_LEN, - (uip_len(buf) - UIP_IPH_LEN - temp_ext_len - UIP_ICMPH_LEN)); - } - uip_ext_len(buf) = temp_ext_len; - } else { -#endif /* UIP_CONF_IPV6_RPL */ - /* If there were extension headers*/ - UIP_IP_BUF(buf)->proto = UIP_PROTO_ICMP6; - uip_len(buf) -= uip_ext_len(buf); - UIP_IP_BUF(buf)->len[0] = ((uip_len(buf) - UIP_IPH_LEN) >> 8); - UIP_IP_BUF(buf)->len[1] = ((uip_len(buf) - UIP_IPH_LEN) & 0xff); - /* move the echo request payload (starting after the icmp header) - * to the new location in the reply. - * The shift is equal to the length of the extension headers present - * Note: UIP_ICMP_BUF still points to the echo request at this stage - */ - memmove((uint8_t *)UIP_ICMP_BUF(buf) + UIP_ICMPH_LEN - uip_ext_len(buf), - (uint8_t *)UIP_ICMP_BUF(buf) + UIP_ICMPH_LEN, - (uip_len(buf) - UIP_IPH_LEN - UIP_ICMPH_LEN)); - uip_ext_len(buf) = 0; -#if UIP_CONF_IPV6_RPL - } -#endif /* UIP_CONF_IPV6_RPL */ - } - /* Below is important for the correctness of UIP_ICMP_BUF and the - * checksum - */ - - /* Note: now UIP_ICMP_BUF points to the beginning of the echo reply */ - UIP_ICMP_BUF(buf)->type = ICMP6_ECHO_REPLY; - UIP_ICMP_BUF(buf)->icode = 0; - UIP_ICMP_BUF(buf)->icmpchksum = 0; - UIP_ICMP_BUF(buf)->icmpchksum = ~uip_icmp6chksum(buf); - - PRINTF("Sending Echo Reply to "); - PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr); - PRINTF(" from "); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF("\n"); - UIP_STAT(++uip_stat.icmp.sent); - return; -} -/*---------------------------------------------------------------------------*/ -void -uip_icmp6_error_output(struct net_buf *buf, uint8_t type, uint8_t code, uint32_t param) { - - uip_ipaddr_t tmp_ipaddr; - - /* check if originating packet is not an ICMP error*/ - if (uip_ext_len(buf)) { - if(UIP_EXT_BUF(buf)->next == UIP_PROTO_ICMP6 && UIP_ICMP_BUF(buf)->type < 128){ - uip_len(buf) = 0; - return; - } - } else { - if(UIP_IP_BUF(buf)->proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF(buf)->type < 128){ - uip_len(buf) = 0; - return; - } - } - -#if UIP_CONF_IPV6_RPL - uip_ext_len(buf) = rpl_invert_header(buf); -#else /* UIP_CONF_IPV6_RPL */ - uip_ext_len(buf) = 0; -#endif /* UIP_CONF_IPV6_RPL */ - - /* remember data of original packet before shifting */ - uip_ipaddr_copy(&tmp_ipaddr, &UIP_IP_BUF(buf)->destipaddr); - - uip_len(buf) += UIP_IPICMPH_LEN + UIP_ICMP6_ERROR_LEN; - - if(uip_len(buf) > UIP_LINK_MTU) - uip_len(buf) = UIP_LINK_MTU; - - memmove((uint8_t *)UIP_ICMP6_ERROR_BUF(buf) + uip_ext_len(buf) + UIP_ICMP6_ERROR_LEN, - (void *)UIP_IP_BUF(buf), uip_len(buf) - UIP_IPICMPH_LEN - uip_ext_len(buf) - UIP_ICMP6_ERROR_LEN); - - UIP_IP_BUF(buf)->vtc = 0x60; - UIP_IP_BUF(buf)->tcflow = 0; - UIP_IP_BUF(buf)->flow = 0; - if (uip_ext_len(buf)) { - UIP_FIRST_EXT_BUF(buf)->next = UIP_PROTO_ICMP6; - } else { - UIP_IP_BUF(buf)->proto = UIP_PROTO_ICMP6; - } - UIP_IP_BUF(buf)->ttl = uip_ds6_if.cur_hop_limit; - - /* the source should not be unspecified nor multicast, the check for - multicast is done in uip_process */ - if(uip_is_addr_unspecified(&UIP_IP_BUF(buf)->srcipaddr)){ - uip_len(buf) = 0; - return; - } - - uip_ipaddr_copy(&UIP_IP_BUF(buf)->destipaddr, &UIP_IP_BUF(buf)->srcipaddr); - - if(uip_is_addr_mcast(&tmp_ipaddr)){ - if(type == ICMP6_PARAM_PROB && code == ICMP6_PARAMPROB_OPTION){ - uip_ds6_select_src(&UIP_IP_BUF(buf)->srcipaddr, &tmp_ipaddr); - } else { - uip_len(buf) = 0; - return; - } - } else { -#if UIP_CONF_ROUTER - /* need to pick a source that corresponds to this node */ - uip_ds6_select_src(&UIP_IP_BUF(buf)->srcipaddr, &tmp_ipaddr); -#else - uip_ipaddr_copy(&UIP_IP_BUF(buf)->srcipaddr, &tmp_ipaddr); -#endif - } - - UIP_ICMP_BUF(buf)->type = type; - UIP_ICMP_BUF(buf)->icode = code; - UIP_ICMP6_ERROR_BUF(buf)->param = uip_htonl(param); - UIP_IP_BUF(buf)->len[0] = ((uip_len(buf) - UIP_IPH_LEN) >> 8); - UIP_IP_BUF(buf)->len[1] = ((uip_len(buf) - UIP_IPH_LEN) & 0xff); - UIP_ICMP_BUF(buf)->icmpchksum = 0; - UIP_ICMP_BUF(buf)->icmpchksum = ~uip_icmp6chksum(buf); - - UIP_STAT(++uip_stat.icmp.sent); - - PRINTF("Sending ICMPv6 ERROR message type %d code %d to ", type, code); - PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr); - PRINTF(" from "); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF("\n"); - return; -} - -/*---------------------------------------------------------------------------*/ -void -uip_icmp6_send(struct net_buf *buf, const uip_ipaddr_t *dest, int type, int code, int payload_len) -{ - - UIP_IP_BUF(buf)->vtc = 0x60; - UIP_IP_BUF(buf)->tcflow = 0; - UIP_IP_BUF(buf)->flow = 0; - UIP_IP_BUF(buf)->proto = UIP_PROTO_ICMP6; - UIP_IP_BUF(buf)->ttl = uip_ds6_if.cur_hop_limit; - UIP_IP_BUF(buf)->len[0] = (UIP_ICMPH_LEN + payload_len) >> 8; - UIP_IP_BUF(buf)->len[1] = (UIP_ICMPH_LEN + payload_len) & 0xff; - - memcpy(&UIP_IP_BUF(buf)->destipaddr, dest, sizeof(*dest)); - uip_ds6_select_src(&UIP_IP_BUF(buf)->srcipaddr, &UIP_IP_BUF(buf)->destipaddr); - - UIP_ICMP_BUF(buf)->type = type; - UIP_ICMP_BUF(buf)->icode = code; - - UIP_ICMP_BUF(buf)->icmpchksum = 0; - UIP_ICMP_BUF(buf)->icmpchksum = ~uip_icmp6chksum(buf); - - uip_len(buf) = UIP_IPH_LEN + UIP_ICMPH_LEN + payload_len; - net_buf_add(buf, uip_len(buf)); - - tcpip_ipv6_output(buf); -} -/*---------------------------------------------------------------------------*/ -static void -echo_reply_input(struct net_buf *buf) -{ - int ttl; - uip_ipaddr_t sender; -#if UIP_CONF_IPV6_RPL - uint8_t temp_ext_len; -#endif /* UIP_CONF_IPV6_RPL */ - - uip_ipaddr_copy(&sender, &UIP_IP_BUF(buf)->srcipaddr); - ttl = UIP_IP_BUF(buf)->ttl; - - if(uip_ext_len(buf) > 0) { -#if UIP_CONF_IPV6_RPL - if((temp_ext_len = rpl_invert_header(buf))) { - /* If there were other extension headers*/ - UIP_FIRST_EXT_BUF(buf)->next = UIP_PROTO_ICMP6; - if (uip_ext_len(buf) != temp_ext_len) { - uip_len(buf) -= (uip_ext_len(buf) - temp_ext_len); - UIP_IP_BUF(buf)->len[0] = ((uip_len(buf) - UIP_IPH_LEN) >> 8); - UIP_IP_BUF(buf)->len[1] = ((uip_len(buf) - UIP_IPH_LEN) & 0xff); - /* move the echo reply payload (starting after the icmp - * header) to the new location in the reply. The shift is - * equal to the length of the remaining extension headers - * present Note: UIP_ICMP_BUF still points to the echo reply - * at this stage - */ - memmove((uint8_t *)UIP_ICMP_BUF(buf) + UIP_ICMPH_LEN - (uip_ext_len(buf) - temp_ext_len), - (uint8_t *)UIP_ICMP_BUF(buf) + UIP_ICMPH_LEN, - (uip_len(buf) - UIP_IPH_LEN - temp_ext_len - UIP_ICMPH_LEN)); - } - uip_ext_len(buf) = temp_ext_len; - uip_len(buf) -= uip_ext_len(buf); - } else { -#endif /* UIP_CONF_IPV6_RPL */ - /* If there were extension headers*/ - UIP_IP_BUF(buf)->proto = UIP_PROTO_ICMP6; - uip_len(buf) -= uip_ext_len(buf); - UIP_IP_BUF(buf)->len[0] = ((uip_len(buf) - UIP_IPH_LEN) >> 8); - UIP_IP_BUF(buf)->len[1] = ((uip_len(buf) - UIP_IPH_LEN) & 0xff); - /* move the echo reply payload (starting after the icmp header) - * to the new location in the reply. The shift is equal to the - * length of the extension headers present Note: UIP_ICMP_BUF - * still points to the echo request at this stage - */ - memmove((uint8_t *)UIP_ICMP_BUF(buf) + UIP_ICMPH_LEN - uip_ext_len(buf), - (uint8_t *)UIP_ICMP_BUF(buf) + UIP_ICMPH_LEN, - (uip_len(buf) - UIP_IPH_LEN - UIP_ICMPH_LEN)); - uip_ext_len(buf) = 0; -#if UIP_CONF_IPV6_RPL - } -#endif /* UIP_CONF_IPV6_RPL */ - } - - /* Call all registered applications to let them know an echo reply - has been received. */ - { - struct uip_icmp6_echo_reply_notification *n; - for(n = list_head(echo_reply_callback_list); - n != NULL; - n = list_item_next(n)) { - if(n->callback != NULL) { - n->callback(&sender, ttl, - (uint8_t *)&UIP_ICMP_BUF(buf)[sizeof(struct uip_icmp_hdr)], - uip_len(buf) - sizeof(struct uip_icmp_hdr) - UIP_IPH_LEN); - } - } - } - - uip_len(buf) = 0; - return; -} -/*---------------------------------------------------------------------------*/ -void -uip_icmp6_echo_reply_callback_add(struct uip_icmp6_echo_reply_notification *n, - uip_icmp6_echo_reply_callback_t c) -{ - if(n != NULL && c != NULL) { - n->callback = c; - list_add(echo_reply_callback_list, n); - } -} -/*---------------------------------------------------------------------------*/ -void -uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n) -{ - list_remove(echo_reply_callback_list, n); -} -/*---------------------------------------------------------------------------*/ -UIP_ICMP6_HANDLER(echo_request_handler, ICMP6_ECHO_REQUEST, - UIP_ICMP6_HANDLER_CODE_ANY, echo_request_input); -UIP_ICMP6_HANDLER(echo_reply_handler, ICMP6_ECHO_REPLY, - UIP_ICMP6_HANDLER_CODE_ANY, echo_reply_input); -/*---------------------------------------------------------------------------*/ -void -uip_icmp6_init() -{ - /* Register Echo Request and Reply handlers */ - uip_icmp6_register_input_handler(&echo_request_handler); - uip_icmp6_register_input_handler(&echo_reply_handler); -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/ipv6/uip-icmp6.h b/net/ip/contiki/ipv6/uip-icmp6.h deleted file mode 100644 index 322e9ca5c3ddc587ff768b8ab1534fb343023d76..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/uip-icmp6.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * Header file for ICMPv6 message and error handing (RFC 4443) - * \author Julien Abeille - * \author Mathilde Durvy - */ - -#include - -#ifndef ICMP6_H_ -#define ICMP6_H_ - -#include "contiki/ip/uip.h" - - -/** \name ICMPv6 message types */ -/** @{ */ -#define ICMP6_DST_UNREACH 1 /**< dest unreachable */ -#define ICMP6_PACKET_TOO_BIG 2 /**< packet too big */ -#define ICMP6_TIME_EXCEEDED 3 /**< time exceeded */ -#define ICMP6_PARAM_PROB 4 /**< ip6 header bad */ -#define ICMP6_ECHO_REQUEST 128 /**< Echo request */ -#define ICMP6_ECHO_REPLY 129 /**< Echo reply */ - -#define ICMP6_RS 133 /**< Router Solicitation */ -#define ICMP6_RA 134 /**< Router Advertisement */ -#define ICMP6_NS 135 /**< Neighbor Solicitation */ -#define ICMP6_NA 136 /**< Neighbor advertisement */ -#define ICMP6_REDIRECT 137 /**< Redirect */ - -#define ICMP6_RPL 155 /**< RPL */ -#define ICMP6_PRIV_EXP_100 100 /**< Private Experimentation */ -#define ICMP6_PRIV_EXP_101 101 /**< Private Experimentation */ -#define ICMP6_PRIV_EXP_200 200 /**< Private Experimentation */ -#define ICMP6_PRIV_EXP_201 201 /**< Private Experimentation */ -#define ICMP6_ROLL_TM ICMP6_PRIV_EXP_200 /**< ROLL Trickle Multicast */ -/** @} */ - - -/** \name ICMPv6 Destination Unreachable message codes*/ -/** @{ */ -#define ICMP6_DST_UNREACH_NOROUTE 0 /**< no route to destination */ -#define ICMP6_DST_UNREACH_ADMIN 1 /**< administratively prohibited */ -#define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /**< not a neighbor(obsolete) */ -#define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /**< beyond scope of source address */ -#define ICMP6_DST_UNREACH_ADDR 3 /**< address unreachable */ -#define ICMP6_DST_UNREACH_NOPORT 4 /**< port unreachable */ -/** @} */ - -/** \name ICMPv6 Time Exceeded message codes*/ -/** @{ */ -#define ICMP6_TIME_EXCEED_TRANSIT 0 /**< ttl==0 in transit */ -#define ICMP6_TIME_EXCEED_REASSEMBLY 1 /**< ttl==0 in reass */ -/** @} */ - -/** \name ICMPv6 Parameter Problem message codes*/ -/** @{ */ -#define ICMP6_PARAMPROB_HEADER 0 /**< erroneous header field */ -#define ICMP6_PARAMPROB_NEXTHEADER 1 /**< unrecognized next header */ -#define ICMP6_PARAMPROB_OPTION 2 /**< unrecognized option */ -/** @} */ - -/** \brief Echo Request constant part length */ -#define UIP_ICMP6_ECHO_REQUEST_LEN 4 - -/** \brief ICMPv6 Error message constant part length */ -#define UIP_ICMP6_ERROR_LEN 4 - -/** \brief ICMPv6 Error message constant part */ -typedef struct uip_icmp6_error{ - uint32_t param; -} PACK_ALIAS_STRUCT uip_icmp6_error; - -/** \name ICMPv6 RFC4443 Message processing and sending */ -/** @{ */ -/** - * \brief Send an icmpv6 error message - * \param type type of the error message - * \param code of the error message - * \param param 32 bit parameter of the error message, semantic depends on error - */ -void -uip_icmp6_error_output(struct net_buf *buf, uint8_t type, uint8_t code, uint32_t param); - -/** - * \brief Send an icmpv6 message - * \param dest destination address of the message - * \param type type of the message - * \param code of the message - * \param payload_len length of the payload - */ -void -uip_icmp6_send(struct net_buf *buf, const uip_ipaddr_t *dest, int type, int code, int payload_len); - - - -typedef void (* uip_icmp6_echo_reply_callback_t)(uip_ipaddr_t *source, - uint8_t ttl, - uint8_t *data, - uint16_t datalen); -struct uip_icmp6_echo_reply_notification { - struct uip_icmp6_echo_reply_notification *next; - uip_icmp6_echo_reply_callback_t callback; -}; - -/** - * \brief Add a callback function for ping replies - * \param n A struct uip_icmp6_echo_reply_notification that must have been allocated by the caller - * \param c A pointer to the callback function to be called - * - * This function adds a callback function to the list of - * callback functions that are called when an ICMP echo - * reply (ping reply) is received. This is used when - * implementing a ping protocol: attach a callback - * function to the ping reply, then send out a ping packet - * with uip_icmp6_send(). - * - * The caller must have statically allocated a struct - * uip_icmp6_echo_reply_notification to hold the internal - * state of the callback function. - * - * When a ping reply packet is received, all registered - * callback functions are called. The callback functions - * must not modify the contents of the uIP buffer. - */ -void -uip_icmp6_echo_reply_callback_add(struct uip_icmp6_echo_reply_notification *n, - uip_icmp6_echo_reply_callback_t c); - -/** - * \brief Remove a callback function for ping replies - * \param n A struct uip_icmp6_echo_reply_notification that must have been previously added with uip_icmp6_echo_reply_callback_add() - * - * This function removes a callback function from the list of - * callback functions that are called when an ICMP echo - * reply (ping reply) is received. - */ -void -uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n); - -/* Generic ICMPv6 input handers */ -typedef struct uip_icmp6_input_handler { - struct uip_icmp6_input_handler *next; - uint8_t type; - uint8_t icode; - void (*handler)(struct net_buf *buf); -} uip_icmp6_input_handler_t; - -#define UIP_ICMP6_INPUT_SUCCESS 0 -#define UIP_ICMP6_INPUT_ERROR 1 - -#define UIP_ICMP6_HANDLER_CODE_ANY 0xFF /* Handle all codes for this type */ - -/* - * Initialise a variable of type uip_icmp6_input_handler, to be used later as - * the argument to uip_icmp6_register_input_handler - * - * The function pointer stored in this variable will get called and will be - * expected to handle incoming ICMPv6 datagrams of the specified type/code - * - * If code has a value of UIP_ICMP6_HANDLER_CODE_ANY, the same function - * will handle all codes for this type. In other words, the ICMPv6 - * message's code is "don't care" - */ -#define UIP_ICMP6_HANDLER(name, type, code, func) \ - static uip_icmp6_input_handler_t name = { NULL, type, code, func } - -/** - * \brief Handle an incoming ICMPv6 message - * \param type The ICMPv6 message type - * \param icode The ICMPv6 message code - * \return Success: UIP_ICMP6_INPUT_SUCCESS, Error: UIP_ICMP6_INPUT_ERROR - * - * Generic handler for unknown ICMPv6 types. It will lookup for a registered - * function capable of handing this message type. The function must have first - * been registered with uip_icmp6_register_input_handler. The function is in - * charge of setting uip_len to 0, otherwise the uIPv6 core will attempt to - * send whatever remains in the UIP_IP_BUF. - * - * A return value of UIP_ICMP6_INPUT_ERROR means that a handler could not be - * invoked. This is most likely because the ICMPv6 type does not have a valid - * handler associated with it. - - * UIP_ICMP6_INPUT_SUCCESS signifies that a handler was found for this ICMPv6 - * type and that it was invoked. It does NOT provide any indication whatsoever - * regarding whether the handler itself succeeded. - */ -uint8_t uip_icmp6_input(struct net_buf *buf, uint8_t type, uint8_t icode); - -/** - * \brief Register a handler which can handle a specific ICMPv6 message type - * \param handler A pointer to the handler - */ -void uip_icmp6_register_input_handler(uip_icmp6_input_handler_t *handler); - - -/** - * \brief Initialise the uIP ICMPv6 core - */ -void uip_icmp6_init(void); - -/** @} */ - -#endif /*ICMP6_H_*/ -/** @} */ - diff --git a/net/ip/contiki/ipv6/uip-nd6.c b/net/ip/contiki/ipv6/uip-nd6.c deleted file mode 100644 index e8fc1de86d331e5ffbeb48aabb411105e5d5b139..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/uip-nd6.c +++ /dev/null @@ -1,1159 +0,0 @@ -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * Neighbor discovery (RFC 4861) - * \author Mathilde Durvy - * \author Julien Abeille - */ - -#include - -#include -#include "contiki/ipv6/uip-icmp6.h" -#include "contiki/ipv6/uip-nd6.h" -#include "contiki/ipv6/uip-ds6.h" -#include "contiki/ip/uip-nameserver.h" -#include "lib/random.h" - -/*------------------------------------------------------------------*/ -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_IPV6_ND -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#if UIP_LOGGING -#include -void uip_log(char *msg); - -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif /* UIP_LOGGING == 1 */ - -/*------------------------------------------------------------------*/ -/** @{ */ -/** \name Pointers to the header structures. - * All pointers except UIP_IP_BUF depend on uip_ext_len, which at - * packet reception, is the total length of the extension headers. - * - * The pointer to ND6 options header also depends on nd6_opt_offset, - * which we set in each function. - * - * Care should be taken when manipulating these buffers about the - * value of these length variables - */ - -#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) /**< Pointer to IP header */ -#define UIP_ICMP_BUF(buf) ((struct uip_icmp_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)]) /**< Pointer to ICMP header*/ -/**@{ Pointers to messages just after icmp header */ -#define UIP_ND6_RS_BUF(buf) ((uip_nd6_rs *)&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf)]) -#define UIP_ND6_RA_BUF(buf) ((uip_nd6_ra *)&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf)]) -#define UIP_ND6_NS_BUF(buf) ((uip_nd6_ns *)&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf)]) -#define UIP_ND6_NA_BUF(buf) ((uip_nd6_na *)&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf)]) -/** @} */ -/** Pointer to ND option */ -#define UIP_ND6_OPT_HDR_BUF(buf) ((uip_nd6_opt_hdr *)&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf) + uip_nd6_opt_offset(buf)]) -#define UIP_ND6_OPT_PREFIX_BUF(buf) ((uip_nd6_opt_prefix_info *)&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf) + uip_nd6_opt_offset(buf)]) -#define UIP_ND6_OPT_MTU_BUF(buf) ((uip_nd6_opt_mtu *)&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf) + uip_nd6_opt_offset(buf)]) -#define UIP_ND6_OPT_RDNSS_BUF(buf) ((uip_nd6_opt_dns *)&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf) + uip_nd6_opt_offset(buf)]) -/** @} */ - -#if 0 -/* The vars moved to net_buf */ -static uint8_t nd6_opt_offset; /** Offset from the end of the icmpv6 header to the option in uip_buf*/ -static uint8_t *nd6_opt_llao; /** Pointer to llao option in uip_buf */ - -#if !UIP_CONF_ROUTER // TBD see if we move it to ra_input -static uip_nd6_opt_prefix_info *nd6_opt_prefix_info; /** Pointer to prefix information option in uip_buf */ -static uip_ipaddr_t ipaddr; -static uip_ds6_prefix_t *prefix; /** Pointer to a prefix list entry */ -#endif -static uip_ds6_nbr_t *nbr; /** Pointer to a nbr cache entry*/ -static uip_ds6_defrt_t *defrt; /** Pointer to a router list entry */ -static uip_ds6_addr_t *addr; /** Pointer to an interface address */ -#endif - -/*------------------------------------------------------------------*/ -/* create a llao */ -static void -create_llao(uint8_t *llao, uint8_t type) { - llao[UIP_ND6_OPT_TYPE_OFFSET] = type; - llao[UIP_ND6_OPT_LEN_OFFSET] = UIP_ND6_OPT_LLAO_LEN >> 3; - memcpy(&llao[UIP_ND6_OPT_DATA_OFFSET], &uip_lladdr, UIP_LLADDR_LEN); - /* padding on some */ - memset(&llao[UIP_ND6_OPT_DATA_OFFSET + UIP_LLADDR_LEN], 0, - UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN); -} - -/*------------------------------------------------------------------*/ - -#if UIP_ND6_SEND_NA -static void -ns_input(struct net_buf *buf) -{ - PRINTF("Received NS from "); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF(" to "); - PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr); - PRINTF(" with target address "); - PRINT6ADDR((uip_ipaddr_t *) (&UIP_ND6_NS_BUF(buf)->tgtipaddr)); - PRINTF("\n"); - UIP_STAT(++uip_stat.nd6.recv); - -#if UIP_CONF_IPV6_CHECKS - if((UIP_IP_BUF(buf)->ttl != UIP_ND6_HOP_LIMIT) || - (uip_is_addr_mcast(&UIP_ND6_NS_BUF(buf)->tgtipaddr)) || - (UIP_ICMP_BUF(buf)->icode != 0)) { - PRINTF("NS received is bad\n"); - goto discard; - } -#endif /* UIP_CONF_IPV6_CHECKS */ - - /* Options processing */ - uip_set_nd6_opt_llao(buf) = NULL; - uip_nd6_opt_offset(buf) = UIP_ND6_NS_LEN; - while(uip_l3_icmp_hdr_len(buf) + uip_nd6_opt_offset(buf) < uip_len(buf)) { -#if UIP_CONF_IPV6_CHECKS - if(UIP_ND6_OPT_HDR_BUF(buf)->len == 0) { - PRINTF("NS received is bad\n"); - goto discard; - } -#endif /* UIP_CONF_IPV6_CHECKS */ - switch (UIP_ND6_OPT_HDR_BUF(buf)->type) { - case UIP_ND6_OPT_SLLAO: - uip_set_nd6_opt_llao(buf) = &uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf) + uip_nd6_opt_offset(buf)]; -#if UIP_CONF_IPV6_CHECKS - /* There must be NO option in a DAD NS */ - if(uip_is_addr_unspecified(&UIP_IP_BUF(buf)->srcipaddr)) { - PRINTF("NS received is bad\n"); - goto discard; - } else { -#endif /*UIP_CONF_IPV6_CHECKS */ - uip_set_nbr(buf) = uip_ds6_nbr_lookup(&UIP_IP_BUF(buf)->srcipaddr); - if(uip_nbr(buf) == NULL) { - uip_ds6_nbr_add(&UIP_IP_BUF(buf)->srcipaddr, - (uip_lladdr_t *)&uip_nd6_opt_llao(buf)[UIP_ND6_OPT_DATA_OFFSET], - 0, NBR_STALE); - } else { - uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(uip_nbr(buf)); - if(memcmp(&uip_nd6_opt_llao(buf)[UIP_ND6_OPT_DATA_OFFSET], - lladdr, UIP_LLADDR_LEN) != 0) { - memcpy(lladdr, &uip_nd6_opt_llao(buf)[UIP_ND6_OPT_DATA_OFFSET], - UIP_LLADDR_LEN); - uip_nbr(buf)->state = NBR_STALE; - } else { - if(uip_nbr(buf)->state == NBR_INCOMPLETE) { - uip_nbr(buf)->state = NBR_STALE; - } - } - } -#if UIP_CONF_IPV6_CHECKS - } -#endif /*UIP_CONF_IPV6_CHECKS */ - break; - default: - PRINTF("ND option (0x%x) not supported in NS\n", - UIP_ND6_OPT_HDR_BUF(buf)->type); - break; - } - uip_nd6_opt_offset(buf) += (UIP_ND6_OPT_HDR_BUF(buf)->len << 3); - } - - uip_set_addr(buf) = uip_ds6_addr_lookup(&UIP_ND6_NS_BUF(buf)->tgtipaddr); - if(uip_addr(buf) != NULL) { -#if UIP_ND6_DEF_MAXDADNS > 0 - if(uip_is_addr_unspecified(&UIP_IP_BUF(buf)->srcipaddr)) { - /* DAD CASE */ -#if UIP_CONF_IPV6_CHECKS - if(!uip_is_addr_solicited_node(&UIP_IP_BUF(buf)->destipaddr)) { - PRINTF("NS received is bad\n"); - goto discard; - } -#endif /* UIP_CONF_IPV6_CHECKS */ - if(uip_addr(buf)->state != ADDR_TENTATIVE) { - uip_create_linklocal_allnodes_mcast(&UIP_IP_BUF(buf)->destipaddr); - uip_ds6_select_src(&UIP_IP_BUF(buf)->srcipaddr, &UIP_IP_BUF(buf)->destipaddr); - uip_flags(buf) = UIP_ND6_NA_FLAG_OVERRIDE; - goto create_na; - } else { - /** \todo if I sent a NS before him, I win */ - uip_ds6_dad_failed(uip_addr(buf)); - goto discard; - } -#else /* UIP_ND6_DEF_MAXDADNS > 0 */ - if(uip_is_addr_unspecified(&UIP_IP_BUF(buf)->srcipaddr)) { - /* DAD CASE */ - goto discard; -#endif /* UIP_ND6_DEF_MAXDADNS > 0 */ - } -#if UIP_CONF_IPV6_CHECKS - if(uip_ds6_is_my_addr(&UIP_IP_BUF(buf)->srcipaddr)) { - /** - * \NOTE do we do something here? we both are using the same address. - * If we are doing dad, we could cancel it, though we should receive a - * NA in response of DAD NS we sent, hence DAD will fail anyway. If we - * were not doing DAD, it means there is a duplicate in the network! - */ - PRINTF("NS received is bad\n"); - goto discard; - } -#endif /*UIP_CONF_IPV6_CHECKS */ - - /* Address resolution case */ - if(uip_is_addr_solicited_node(&UIP_IP_BUF(buf)->destipaddr)) { - uip_ipaddr_copy(&UIP_IP_BUF(buf)->destipaddr, &UIP_IP_BUF(buf)->srcipaddr); - uip_ipaddr_copy(&UIP_IP_BUF(buf)->srcipaddr, &UIP_ND6_NS_BUF(buf)->tgtipaddr); - uip_flags(buf) = UIP_ND6_NA_FLAG_SOLICITED | UIP_ND6_NA_FLAG_OVERRIDE; - goto create_na; - } - - /* NUD CASE */ - if(uip_ds6_addr_lookup(&UIP_IP_BUF(buf)->destipaddr) == uip_addr(buf)) { - uip_ipaddr_copy(&UIP_IP_BUF(buf)->destipaddr, &UIP_IP_BUF(buf)->srcipaddr); - uip_ipaddr_copy(&UIP_IP_BUF(buf)->srcipaddr, &UIP_ND6_NS_BUF(buf)->tgtipaddr); - uip_flags(buf) = UIP_ND6_NA_FLAG_SOLICITED | UIP_ND6_NA_FLAG_OVERRIDE; - goto create_na; - } else { -#if UIP_CONF_IPV6_CHECKS - PRINTF("NS received is bad\n"); - goto discard; -#endif /* UIP_CONF_IPV6_CHECKS */ - } - } else { - goto discard; - } - - -create_na: - /* If the node is a router it should set R flag in NAs */ -#if UIP_CONF_ROUTER - uip_flags(buf) = uip_flags(buf) | UIP_ND6_NA_FLAG_ROUTER; -#endif - uip_ext_len(buf) = 0; - UIP_IP_BUF(buf)->vtc = 0x60; - UIP_IP_BUF(buf)->tcflow = 0; - UIP_IP_BUF(buf)->flow = 0; - UIP_IP_BUF(buf)->len[0] = 0; /* length will not be more than 255 */ - UIP_IP_BUF(buf)->len[1] = UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN; - UIP_IP_BUF(buf)->proto = UIP_PROTO_ICMP6; - UIP_IP_BUF(buf)->ttl = UIP_ND6_HOP_LIMIT; - - UIP_ICMP_BUF(buf)->type = ICMP6_NA; - UIP_ICMP_BUF(buf)->icode = 0; - - UIP_ND6_NA_BUF(buf)->flagsreserved = uip_flags(buf); - memcpy(&UIP_ND6_NA_BUF(buf)->tgtipaddr, &uip_addr(buf)->ipaddr, sizeof(uip_ipaddr_t)); - - create_llao(&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf) + UIP_ND6_NA_LEN], - UIP_ND6_OPT_TLLAO); - - UIP_ICMP_BUF(buf)->icmpchksum = 0; - UIP_ICMP_BUF(buf)->icmpchksum = ~uip_icmp6chksum(buf); - - uip_len(buf) = buf->len = - UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN; - - UIP_STAT(++uip_stat.nd6.sent); - PRINTF("Sending NA to "); - PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr); - PRINTF(" from "); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF(" with target address "); - PRINT6ADDR(&UIP_ND6_NA_BUF(buf)->tgtipaddr); - PRINTF("\n"); - return; - -discard: - uip_len(buf) = 0; - uip_ext_len(buf) = 0; - return; -} -#endif /* UIP_ND6_SEND_NA */ - - - -/*------------------------------------------------------------------*/ -void -uip_nd6_ns_output(struct net_buf *buf, uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt) -{ - bool send_from_here = true; - - if (!buf) { - buf = ip_buf_get_reserve_tx(UIP_IPICMPH_LEN); - if (!buf) { - PRINTF("%s(): Cannot send NS, no net buffers\n", __FUNCTION__); - return; - } - send_from_here = true; - } - uip_ext_len(buf) = 0; - UIP_IP_BUF(buf)->vtc = 0x60; - UIP_IP_BUF(buf)->tcflow = 0; - UIP_IP_BUF(buf)->flow = 0; - UIP_IP_BUF(buf)->proto = UIP_PROTO_ICMP6; - UIP_IP_BUF(buf)->ttl = UIP_ND6_HOP_LIMIT; - - if(dest == NULL) { - uip_create_solicited_node(tgt, &UIP_IP_BUF(buf)->destipaddr); - } else { - uip_ipaddr_copy(&UIP_IP_BUF(buf)->destipaddr, dest); - } - UIP_ICMP_BUF(buf)->type = ICMP6_NS; - UIP_ICMP_BUF(buf)->icode = 0; - UIP_ND6_NS_BUF(buf)->reserved = 0; - uip_ipaddr_copy((uip_ipaddr_t *) &UIP_ND6_NS_BUF(buf)->tgtipaddr, tgt); - UIP_IP_BUF(buf)->len[0] = 0; /* length will not be more than 255 */ - /* - * check if we add a SLLAO option: for DAD, MUST NOT, for NUD, MAY - * (here yes), for Address resolution , MUST - */ - if(!(uip_ds6_is_my_addr(tgt))) { - if(src != NULL) { - uip_ipaddr_copy(&UIP_IP_BUF(buf)->srcipaddr, src); - } else { - uip_ds6_select_src(&UIP_IP_BUF(buf)->srcipaddr, &UIP_IP_BUF(buf)->destipaddr); - } - if (uip_is_addr_unspecified(&UIP_IP_BUF(buf)->srcipaddr)) { - PRINTF("Dropping NS due to no suitable source address\n"); - uip_len(buf) = 0; - if (send_from_here) { - ip_buf_unref(buf); - } - return; - } - UIP_IP_BUF(buf)->len[1] = - UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN; - - create_llao(&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf) + UIP_ND6_NS_LEN], - UIP_ND6_OPT_SLLAO); - - uip_len(buf) = - UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN; - net_buf_add(buf, UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN); - } else { - uip_create_unspecified(&UIP_IP_BUF(buf)->srcipaddr); - UIP_IP_BUF(buf)->len[1] = UIP_ICMPH_LEN + UIP_ND6_NS_LEN; - uip_len(buf) = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NS_LEN; - net_buf_add(buf, UIP_ND6_NS_LEN); - } - - UIP_ICMP_BUF(buf)->icmpchksum = 0; - UIP_ICMP_BUF(buf)->icmpchksum = ~uip_icmp6chksum(buf); - - UIP_STAT(++uip_stat.nd6.sent); - PRINTF("Sending NS to "); - PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr); - PRINTF(" from "); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF(" with target address "); - PRINT6ADDR(tgt); - PRINTF("\n"); - - if (send_from_here) { - if (tcpip_ipv6_output(buf) == 0) { - ip_buf_unref(buf); - } - } - return; -} -/*------------------------------------------------------------------*/ -/** - * Neighbor Advertisement Processing - * - * we might have to send a pkt that had been buffered while address - * resolution was performed (if we support buffering, see UIP_CONF_QUEUE_PKT) - * - * As per RFC 4861, on link layer that have addresses, TLLAO options MUST be - * included when responding to multicast solicitations, SHOULD be included in - * response to unicast (here we assume it is for now) - * - * NA can be received after sending NS for DAD, Address resolution or NUD. Can - * be unsolicited as well. - * It can trigger update of the state of the neighbor in the neighbor cache, - * router in the router list. - * If the NS was for DAD, it means DAD failed - * - */ -#if UIP_ND6_SEND_NA -static void -na_input(struct net_buf *buf) -{ - uint8_t is_llchange; - uint8_t is_router; - uint8_t is_solicited; - uint8_t is_override; - - PRINTF("Received NA from "); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF(" to "); - PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr); - PRINTF(" with target address "); - PRINT6ADDR((uip_ipaddr_t *) (&UIP_ND6_NA_BUF(buf)->tgtipaddr)); - PRINTF("\n"); - UIP_STAT(++uip_stat.nd6.recv); - - /* - * booleans. the three last one are not 0 or 1 but 0 or 0x80, 0x40, 0x20 - * but it works. Be careful though, do not use tests such as is_router == 1 - */ - is_llchange = 0; - is_router = ((UIP_ND6_NA_BUF(buf)->flagsreserved & UIP_ND6_NA_FLAG_ROUTER)); - is_solicited = - ((UIP_ND6_NA_BUF(buf)->flagsreserved & UIP_ND6_NA_FLAG_SOLICITED)); - is_override = - ((UIP_ND6_NA_BUF(buf)->flagsreserved & UIP_ND6_NA_FLAG_OVERRIDE)); - -#if UIP_CONF_IPV6_CHECKS - if((UIP_IP_BUF(buf)->ttl != UIP_ND6_HOP_LIMIT) || - (UIP_ICMP_BUF(buf)->icode != 0) || - (uip_is_addr_mcast(&UIP_ND6_NA_BUF(buf)->tgtipaddr)) || - (is_solicited && uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr))) { - PRINTF("NA received is bad\n"); - goto discard; - } -#endif /*UIP_CONF_IPV6_CHECKS */ - - /* Options processing: we handle TLLAO, and must ignore others */ - uip_nd6_opt_offset(buf) = UIP_ND6_NA_LEN; - uip_set_nd6_opt_llao(buf) = NULL; - while(uip_l3_icmp_hdr_len(buf) + uip_nd6_opt_offset(buf) < uip_len(buf)) { -#if UIP_CONF_IPV6_CHECKS - if(UIP_ND6_OPT_HDR_BUF(buf)->len == 0) { - PRINTF("NA received is bad\n"); - goto discard; - } -#endif /*UIP_CONF_IPV6_CHECKS */ - switch (UIP_ND6_OPT_HDR_BUF(buf)->type) { - case UIP_ND6_OPT_TLLAO: - uip_set_nd6_opt_llao(buf) = (uint8_t *)UIP_ND6_OPT_HDR_BUF(buf); - break; - default: - PRINTF("ND option (0x%x) not supported in NA\n", - UIP_ND6_OPT_HDR_BUF(buf)->type); - break; - } - uip_nd6_opt_offset(buf) += (UIP_ND6_OPT_HDR_BUF(buf)->len << 3); - } - uip_set_addr(buf) = uip_ds6_addr_lookup(&UIP_ND6_NA_BUF(buf)->tgtipaddr); - /* Message processing, including TLLAO if any */ - if(uip_addr(buf) != NULL) { -#if UIP_ND6_DEF_MAXDADNS > 0 - if(uip_addr(buf)->state == ADDR_TENTATIVE) { - uip_ds6_dad_failed(uip_addr(buf)); - } -#endif /*UIP_ND6_DEF_MAXDADNS > 0 */ - PRINTF("NA received is bad\n"); - goto discard; - } else { - uip_lladdr_t *lladdr; - uip_set_nbr(buf) = uip_ds6_nbr_lookup(&UIP_ND6_NA_BUF(buf)->tgtipaddr); - lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(uip_nbr(buf)); - if(uip_nbr(buf) == NULL) { - goto discard; - } - if(uip_nd6_opt_llao(buf) != 0) { - is_llchange = - memcmp(&uip_nd6_opt_llao(buf)[UIP_ND6_OPT_DATA_OFFSET], (void *)lladdr, - UIP_LLADDR_LEN); - } - if(uip_nbr(buf)->state == NBR_INCOMPLETE) { - if(uip_nd6_opt_llao(buf) == NULL) { - goto discard; - } - memcpy(lladdr, &uip_nd6_opt_llao(buf)[UIP_ND6_OPT_DATA_OFFSET], - UIP_LLADDR_LEN); - if(is_solicited) { - uip_nbr(buf)->state = NBR_REACHABLE; - uip_nbr(buf)->nscount = 0; - - /* reachable time is stored in ms */ - stimer_set(&(uip_nbr(buf)->reachable), uip_ds6_if.reachable_time / 1000); - - } else { - uip_nbr(buf)->state = NBR_STALE; - } - uip_nbr(buf)->isrouter = is_router; - } else { - if(!is_override && is_llchange) { - if(uip_nbr(buf)->state == NBR_REACHABLE) { - uip_nbr(buf)->state = NBR_STALE; - } - goto discard; - } else { - if(is_override || (!is_override && uip_nd6_opt_llao(buf) != 0 && !is_llchange) - || uip_nd6_opt_llao(buf) == 0) { - if(uip_nd6_opt_llao(buf) != 0) { - memcpy(lladdr, &uip_nd6_opt_llao(buf)[UIP_ND6_OPT_DATA_OFFSET], - UIP_LLADDR_LEN); - } - if(is_solicited) { - uip_nbr(buf)->state = NBR_REACHABLE; - /* reachable time is stored in ms */ - stimer_set(&(uip_nbr(buf)->reachable), uip_ds6_if.reachable_time / 1000); - } else { - if(uip_nd6_opt_llao(buf) != 0 && is_llchange) { - uip_nbr(buf)->state = NBR_STALE; - } - } - } - } - if(uip_nbr(buf)->isrouter && !is_router) { - uip_set_defrt(buf) = uip_ds6_defrt_lookup(&UIP_IP_BUF(buf)->srcipaddr); - if(uip_defrt(buf) != NULL) { - uip_ds6_defrt_rm(uip_defrt(buf)); - } - } - uip_nbr(buf)->isrouter = is_router; - } - } -#if UIP_CONF_IPV6_QUEUE_PKT - /* The nbr is now reachable, check if we had buffered a pkt for it */ - /*if(nbr->queue_buf_len != 0) { - uip_len = nbr->queue_buf_len; - memcpy(UIP_IP_BUF, nbr->queue_buf, uip_len); - nbr->queue_buf_len = 0; - return; - }*/ - if(uip_packetqueue_buflen(&uip_nbr(buf)->packethandle) != 0) { - uip_len(buf) = buf->len = uip_packetqueue_buflen(&uip_nbr(buf)->packethandle); - memcpy(UIP_IP_BUF(buf), uip_packetqueue_buf(&uip_nbr(buf)->packethandle), uip_len(buf)); - uip_packetqueue_free(&uip_nbr(buf)->packethandle); - return; - } - -#endif /*UIP_CONF_IPV6_QUEUE_PKT */ - -discard: - uip_len(buf) = 0; - uip_ext_len(buf) = 0; - return; -} -#endif /* UIP_ND6_SEND_NA */ - - -#if UIP_CONF_ROUTER -#if UIP_ND6_SEND_RA -/*---------------------------------------------------------------------------*/ -static void -rs_input(void) -{ - - PRINTF("Received RS from "); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF(" to "); - PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr); - PRINTF("\n"); - UIP_STAT(++uip_stat.nd6.recv); - - -#if UIP_CONF_IPV6_CHECKS - /* - * Check hop limit / icmp code - * target address must not be multicast - * if the NA is solicited, dest must not be multicast - */ - if((UIP_IP_BUF(buf)->ttl != UIP_ND6_HOP_LIMIT) || (UIP_ICMP_BUF->icode != 0)) { - PRINTF("RS received is bad\n"); - goto discard; - } -#endif /*UIP_CONF_IPV6_CHECKS */ - - /* Only valid option is Source Link-Layer Address option any thing - else is discarded */ - uip_nd6_opt_offset(buf) = UIP_ND6_RS_LEN; - uip_set_nd6_opt_llao = NULL; - - while(uip_l3_icmp_hdr_len + uip_nd6_opt_offset(buf) < uip_len) { -#if UIP_CONF_IPV6_CHECKS - if(UIP_ND6_OPT_HDR_BUF->len == 0) { - PRINTF("RS received is bad\n"); - goto discard; - } -#endif /*UIP_CONF_IPV6_CHECKS */ - switch (UIP_ND6_OPT_HDR_BUF->type) { - case UIP_ND6_OPT_SLLAO: - uip_set_nd6_opt_llao = (uint8_t *)UIP_ND6_OPT_HDR_BUF; - break; - default: - PRINTF("ND option (0x%x) not supported in RS\n", - UIP_ND6_OPT_HDR_BUF(buf)->type); - break; - } - uip_nd6_opt_offset(buf) += (UIP_ND6_OPT_HDR_BUF->len << 3); - } - /* Options processing: only SLLAO */ - if(nd6_opt_llao != NULL) { -#if UIP_CONF_IPV6_CHECKS - if(uip_is_addr_unspecified(&UIP_IP_BUF(buf)->srcipaddr)) { - PRINTF("RS received is bad\n"); - goto discard; - } else { -#endif /*UIP_CONF_IPV6_CHECKS */ - if((uip_set_nbr(buf) = uip_ds6_nbr_lookup(&UIP_IP_BUF(buf)->srcipaddr)) == NULL) { - /* we need to add the neighbor */ - uip_ds6_nbr_add(&UIP_IP_BUF(buf)->srcipaddr, - (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE); - } else { - /* If LL address changed, set neighbor state to stale */ - if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - uip_ds6_nbr_get_ll(uip_nbr(buf)), UIP_LLADDR_LEN) != 0) { - uip_ds6_nbr_t nbr_data = *(uip_ds6_nbr_t *)uip_nbr(buf); - uip_ds6_nbr_rm(uip_nbr(buf)); - uip_set_nbr(buf) = uip_ds6_nbr_add(&UIP_IP_BUF(buf)->srcipaddr, - (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE); - uip_nbr(buf)->reachable = nbr_data.reachable; - uip_nbr(buf)->sendns = nbr_data.sendns; - uip_nbr(buf)->nscount = nbr_data.nscount; - } - uip_nbr(buf)->isrouter = 0; - } -#if UIP_CONF_IPV6_CHECKS - } -#endif /*UIP_CONF_IPV6_CHECKS */ - } - - /* Schedule a sollicited RA */ - uip_ds6_send_ra_sollicited(); - -discard: - uip_len = 0; - uip_ext_len = 0; - return; -} - -/*---------------------------------------------------------------------------*/ -void -uip_nd6_ra_output(uip_ipaddr_t * dest) -{ - bool send_from_here = true; - - if (!buf) { - buf = ip_buf_get_reserve_tx(UIP_IPICMPH_LEN); - if (!buf) { - PRINTF("%s(): Cannot send RA, no net buffers\n", __FUNCTION__); - return; - } - - send_from_here = true; - } - - UIP_IP_BUF(buf)->vtc = 0x60; - UIP_IP_BUF(buf)->tcflow = 0; - UIP_IP_BUF(buf)->flow = 0; - UIP_IP_BUF(buf)->proto = UIP_PROTO_ICMP6; - UIP_IP_BUF(buf)->ttl = UIP_ND6_HOP_LIMIT; - - if(dest == NULL) { - uip_create_linklocal_allnodes_mcast(&UIP_IP_BUF(buf)->destipaddr); - } else { - /* For sollicited RA */ - uip_ipaddr_copy(&UIP_IP_BUF(buf)->destipaddr, dest); - } - uip_ds6_select_src(&UIP_IP_BUF(buf)->srcipaddr, &UIP_IP_BUF(buf)->destipaddr); - - UIP_ICMP_BUF->type = ICMP6_RA; - UIP_ICMP_BUF->icode = 0; - - UIP_ND6_RA_BUF->cur_ttl = uip_ds6_if.cur_hop_limit; - - UIP_ND6_RA_BUF->flags_reserved = - (UIP_ND6_M_FLAG << 7) | (UIP_ND6_O_FLAG << 6); - - UIP_ND6_RA_BUF->router_lifetime = uip_htons(UIP_ND6_ROUTER_LIFETIME); - //UIP_ND6_RA_BUF->reachable_time = uip_htonl(uip_ds6_if.reachable_time); - //UIP_ND6_RA_BUF->retrans_timer = uip_htonl(uip_ds6_if.retrans_timer); - UIP_ND6_RA_BUF->reachable_time = 0; - UIP_ND6_RA_BUF->retrans_timer = 0; - - uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_RA_LEN; - uip_nd6_opt_offset(buf) = UIP_ND6_RA_LEN; - net_buf_add(buf, UIP_ND6_RA_LEN); - - -#if !UIP_CONF_ROUTER - /* Prefix list */ - for(uip_prefix(buf) = uip_ds6_prefix_list; - uip_prefix(buf) < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; uip_prefix(buf)++) { - if((uip_prefix(buf)->isused) && (uip_prefix(buf)->advertise)) { - UIP_ND6_OPT_PREFIX_BUF(buf)->type = UIP_ND6_OPT_PREFIX_INFO; - UIP_ND6_OPT_PREFIX_BUF(buf)->len = UIP_ND6_OPT_PREFIX_INFO_LEN / 8; - UIP_ND6_OPT_PREFIX_BUF(buf)->preflen = uip_prefix(buf)->length; - UIP_ND6_OPT_PREFIX_BUF(buf)->flagsreserved1 = uip_prefix(buf)->l_a_reserved; - UIP_ND6_OPT_PREFIX_BUF(buf)->validlt = uip_htonl(uip_prefix(buf)->vlifetime); - UIP_ND6_OPT_PREFIX_BUF(buf)->preferredlt = uip_htonl(uip_prefix(buf)->plifetime); - UIP_ND6_OPT_PREFIX_BUF(buf)->reserved2 = 0; - uip_ipaddr_copy(&(UIP_ND6_OPT_PREFIX_BUF(buf)->prefix), &(uip_prefix(buf)->ipaddr)); - uip_nd6_opt_offset(buf) += UIP_ND6_OPT_PREFIX_INFO_LEN; - uip_len(buf) += UIP_ND6_OPT_PREFIX_INFO_LEN; - net_buf_add(buf, UIP_ND6_OPT_PREFIX_INFO_LEN); - } - } -#endif /* !UIP_CONF_ROUTER */ - - /* Source link-layer option */ - create_llao((uint8_t *)UIP_ND6_OPT_HDR_BUF(buf), UIP_ND6_OPT_SLLAO); - - uip_len(buf) += UIP_ND6_OPT_LLAO_LEN; - uip_nd6_opt_offset(buf) += UIP_ND6_OPT_LLAO_LEN; - net_buf_add(buf, UIP_ND6_OPT_LLAO_LEN); - - /* MTU */ - UIP_ND6_OPT_MTU_BUF(buf)->type = UIP_ND6_OPT_MTU; - UIP_ND6_OPT_MTU_BUF(buf)->len = UIP_ND6_OPT_MTU_LEN >> 3; - UIP_ND6_OPT_MTU_BUF(buf)->reserved = 0; - //UIP_ND6_OPT_MTU_BUF(buf)->mtu = uip_htonl(uip_ds6_if.link_mtu); - UIP_ND6_OPT_MTU_BUF(buf)->mtu = uip_htonl(1500); - - uip_len(buf) += UIP_ND6_OPT_MTU_LEN; - uip_nd6_opt_offset(buf) += UIP_ND6_OPT_MTU_LEN; - net_buf_add(buf, UIP_ND6_OPT_MTU_LEN); - -#if UIP_ND6_RA_RDNSS - if(uip_nameserver_count() > 0) { - uint8_t i = 0; - uip_ipaddr_t *ip = &UIP_ND6_OPT_RDNSS_BUF(buf)->ip; - uip_ipaddr_t *dns = NULL; - UIP_ND6_OPT_RDNSS_BUF(buf)->type = UIP_ND6_OPT_RDNSS; - UIP_ND6_OPT_RDNSS_BUF(buf)->reserved = 0; - UIP_ND6_OPT_RDNSS_BUF(buf)->lifetime = uip_nameserver_next_expiration(); - if(UIP_ND6_OPT_RDNSS_BUF(buf)->lifetime != UIP_NAMESERVER_INFINITE_LIFETIME) { - UIP_ND6_OPT_RDNSS_BUF(buf)->lifetime -= clock_seconds(); - } - while((dns = uip_nameserver_get(i)) != NULL) { - uip_ipaddr_copy(ip++, dns); - i++; - } - UIP_ND6_OPT_RDNSS_BUF(buf)->len = UIP_ND6_OPT_RDNSS_LEN + (i << 1); - PRINTF("%d nameservers reported\n", i); - uip_len(buf) += UIP_ND6_OPT_RDNSS_BUF(buf)->len << 3; - uip_nd6_opt_offset(buf) += UIP_ND6_OPT_RDNSS_BUF(buf)->len << 3; - net_buf_add(buf, UIP_ND6_OPT_RDNSS_BUF(buf)->len << 3); - } -#endif /* UIP_ND6_RA_RDNSS */ - - UIP_IP_BUF(buf)->len[0] = ((uip_len(buf) - UIP_IPH_LEN) >> 8); - UIP_IP_BUF(buf)->len[1] = ((uip_len(buf) - UIP_IPH_LEN) & 0xff); - - /*ICMP checksum */ - UIP_ICMP_BUF->icmpchksum = 0; - UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(buf); - - UIP_STAT(++uip_stat.nd6.sent); - PRINTF("Sending RA to "); - PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr); - PRINTF(" from "); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF("\n"); - - if (send_from_here) { - if (tcpip_ipv6_output(buf) == 0) { - ip_buf_unref(buf); - } - } - return; -} -#endif /* UIP_ND6_SEND_RA */ -#endif /* UIP_CONF_ROUTER */ - -#if !UIP_CONF_ROUTER -/*---------------------------------------------------------------------------*/ -void -uip_nd6_rs_output(struct net_buf *buf) -{ - bool send_from_here = false; - - if (!buf) { - buf = ip_buf_get_reserve_tx(UIP_IPICMPH_LEN); - if (!buf) { - PRINTF("%s(): Cannot send RS, no net buffers\n", __FUNCTION__); - return; - } - send_from_here = true; - } - UIP_IP_BUF(buf)->vtc = 0x60; - UIP_IP_BUF(buf)->tcflow = 0; - UIP_IP_BUF(buf)->flow = 0; - UIP_IP_BUF(buf)->proto = UIP_PROTO_ICMP6; - UIP_IP_BUF(buf)->ttl = UIP_ND6_HOP_LIMIT; - uip_create_linklocal_allrouters_mcast(&UIP_IP_BUF(buf)->destipaddr); - uip_ds6_select_src(&UIP_IP_BUF(buf)->srcipaddr, &UIP_IP_BUF(buf)->destipaddr); - UIP_ICMP_BUF(buf)->type = ICMP6_RS; - UIP_ICMP_BUF(buf)->icode = 0; - UIP_IP_BUF(buf)->len[0] = 0; /* length will not be more than 255 */ - - if(uip_is_addr_unspecified(&UIP_IP_BUF(buf)->srcipaddr)) { - UIP_IP_BUF(buf)->len[1] = UIP_ICMPH_LEN + UIP_ND6_RS_LEN; - uip_len(buf) = uip_l3_icmp_hdr_len(buf) + UIP_ND6_RS_LEN; - memset(&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf)], UIP_ND6_RS_LEN, 0); - net_buf_add(buf, UIP_ND6_RS_LEN); - } else { - uip_len(buf) = uip_l3_icmp_hdr_len(buf) + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN; - UIP_IP_BUF(buf)->len[1] = - UIP_ICMPH_LEN + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN; - net_buf_add(buf, UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN); - - create_llao(&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf) + UIP_ND6_RS_LEN], - UIP_ND6_OPT_SLLAO); - } - - UIP_ICMP_BUF(buf)->icmpchksum = 0; - UIP_ICMP_BUF(buf)->icmpchksum = ~uip_icmp6chksum(buf); - - UIP_STAT(++uip_stat.nd6.sent); - PRINTF("Sending RS to "); - PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr); - PRINTF(" from "); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF("\n"); - - if (send_from_here) { - if (tcpip_ipv6_output(buf) == 0) { - ip_buf_unref(buf); - } - } - return; -} -/*---------------------------------------------------------------------------*/ -/* - * Process a Router Advertisement - * - * - Possible actions when receiving a RA: add router to router list, - * recalculate reachable time, update link hop limit, update retrans timer. - * - If MTU option: update MTU. - * - If SLLAO option: update entry in neighbor cache - * - If prefix option: start autoconf, add prefix to prefix list - */ -void -ra_input(struct net_buf *buf) -{ - PRINTF("Received RA from "); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF(" to "); - PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr); - PRINTF("\n"); - UIP_STAT(++uip_stat.nd6.recv); - -#if UIP_CONF_IPV6_CHECKS - if((UIP_IP_BUF(buf)->ttl != UIP_ND6_HOP_LIMIT) || - (!uip_is_addr_link_local(&UIP_IP_BUF(buf)->srcipaddr)) || - (UIP_ICMP_BUF(buf)->icode != 0)) { - PRINTF("RA received is bad\n"); - goto discard; - } -#endif /*UIP_CONF_IPV6_CHECKS */ - - if(UIP_ND6_RA_BUF(buf)->cur_ttl != 0) { - uip_ds6_if.cur_hop_limit = UIP_ND6_RA_BUF(buf)->cur_ttl; - PRINTF("uip_ds6_if.cur_hop_limit %u\n", uip_ds6_if.cur_hop_limit); - } - - if(UIP_ND6_RA_BUF(buf)->reachable_time != 0) { - if(uip_ds6_if.base_reachable_time != - uip_ntohl(UIP_ND6_RA_BUF(buf)->reachable_time)) { - uip_ds6_if.base_reachable_time = uip_ntohl(UIP_ND6_RA_BUF(buf)->reachable_time); - uip_ds6_if.reachable_time = uip_ds6_compute_reachable_time(); - } - } - if(UIP_ND6_RA_BUF(buf)->retrans_timer != 0) { - uip_ds6_if.retrans_timer = uip_ntohl(UIP_ND6_RA_BUF(buf)->retrans_timer); - } - - /* Options processing */ - uip_nd6_opt_offset(buf) = UIP_ND6_RA_LEN; - while(uip_l3_icmp_hdr_len(buf) + uip_nd6_opt_offset(buf) < uip_len(buf)) { - if(UIP_ND6_OPT_HDR_BUF(buf)->len == 0) { - PRINTF("RA received is bad\n"); - goto discard; - } - switch (UIP_ND6_OPT_HDR_BUF(buf)->type) { - case UIP_ND6_OPT_SLLAO: - PRINTF("Processing SLLAO option in RA\n"); - uip_set_nd6_opt_llao(buf) = (uint8_t *) UIP_ND6_OPT_HDR_BUF(buf); - uip_set_nbr(buf) = uip_ds6_nbr_lookup(&UIP_IP_BUF(buf)->srcipaddr); - if(uip_nbr(buf) == NULL) { - uip_set_nbr(buf) = uip_ds6_nbr_add(&UIP_IP_BUF(buf)->srcipaddr, - (uip_lladdr_t *)&uip_nd6_opt_llao(buf)[UIP_ND6_OPT_DATA_OFFSET], - 1, NBR_STALE); - } else { - uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(uip_nbr(buf)); - if(uip_nbr(buf)->state == NBR_INCOMPLETE) { - uip_nbr(buf)->state = NBR_STALE; - } - if(memcmp(&uip_nd6_opt_llao(buf)[UIP_ND6_OPT_DATA_OFFSET], - lladdr, UIP_LLADDR_LEN) != 0) { - memcpy(lladdr, &uip_nd6_opt_llao(buf)[UIP_ND6_OPT_DATA_OFFSET], - UIP_LLADDR_LEN); - uip_nbr(buf)->state = NBR_STALE; - } - uip_nbr(buf)->isrouter = 1; - } - break; - case UIP_ND6_OPT_MTU: - PRINTF("Processing MTU option in RA\n"); - uip_ds6_if.link_mtu = - uip_ntohl(((uip_nd6_opt_mtu *) UIP_ND6_OPT_HDR_BUF(buf))->mtu); - break; - case UIP_ND6_OPT_PREFIX_INFO: - PRINTF("Processing PREFIX option in RA\n"); - uip_set_nd6_opt_prefix_info(buf) = (uip_nd6_opt_prefix_info *) UIP_ND6_OPT_HDR_BUF(buf); - if((uip_ntohl(uip_nd6_opt_prefix_info(buf)->validlt) >= - uip_ntohl(uip_nd6_opt_prefix_info(buf)->preferredlt)) - && (!uip_is_addr_link_local(&uip_nd6_opt_prefix_info(buf)->prefix))) { - /* on-link flag related processing */ - if(uip_nd6_opt_prefix_info(buf)->flagsreserved1 & UIP_ND6_RA_FLAG_ONLINK) { - uip_set_prefix(buf) = - uip_ds6_prefix_lookup(&uip_nd6_opt_prefix_info(buf)->prefix, - uip_nd6_opt_prefix_info(buf)->preflen); - if(uip_prefix(buf) == NULL) { - if(uip_nd6_opt_prefix_info(buf)->validlt != 0) { - if(uip_nd6_opt_prefix_info(buf)->validlt != UIP_ND6_INFINITE_LIFETIME) { - uip_set_prefix(buf) = uip_ds6_prefix_add(&uip_nd6_opt_prefix_info(buf)->prefix, - uip_nd6_opt_prefix_info(buf)->preflen, - uip_ntohl(uip_nd6_opt_prefix_info(buf)-> - validlt)); - } else { - uip_set_prefix(buf) = uip_ds6_prefix_add(&uip_nd6_opt_prefix_info(buf)->prefix, - uip_nd6_opt_prefix_info(buf)->preflen, 0); - } - } - } else { - switch (uip_nd6_opt_prefix_info(buf)->validlt) { - case 0: - uip_ds6_prefix_rm(uip_prefix(buf)); - break; - case UIP_ND6_INFINITE_LIFETIME: - uip_prefix(buf)->isinfinite = 1; - break; - default: - PRINTF("Updating timer of prefix "); - PRINT6ADDR(&uip_prefix(buf)->ipaddr); - PRINTF(" new value %lu\n", uip_ntohl(uip_nd6_opt_prefix_info(buf)->validlt)); - stimer_set(&uip_prefix(buf)->vlifetime, - uip_ntohl(uip_nd6_opt_prefix_info(buf)->validlt)); - uip_prefix(buf)->isinfinite = 0; - break; - } - } - } - /* End of on-link flag related processing */ - /* autonomous flag related processing */ - if((uip_nd6_opt_prefix_info(buf)->flagsreserved1 & UIP_ND6_RA_FLAG_AUTONOMOUS) - && (uip_nd6_opt_prefix_info(buf)->validlt != 0) - && (uip_nd6_opt_prefix_info(buf)->preflen == UIP_DEFAULT_PREFIX_LEN)) { - - uip_ipaddr_copy(&uip_nd6_ipaddr(buf), &uip_nd6_opt_prefix_info(buf)->prefix); - uip_ds6_set_addr_iid(&uip_nd6_ipaddr(buf), &uip_lladdr); - uip_set_addr(buf) = uip_ds6_addr_lookup(&uip_nd6_ipaddr(buf)); - if((uip_addr(buf) != NULL) && (uip_addr(buf)->type == ADDR_AUTOCONF)) { - if(uip_nd6_opt_prefix_info(buf)->validlt != UIP_ND6_INFINITE_LIFETIME) { - /* The processing below is defined in RFC4862 section 5.5.3 e */ - if((uip_ntohl(uip_nd6_opt_prefix_info(buf)->validlt) > 2 * 60 * 60) || - (uip_ntohl(uip_nd6_opt_prefix_info(buf)->validlt) > - stimer_remaining(&uip_addr(buf)->vlifetime))) { - PRINTF("Updating timer of address "); - PRINT6ADDR(&uip_addr(buf)->ipaddr); - PRINTF(" new value %lu\n", - uip_ntohl(uip_nd6_opt_prefix_info(buf)->validlt)); - stimer_set(&uip_addr(buf)->vlifetime, - uip_ntohl(uip_nd6_opt_prefix_info(buf)->validlt)); - } else { - stimer_set(&uip_addr(buf)->vlifetime, 2 * 60 * 60); - PRINTF("Updating timer of address "); - PRINT6ADDR(&uip_addr(buf)->ipaddr); - PRINTF(" new value %lu\n", (unsigned long)(2 * 60 * 60)); - } - uip_addr(buf)->isinfinite = 0; - } else { - uip_addr(buf)->isinfinite = 1; - } - } else { - if(uip_ntohl(uip_nd6_opt_prefix_info(buf)->validlt) == - UIP_ND6_INFINITE_LIFETIME) { - uip_ds6_addr_add(&uip_nd6_ipaddr(buf), 0, ADDR_AUTOCONF); - } else { - uip_ds6_addr_add(&uip_nd6_ipaddr(buf), uip_ntohl(uip_nd6_opt_prefix_info(buf)->validlt), - ADDR_AUTOCONF); - } - } - } - /* End of autonomous flag related processing */ - } - break; -#if UIP_ND6_RA_RDNSS - case UIP_ND6_OPT_RDNSS: - if(UIP_ND6_RA_BUF(buf)->flags_reserved & (UIP_ND6_O_FLAG << 6)) { - PRINTF("Processing RDNSS option\n"); - uint8_t naddr = (UIP_ND6_OPT_RDNSS_BUF->len - 1) / 2; - uip_ipaddr_t *ip = (uip_ipaddr_t *)(&UIP_ND6_OPT_RDNSS_BUF->ip); - PRINTF("got %d nameservers\n", naddr); - while(naddr-- > 0) { - PRINTF(" nameserver: "); - PRINT6ADDR(ip); - PRINTF(" lifetime: %lx\n", uip_ntohl(UIP_ND6_OPT_RDNSS_BUF->lifetime)); - uip_nameserver_update(ip, uip_ntohl(UIP_ND6_OPT_RDNSS_BUF->lifetime)); - ip++; - } - } - break; -#endif /* UIP_ND6_RA_RDNSS */ - default: - PRINTF("ND option (0x%x) not supported in RA\n", - UIP_ND6_OPT_HDR_BUF(buf)->type); - break; - } - uip_nd6_opt_offset(buf) += (UIP_ND6_OPT_HDR_BUF(buf)->len << 3); - } - - uip_set_defrt(buf) = uip_ds6_defrt_lookup(&UIP_IP_BUF(buf)->srcipaddr); - if(UIP_ND6_RA_BUF(buf)->router_lifetime != 0) { - if(uip_nbr(buf) != NULL) { - uip_nbr(buf)->isrouter = 1; - } - if(uip_defrt(buf) == NULL) { - uip_ds6_defrt_add(&UIP_IP_BUF(buf)->srcipaddr, - (unsigned - long)(uip_ntohs(UIP_ND6_RA_BUF(buf)->router_lifetime))); - } else { - stimer_set(&(uip_defrt(buf)->lifetime), - (unsigned long)(uip_ntohs(UIP_ND6_RA_BUF(buf)->router_lifetime))); - } - } else { - if(uip_defrt(buf) != NULL) { - uip_ds6_defrt_rm(uip_defrt(buf)); - } - } - -#if UIP_CONF_IPV6_QUEUE_PKT - /* If the nbr just became reachable (e.g. it was in NBR_INCOMPLETE state - * and we got a SLLAO), check if we had buffered a pkt for it */ - /* if((nbr != NULL) && (nbr->queue_buf_len != 0)) { - uip_len = nbr->queue_buf_len; - memcpy(UIP_IP_BUF, nbr->queue_buf, uip_len); - nbr->queue_buf_len = 0; - return; - }*/ - if(uip_nbr(buf) != NULL && uip_packetqueue_buflen(&uip_nbr(buf)->packethandle) != 0) { - uip_len(buf) = buf->len = uip_packetqueue_buflen(&uip_nbr(buf)->packethandle); - memcpy(UIP_IP_BUF(buf), uip_packetqueue_buf(&uip_nbr(buf)->packethandle), uip_len(buf)); - uip_packetqueue_free(&uip_nbr(buf)->packethandle); - return; - } - -#endif /*UIP_CONF_IPV6_QUEUE_PKT */ - -discard: - uip_len(buf) = 0; - uip_ext_len(buf) = 0; - return; -} -#endif /* !UIP_CONF_ROUTER */ -/*------------------------------------------------------------------*/ -/* ICMPv6 input handlers */ -#if UIP_ND6_SEND_NA -UIP_ICMP6_HANDLER(ns_input_handler, ICMP6_NS, UIP_ICMP6_HANDLER_CODE_ANY, - ns_input); -UIP_ICMP6_HANDLER(na_input_handler, ICMP6_NA, UIP_ICMP6_HANDLER_CODE_ANY, - na_input); -#endif - -#if UIP_CONF_ROUTER && UIP_ND6_SEND_RA -UIP_ICMP6_HANDLER(rs_input_handler, ICMP6_RS, UIP_ICMP6_HANDLER_CODE_ANY, - rs_input); -#endif - -#if !UIP_CONF_ROUTER -UIP_ICMP6_HANDLER(ra_input_handler, ICMP6_RA, UIP_ICMP6_HANDLER_CODE_ANY, - ra_input); -#endif -/*---------------------------------------------------------------------------*/ -void -uip_nd6_init() -{ - -#if UIP_ND6_SEND_NA - /* Only handle NSs if we are prepared to send out NAs */ - uip_icmp6_register_input_handler(&ns_input_handler); - - /* - * Only handle NAs if we are prepared to send out NAs. - * This is perhaps logically incorrect, but this condition was present in - * uip_process and we keep it until proven wrong - */ - uip_icmp6_register_input_handler(&na_input_handler); -#endif - - -#if UIP_CONF_ROUTER && UIP_ND6_SEND_RA - /* Only accept RS if we are a router and happy to send out RAs */ - uip_icmp6_register_input_handler(&rs_input_handler); -#endif - -#if !UIP_CONF_ROUTER - /* Only process RAs if we are not a router */ - uip_icmp6_register_input_handler(&ra_input_handler); -#endif -} -/*---------------------------------------------------------------------------*/ - /** @} */ diff --git a/net/ip/contiki/ipv6/uip-nd6.h b/net/ip/contiki/ipv6/uip-nd6.h deleted file mode 100644 index d933717298ce2b6f2665cd789c4cc5ef2b5ed432..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/uip-nd6.h +++ /dev/null @@ -1,577 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * Header file for IPv6 Neighbor discovery (RFC 4861) - * \author Julien Abeille - * \author Mathilde Durvy - */ - -#ifndef UIP_ND6_H_ -#define UIP_ND6_H_ - -#include - -#include "contiki/ip/uip.h" -#include "sys/stimer.h" -/** - * \name General - * @{ - */ -/** \brief HOP LIMIT to be used when sending ND messages (255) */ -#define UIP_ND6_HOP_LIMIT 255 -/** \brief INFINITE lifetime */ -#define UIP_ND6_INFINITE_LIFETIME 0xFFFFFFFF -/** @} */ - -/** \name RFC 4861 Host constant */ -/** @{ */ -#define UIP_ND6_MAX_RTR_SOLICITATION_DELAY 1 -#define UIP_ND6_RTR_SOLICITATION_INTERVAL 4 -#define UIP_ND6_MAX_RTR_SOLICITATIONS 3 -/** @} */ - -/** \name RFC 4861 Router constants */ -/** @{ */ -#ifndef UIP_CONF_ND6_SEND_RA -#define UIP_ND6_SEND_RA 1 /* enable/disable RA sending */ -#else -#define UIP_ND6_SEND_RA UIP_CONF_ND6_SEND_RA -#endif -#ifndef UIP_CONF_ND6_SEND_NA -#define UIP_ND6_SEND_NA 1 /* enable/disable NA sending */ -#else -#define UIP_ND6_SEND_NA UIP_CONF_ND6_SEND_NA -#endif -#ifndef UIP_CONF_ND6_MAX_RA_INTERVAL -#define UIP_ND6_MAX_RA_INTERVAL 600 -#else -#define UIP_ND6_MAX_RA_INTERVAL UIP_CONF_ND6_MAX_RA_INTERVAL -#endif -#ifndef UIP_CONF_ND6_MIN_RA_INTERVAL -#define UIP_ND6_MIN_RA_INTERVAL (UIP_ND6_MAX_RA_INTERVAL / 3) -#else -#define UIP_ND6_MIN_RA_INTERVAL UIP_CONF_ND6_MIN_RA_INTERVAL -#endif -#define UIP_ND6_M_FLAG 0 -#define UIP_ND6_O_FLAG (UIP_ND6_RA_RDNSS || UIP_ND6_RA_DNSSL) -#define UIP_ND6_ROUTER_LIFETIME 3 * UIP_ND6_MAX_RA_INTERVAL - -#define UIP_ND6_MAX_INITIAL_RA_INTERVAL 16 /*seconds*/ -#define UIP_ND6_MAX_INITIAL_RAS 3 /*transmissions*/ -#ifndef UIP_CONF_ND6_MIN_DELAY_BETWEEN_RAS -#define UIP_ND6_MIN_DELAY_BETWEEN_RAS 3 /*seconds*/ -#else -#define UIP_ND6_MIN_DELAY_BETWEEN_RAS UIP_CONF_ND6_MIN_DELAY_BETWEEN_RAS -#endif -//#define UIP_ND6_MAX_RA_DELAY_TIME 0.5 /*seconds*/ -#define UIP_ND6_MAX_RA_DELAY_TIME_MS 500 /*milli seconds*/ -/** @} */ - -#ifndef UIP_CONF_ND6_DEF_MAXDADNS -/** \brief Do not try DAD when using EUI-64 as allowed by draft-ietf-6lowpan-nd-15 section 8.2 */ -#if UIP_CONF_LL_802154 -#define UIP_ND6_DEF_MAXDADNS 0 -#else /* UIP_CONF_LL_802154 */ -#define UIP_ND6_DEF_MAXDADNS UIP_ND6_SEND_NA -#endif /* UIP_CONF_LL_802154 */ -#else /* UIP_CONF_ND6_DEF_MAXDADNS */ -#define UIP_ND6_DEF_MAXDADNS UIP_CONF_ND6_DEF_MAXDADNS -#endif /* UIP_CONF_ND6_DEF_MAXDADNS */ - -/** \name RFC 4861 Node constant */ -#define UIP_ND6_MAX_MULTICAST_SOLICIT 3 - -#ifdef UIP_CONF_ND6_MAX_UNICAST_SOLICIT -#define UIP_ND6_MAX_UNICAST_SOLICIT UIP_CONF_ND6_MAX_UNICAST_SOLICIT -#else /* UIP_CONF_ND6_MAX_UNICAST_SOLICIT */ -#define UIP_ND6_MAX_UNICAST_SOLICIT 3 -#endif /* UIP_CONF_ND6_MAX_UNICAST_SOLICIT */ - -#ifdef UIP_CONF_ND6_REACHABLE_TIME -#define UIP_ND6_REACHABLE_TIME UIP_CONF_ND6_REACHABLE_TIME -#else -#define UIP_ND6_REACHABLE_TIME 30000 -#endif - -#ifdef UIP_CONF_ND6_RETRANS_TIMER -#define UIP_ND6_RETRANS_TIMER UIP_CONF_ND6_RETRANS_TIMER -#else -#define UIP_ND6_RETRANS_TIMER 1000 -#endif - -#define UIP_ND6_DELAY_FIRST_PROBE_TIME 5 -#define UIP_ND6_MIN_RANDOM_FACTOR(x) (x / 2) -#define UIP_ND6_MAX_RANDOM_FACTOR(x) ((x) + (x) / 2) -/** @} */ - - -/** \name RFC 6106 RA DNS Options Constants */ -/** @{ */ -#ifndef UIP_CONF_ND6_RA_RDNSS -#define UIP_ND6_RA_RDNSS 0 -#else -#define UIP_ND6_RA_RDNSS UIP_CONF_ND6_RA_RDNSS -#endif - -#ifndef UIP_CONF_ND6_RA_DNSSL -#define UIP_ND6_RA_DNSSL 0 -#else -#error Not implemented -#define UIP_ND6_RA_DNSSL UIP_CONF_ND6_RA_DNSSL -#endif -/** @} */ - - -/** \name ND6 option types */ -/** @{ */ -#define UIP_ND6_OPT_SLLAO 1 -#define UIP_ND6_OPT_TLLAO 2 -#define UIP_ND6_OPT_PREFIX_INFO 3 -#define UIP_ND6_OPT_REDIRECTED_HDR 4 -#define UIP_ND6_OPT_MTU 5 -#define UIP_ND6_OPT_RDNSS 25 -#define UIP_ND6_OPT_DNSSL 31 -/** @} */ - -/** \name ND6 option types */ -/** @{ */ -#define UIP_ND6_OPT_TYPE_OFFSET 0 -#define UIP_ND6_OPT_LEN_OFFSET 1 -#define UIP_ND6_OPT_DATA_OFFSET 2 - -/** \name ND6 message length (excluding options) */ -/** @{ */ -#define UIP_ND6_NA_LEN 20 -#define UIP_ND6_NS_LEN 20 -#define UIP_ND6_RA_LEN 12 -#define UIP_ND6_RS_LEN 4 -/** @} */ - - -/** \name ND6 option length in bytes */ -/** @{ */ -#define UIP_ND6_OPT_HDR_LEN 2 -#define UIP_ND6_OPT_PREFIX_INFO_LEN 32 -#define UIP_ND6_OPT_MTU_LEN 8 -#define UIP_ND6_OPT_RDNSS_LEN 1 -#define UIP_ND6_OPT_DNSSL_LEN 1 - - -/* Length of TLLAO and SLLAO options, it is L2 dependant */ -#if UIP_CONF_LL_802154 -/* If the interface is 802.15.4. For now we use only long addresses */ -#define UIP_ND6_OPT_SHORT_LLAO_LEN 8 -#define UIP_ND6_OPT_LONG_LLAO_LEN 16 -/** \brief length of a ND6 LLAO option for 802.15.4 */ -#define UIP_ND6_OPT_LLAO_LEN UIP_ND6_OPT_LONG_LLAO_LEN -#else /*UIP_CONF_LL_802154*/ -#if UIP_CONF_LL_80211 -/* If the interface is 802.11 */ -/** \brief length of a ND6 LLAO option for 802.11 */ -#define UIP_ND6_OPT_LLAO_LEN 8 -#else /*UIP_CONF_LL_80211*/ -/** \brief length of a ND6 LLAO option for default L2 type (e.g. Ethernet) */ -#define UIP_ND6_OPT_LLAO_LEN 8 -#endif /*UIP_CONF_LL_80211*/ -#endif /*UIP_CONF_LL_802154*/ -/** @} */ - - -/** \name Neighbor Advertisement flags masks */ -/** @{ */ -#define UIP_ND6_NA_FLAG_ROUTER 0x80 -#define UIP_ND6_NA_FLAG_SOLICITED 0x40 -#define UIP_ND6_NA_FLAG_OVERRIDE 0x20 -#define UIP_ND6_RA_FLAG_ONLINK 0x80 -#define UIP_ND6_RA_FLAG_AUTONOMOUS 0x40 -/** @} */ - -/** - * \name ND message structures - * @{ - */ - -/** - * \brief A neighbor solicitation constant part - * - * Possible option is: SLLAO - */ -typedef struct uip_nd6_ns { - uint32_t reserved; - uip_ipaddr_t tgtipaddr; -} PACK_ALIAS_STRUCT uip_nd6_ns; - -/** - * \brief A neighbor advertisement constant part. - * - * Possible option is: TLLAO - */ -typedef struct uip_nd6_na { - uint8_t flagsreserved; - uint8_t reserved[3]; - uip_ipaddr_t tgtipaddr; -} PACK_ALIAS_STRUCT uip_nd6_na; - -/** - * \brief A router solicitation constant part - * - * Possible option is: SLLAO - */ -typedef struct uip_nd6_rs { - uint32_t reserved; -} uip_nd6_rs; - -/** - * \brief A router advertisement constant part - * - * Possible options are: SLLAO, MTU, Prefix Information - */ -typedef struct uip_nd6_ra { - uint8_t cur_ttl; - uint8_t flags_reserved; - uint16_t router_lifetime; - uint32_t reachable_time; - uint32_t retrans_timer; -} PACK_ALIAS_STRUCT uip_nd6_ra; - -/** - * \brief A redirect message constant part - * - * Possible options are: TLLAO, redirected header - */ -typedef struct uip_nd6_redirect { - uint32_t reserved; - uip_ipaddr_t tgtipaddress; - uip_ipaddr_t destipaddress; -} uip_nd6_redirect; -/** @} */ - -/** - * \name ND Option structures - * @{ - */ - -/** \brief ND option header */ -typedef struct uip_nd6_opt_hdr { - uint8_t type; - uint8_t len; -} PACK_ALIAS_STRUCT uip_nd6_opt_hdr; - -/** \brief ND option prefix information */ -typedef struct uip_nd6_opt_prefix_info { - uint8_t type; - uint8_t len; - uint8_t preflen; - uint8_t flagsreserved1; - uint32_t validlt; - uint32_t preferredlt; - uint32_t reserved2; - uip_ipaddr_t prefix; -} uip_nd6_opt_prefix_info ; - -/** \brief ND option MTU */ -typedef struct uip_nd6_opt_mtu { - uint8_t type; - uint8_t len; - uint16_t reserved; - uint32_t mtu; -} PACK_ALIAS_STRUCT uip_nd6_opt_mtu; - -/** \brief ND option RDNSS */ -typedef struct uip_nd6_opt_dns { - uint8_t type; - uint8_t len; - uint16_t reserved; - uint32_t lifetime; - uip_ipaddr_t ip; -} uip_nd6_opt_dns; - -/** \struct Redirected header option */ -typedef struct uip_nd6_opt_redirected_hdr { - uint8_t type; - uint8_t len; - uint8_t reserved[6]; -} uip_nd6_opt_redirected_hdr; -/** @} */ - -/** - * \name ND Messages Processing and Generation - * @{ - */ - /** - * \brief Process a neighbor solicitation - * - * The NS can be received in 3 cases (procedures): - * - sender is performing DAD (ip src = unspecified, no SLLAO option) - * - sender is performing NUD (ip dst = unicast) - * - sender is performing address resolution (ip dest = solicited node mcast - * address) - * - * We do: - * - if the tgt belongs to me, reply, otherwise ignore - * - if i was performing DAD for the same address, two cases: - * -- I already sent a NS, hence I win - * -- I did not send a NS yet, hence I lose - * - * If we need to send a NA in response (i.e. the NS was done for NUD, or - * address resolution, or DAD and there is a conflict), we do it in this - * function: set src, dst, tgt address in the three cases, then for all cases - * set the rest, including SLLAO - * - */ -void -uip_nd6_ns_input(void); - -/** - * \brief Send a neighbor solicitation, send a Neighbor Advertisement - * \param src pointer to the src of the NS if known - * \param dest pointer to ip address to send the NS, for DAD or ADDR Resol, - * MUST be NULL, for NUD, must be correct unicast dest - * \param tgt pointer to ip address to fill the target address field, must - * not be NULL - * - * - RFC 4861, 7.2.2 : - * "If the source address of the packet prompting the solicitation is the - * same as one of the addresses assigned to the outgoing interface, that - * address SHOULD be placed in the IP Source Address of the outgoing - * solicitation. Otherwise, any one of the addresses assigned to the - * interface should be used." - * This is why we have a src ip address as argument. If NULL, we will do - * src address selection, otherwise we use the argument. - * - * - we check if it is a NS for Address resolution or NUD, if yes we include - * a SLLAO option, otherwise no. - */ -void -uip_nd6_ns_output(struct net_buf *buf, uip_ipaddr_t *src, uip_ipaddr_t *dest, uip_ipaddr_t *tgt); - -#if UIP_CONF_ROUTER -#if UIP_ND6_SEND_RA -/** - * \brief send a Router Advertisement - * - * Only for router, for periodic as well as sollicited RA - */ -void uip_nd6_ra_output(uip_ipaddr_t *dest); -#endif /* UIP_ND6_SEND_RA */ -#endif /*UIP_CONF_ROUTER*/ - -/** - * \brief Send a Router Solicitation - * - * src is chosen through the uip_netif_select_src function. If src is - * unspecified (i.e. we do not have a preferred address yet), then we do not - * put a SLLAO option (MUST NOT in RFC 4861). Otherwise we do. - * - * RS message format, - * possible option is SLLAO, MUST NOT be included if source = unspecified - * SHOULD be included otherwise - */ -void uip_nd6_rs_output(struct net_buf *buf); - -/** - * \brief Initialise the uIP ND core - */ -void uip_nd6_init(void); -/** @} */ - - -void -uip_appserver_addr_get(uip_ipaddr_t *ipaddr); -/*--------------------------------------*/ -/** ANNEX - message formats ********/ -/*--------------------------------------*/ - -/* - * RS format. possible option is SLLAO - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Type | Code | Checksum | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Reserved | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Options ... - * +-+-+-+-+-+-+-+-+-+-+-+- - * - * - * RA format. possible options: prefix information, MTU, SLLAO - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Type | Code | Checksum | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Cur Hop Limit |M|O| Reserved | Router Lifetime | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Reachable Time | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Retrans Timer | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Options ... - * +-+-+-+-+-+-+-+-+-+-+-+- - * - * - * NS format: options should be SLLAO - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Type | Code | Checksum | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Reserved | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | | - * + + - * | | - * + Target Address + - * | | - * + + - * | | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Options ... - * +-+-+-+-+-+-+-+-+-+-+-+- - * - * - * NA message format. possible options is TLLAO - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Type | Code | Checksum | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * |R|S|O| Reserved | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | | - * + + - * | | - * + Target Address + - * | | - * + + - * | | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Options ... - * +-+-+-+-+-+-+-+-+-+-+-+- - * - * - * Redirect message format. Possible options are TLLAO and Redirected header - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Type | Code | Checksum | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Reserved | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | | - * + + - * | | - * + Target Address + - * | | - * + + - * | | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | | - * + + - * | | - * + Destination Address + - * | | - * + + - * | | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Options ... - * +-+-+-+-+-+-+-+-+-+-+-+- - * - * - * SLLAO/TLLAO option: - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Type | Length | Link-Layer Address ... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * - * Prefix information option - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Type | Length | Prefix Length |L|A| Reserved1 | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Valid Lifetime | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Preferred Lifetime | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Reserved2 | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | | - * + + - * | | - * + Prefix + - * | | - * + + - * | | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * - * MTU option - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Type | Length | Reserved | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | MTU | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * - * Redirected header option - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Type | Length | Reserved | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Reserved | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | | - * ~ IP header + data ~ - * | | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - */ -#endif /* UIP_ND6_H_ */ - -/** @} */ diff --git a/net/ip/contiki/ipv6/uip6.c b/net/ip/contiki/ipv6/uip6.c deleted file mode 100644 index ee60d868a0cbcc563c281c5550dbd7db95f7984d..0000000000000000000000000000000000000000 --- a/net/ip/contiki/ipv6/uip6.c +++ /dev/null @@ -1,2647 +0,0 @@ -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack. - * - * - */ - -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * The uIP TCP/IPv6 stack code. - * - * \author Adam Dunkels - * \author Julien Abeille (IPv6 related code) - * \author Mathilde Durvy (IPv6 related code) - */ - -/* - * uIP is a small implementation of the IP, UDP and TCP protocols (as - * well as some basic ICMP stuff). The implementation couples the IP, - * UDP, TCP and the application layers very tightly. To keep the size - * of the compiled code down, this code frequently uses the goto - * statement. While it would be possible to break the uip_process() - * function into many smaller functions, this would increase the code - * size because of the overhead of parameter passing and the fact that - * the optimizer would not be as efficient. - * - * The principle is that we have a small buffer, called the uip_buf, - * in which the device driver puts an incoming packet. The TCP/IP - * stack parses the headers in the packet, and calls the - * application. If the remote host has sent data to the application, - * this data is present in the uip_buf and the application read the - * data from there. It is up to the application to put this data into - * a byte stream if needed. The application will not be fed with data - * that is out of sequence. - * - * If the application wishes to send data to the peer, it should put - * its data into the uip_buf. The uip_appdata pointer points to the - * first available byte. The TCP/IP stack will calculate the - * checksums, and fill in the necessary header fields and finally send - * the packet back to the peer. - */ - -#include -#include -#include - -#include "contiki/ip/uip.h" -#include "contiki/ip/uipopt.h" -#include "contiki/ipv6/uip-icmp6.h" -#include "contiki/ipv6/uip-nd6.h" -#include "contiki/ipv6/uip-ds6.h" -#include "contiki/ipv6/multicast/uip-mcast6.h" - -#include - -/* Need to set the connection status in context when TCP connection is - * established. - */ -extern void net_context_set_connection_status(struct net_context *context, - int status); -void *net_context_get_internal_connection(struct net_context *context); -void net_context_set_internal_connection(struct net_context *context, - void *conn); -struct net_context *net_context_find_internal_connection(void *conn); -void net_context_tcp_set_pending(struct net_context *context, - struct net_buf *buf); - -/*---------------------------------------------------------------------------*/ -/* For Debug, logging, statistics */ -/*---------------------------------------------------------------------------*/ - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_IPV6 -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#if UIP_CONF_IPV6_RPL -#include "rpl/rpl.h" -#endif /* UIP_CONF_IPV6_RPL */ - -#if UIP_LOGGING == 1 -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif /* UIP_LOGGING == 1 */ - -#if UIP_STATISTICS == 1 -struct uip_stats uip_stat; -#endif /* UIP_STATISTICS == 1 */ - - -/*---------------------------------------------------------------------------*/ -/** - * \name Layer 2 variables - * @{ - */ -/*---------------------------------------------------------------------------*/ -/** Host L2 address */ -#if UIP_CONF_LL_802154 -uip_lladdr_t uip_lladdr; -#else /*UIP_CONF_LL_802154*/ -uip_lladdr_t uip_lladdr = {{0x00,0x06,0x98,0x00,0x02,0x32}}; -#endif /*UIP_CONF_LL_802154*/ -/** @} */ - -/*---------------------------------------------------------------------------*/ -/** - * \name Layer 3 variables - * @{ - */ -/*---------------------------------------------------------------------------*/ -/** - * \brief Type of the next header in IPv6 header or extension headers - * - * Can be the next header field in the IPv6 header or in an extension header. - * When doing fragment reassembly, we must change the value of the next header - * field in the header before the fragmentation header, hence we need a pointer - * to this field. - */ -#if 0 -/* Global variables cannot be used, these are moved to net_buf */ -uint8_t *uip_next_hdr; -/** \brief bitmap we use to record which IPv6 headers we have already seen */ -uint8_t uip_ext_bitmap = 0; -/** - * \brief length of the extension headers read. updated each time we process - * a header - */ -uint8_t uip_ext_len = 0; -/** \brief length of the header options read */ -uint8_t uip_ext_opt_offset = 0; -#endif -/** @} */ - -/*---------------------------------------------------------------------------*/ -/* Buffers */ -/*---------------------------------------------------------------------------*/ -/** - * \name Buffer defines - * @{ - */ -#define FBUF(buf) ((struct uip_tcpip_hdr *)&uip_reassbuf(buf)[0]) -#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) -#define UIP_ICMP_BUF(buf) ((struct uip_icmp_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)]) -#define UIP_UDP_BUF(buf) ((struct uip_udp_hdr *)&uip_buf(buf)[UIP_LLH_LEN + UIP_IPH_LEN]) -#define UIP_TCP_BUF(buf) ((struct uip_tcp_hdr *)&uip_buf(buf)[UIP_LLH_LEN + UIP_IPH_LEN]) -#define UIP_EXT_BUF(buf) ((struct uip_ext_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)]) -#define UIP_ROUTING_BUF(buf) ((struct uip_routing_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)]) -#define UIP_FRAG_BUF(buf) ((struct uip_frag_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)]) -#define UIP_HBHO_BUF(buf) ((struct uip_hbho_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)]) -#define UIP_DESTO_BUF(buf) ((struct uip_desto_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)]) -#define UIP_EXT_HDR_OPT_BUF(buf) ((struct uip_ext_hdr_opt *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf) + uip_ext_opt_offset(buf)]) -#define UIP_EXT_HDR_OPT_PADN_BUF(buf) ((struct uip_ext_hdr_opt_padn *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf) + uip_ext_opt_offset(buf)]) -#if UIP_CONF_IPV6_RPL -#define UIP_EXT_HDR_OPT_RPL_BUF(buf) ((struct uip_ext_hdr_opt_rpl *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf) + uip_ext_opt_offset(buf)]) -#endif /* UIP_CONF_IPV6_RPL */ -#define UIP_ICMP6_ERROR_BUF(buf) ((struct uip_icmp6_error *)&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf)]) -/** @} */ -/** - * \name Buffer variables - * @{ - */ -/** Packet buffer for incoming and outgoing packets */ -#if 0 -/* Global variables cannot be used, these are now in net_buf */ -#ifndef UIP_CONF_EXTERNAL_BUFFER -uip_buf_t uip_aligned_buf; -#endif /* UIP_CONF_EXTERNAL_BUFFER */ - -/* The uip_appdata pointer points to application data. */ -void *uip_appdata; -/* The uip_appdata pointer points to the application data which is to be sent*/ -void *uip_sappdata; -#endif - -#if UIP_URGDATA > 0 -/* The uip_urgdata pointer points to urgent data (out-of-band data), if present */ -void *uip_urgdata; -uint16_t uip_urglen, uip_surglen; -#endif /* UIP_URGDATA > 0 */ - -/* The uip_len is either 8 or 16 bits, depending on the maximum packet size.*/ -/* uint16_t uip_len, uip_slen; No longer used as len is part of net_buf */ -/** @} */ - -/*---------------------------------------------------------------------------*/ -/** - * \name General variables - * @{ - */ -/*---------------------------------------------------------------------------*/ - -#if 0 -/* Global variables cannot be used, these are now in net_buf */ - -/* The uip_flags variable is used for communication between the TCP/IP stack -and the application program. */ -uint8_t uip_flags; - -/* uip_conn always points to the current connection (set to NULL for UDP). */ -struct uip_conn *uip_conn; -#endif - -#if UIP_ACTIVE_OPEN || UIP_UDP -/* Keeps track of the last port used for a new connection. */ -static uint16_t lastport; -#endif /* UIP_ACTIVE_OPEN || UIP_UDP */ -/** @} */ - -/*---------------------------------------------------------------------------*/ -/* TCP */ -/*---------------------------------------------------------------------------*/ -/** - * \name TCP defines - *@{ - */ -/* Structures and definitions. */ -#define TCP_FIN 0x01 -#define TCP_SYN 0x02 -#define TCP_RST 0x04 -#define TCP_PSH 0x08 -#define TCP_ACK 0x10 -#define TCP_URG 0x20 -#define TCP_CTL 0x3f - -#define TCP_OPT_END 0 /* End of TCP options list */ -#define TCP_OPT_NOOP 1 /* "No-operation" TCP option */ -#define TCP_OPT_MSS 2 /* Maximum segment size TCP option */ - -#define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */ -/** @} */ -/** - * \name TCP variables - *@{ - */ -#if UIP_TCP -/* The uip_conns array holds all TCP connections. */ -struct uip_conn uip_conns[UIP_CONNS]; - -/* The uip_listenports list all currently listning ports. */ -uint16_t uip_listenports[UIP_LISTENPORTS]; - -/* The iss variable is used for the TCP initial sequence number. */ -static uint8_t iss[4]; - -/* Temporary variables. */ -uint8_t uip_acc32[4]; -static uint8_t opt; -static uint16_t tmp16; -#endif /* UIP_TCP */ -/** @} */ - -/*---------------------------------------------------------------------------*/ -/** - * \name UDP variables - * @{ - */ -/*---------------------------------------------------------------------------*/ -#if UIP_UDP -#if 0 -/* Moved to net_buf */ -struct uip_udp_conn *uip_udp_conn; -#endif -struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; -#endif /* UIP_UDP */ -/** @} */ - -/*---------------------------------------------------------------------------*/ -/** - * \name ICMPv6 variables - * @{ - */ -/*---------------------------------------------------------------------------*/ -#if UIP_CONF_ICMP6 -/** single possible icmpv6 "connection" */ -struct uip_icmp6_conn uip_icmp6_conns; -#endif /*UIP_CONF_ICMP6*/ -/** @} */ - -/*---------------------------------------------------------------------------*/ -/* Functions */ -/*---------------------------------------------------------------------------*/ -#if (!UIP_ARCH_ADD32 && UIP_TCP) -void -uip_add32(uint8_t *op32, uint16_t op16) -{ - uip_acc32[3] = op32[3] + (op16 & 0xff); - uip_acc32[2] = op32[2] + (op16 >> 8); - uip_acc32[1] = op32[1]; - uip_acc32[0] = op32[0]; - - if(uip_acc32[2] < (op16 >> 8)) { - ++uip_acc32[1]; - if(uip_acc32[1] == 0) { - ++uip_acc32[0]; - } - } - - - if(uip_acc32[3] < (op16 & 0xff)) { - ++uip_acc32[2]; - if(uip_acc32[2] == 0) { - ++uip_acc32[1]; - if(uip_acc32[1] == 0) { - ++uip_acc32[0]; - } - } - } -} - -#endif /* UIP_ARCH_ADD32 && UIP_TCP */ - -#if ! UIP_ARCH_CHKSUM -/*---------------------------------------------------------------------------*/ -static uint16_t -chksum(uint16_t sum, const uint8_t *data, uint16_t len) -{ - uint16_t t; - const uint8_t *dataptr; - const uint8_t *last_byte; - - dataptr = data; - last_byte = data + len - 1; - - while(dataptr < last_byte) { /* At least two more bytes */ - t = (dataptr[0] << 8) + dataptr[1]; - sum += t; - if(sum < t) { - sum++; /* carry */ - } - dataptr += 2; - } - - if(dataptr == last_byte) { - t = (dataptr[0] << 8) + 0; - sum += t; - if(sum < t) { - sum++; /* carry */ - } - } - - /* Return sum in host byte order. */ - return sum; -} -/*---------------------------------------------------------------------------*/ -uint16_t -uip_chksum(uint16_t *data, uint16_t len) -{ - return uip_htons(chksum(0, (uint8_t *)data, len)); -} -/*---------------------------------------------------------------------------*/ -#ifndef UIP_ARCH_IPCHKSUM -uint16_t -uip_ipchksum(struct net_buf *buf) -{ - uint16_t sum; - - sum = chksum(0, &uip_buf(buf)[UIP_LLH_LEN], UIP_IPH_LEN); - PRINTF("uip_ipchksum: sum 0x%04x\n", sum); - return (sum == 0) ? 0xffff : uip_htons(sum); -} -#endif -/*---------------------------------------------------------------------------*/ -static uint16_t -upper_layer_chksum(struct net_buf *buf, uint8_t proto) -{ -/* gcc 4.4.0 - 4.6.1 (maybe 4.3...) with -Os on 8 bit CPUS incorrectly compiles: - * int bar (int); - * int foo (unsigned char a, unsigned char b) { - * int len = (a << 8) + b; //len becomes 0xff00&+b - * return len + bar (len); - * } - * upper_layer_len triggers this bug unless it is declared volatile. - * See https://sourceforge.net/apps/mantisbt/contiki/view.php?id=3 - */ - volatile uint16_t upper_layer_len; - uint16_t sum; - - upper_layer_len = (((uint16_t)(UIP_IP_BUF(buf)->len[0]) << 8) + UIP_IP_BUF(buf)->len[1] - uip_ext_len(buf)); - - PRINTF("Upper layer checksum len: %d from: %d\n", upper_layer_len, - UIP_IPH_LEN + UIP_LLH_LEN + uip_ext_len(buf)); - - /* First sum pseudoheader. */ - /* IP protocol and length fields. This addition cannot carry. */ - sum = upper_layer_len + proto; - /* Sum IP source and destination addresses. */ - sum = chksum(sum, (uint8_t *)&UIP_IP_BUF(buf)->srcipaddr, 2 * sizeof(uip_ipaddr_t)); - - /* Sum TCP header and data. */ - sum = chksum(sum, &uip_buf(buf)[UIP_IPH_LEN + UIP_LLH_LEN + uip_ext_len(buf)], - upper_layer_len); - - return (sum == 0) ? 0xffff : uip_htons(sum); -} -/*---------------------------------------------------------------------------*/ -uint16_t -uip_icmp6chksum(struct net_buf *buf) -{ - return upper_layer_chksum(buf, UIP_PROTO_ICMP6); - -} -/*---------------------------------------------------------------------------*/ -#if UIP_TCP -uint16_t -uip_tcpchksum(struct net_buf *buf) -{ - return upper_layer_chksum(buf, UIP_PROTO_TCP); -} -#endif /* UIP_TCP */ -/*---------------------------------------------------------------------------*/ -#if UIP_UDP && UIP_UDP_CHECKSUMS -uint16_t -uip_udpchksum(struct net_buf *buf) -{ - return upper_layer_chksum(buf, UIP_PROTO_UDP); -} -#endif /* UIP_UDP && UIP_UDP_CHECKSUMS */ -#endif /* UIP_ARCH_CHKSUM */ -/*---------------------------------------------------------------------------*/ -void -uip_init(void) -{ -#if UIP_TCP - uint8_t c; -#endif - - uip_ds6_init(); - uip_icmp6_init(); - uip_nd6_init(); - -#if UIP_TCP - for(c = 0; c < UIP_LISTENPORTS; ++c) { - uip_listenports[c] = 0; - } - for(c = 0; c < UIP_CONNS; ++c) { - uip_conns[c].tcpstateflags = UIP_CLOSED; - uip_conns[c].len = 0; - } - - { - /* Randomise initial seq number */ - uint32_t c = clock_get_cycle(); - iss[0] = c & 0xff; - iss[1] = (c & 0xff00) >> 8; - iss[2] = (c & 0xff0000) >> 16; - iss[3] = (c & 0xff000000) >> 24; - } -#endif /* UIP_TCP */ - -#if UIP_ACTIVE_OPEN || UIP_UDP - lastport = 1024; -#endif /* UIP_ACTIVE_OPEN || UIP_UDP */ - -#if UIP_UDP - memset(&uip_udp_conns, 0, sizeof(uip_udp_conns)); -#endif /* UIP_UDP */ - -#if UIP_CONF_IPV6_MULTICAST - UIP_MCAST6.init(); -#endif -} -/*---------------------------------------------------------------------------*/ -#if UIP_TCP && UIP_ACTIVE_OPEN -struct uip_conn * -uip_connect(const uip_ipaddr_t *ripaddr, uint16_t rport) -{ - register struct uip_conn *conn, *cconn; - uint8_t c; - - /* Find an unused local port. */ - again: - ++lastport; - - if(lastport >= 32000) { - lastport = 4096; - } - - /* Check if this port is already in use, and if so try to find - another one. */ - for(c = 0; c < UIP_CONNS; ++c) { - conn = &uip_conns[c]; - if(conn->tcpstateflags != UIP_CLOSED && - conn->lport == uip_htons(lastport)) { - goto again; - } - } - - conn = 0; - for(c = 0; c < UIP_CONNS; ++c) { - cconn = &uip_conns[c]; - if(cconn->tcpstateflags == UIP_CLOSED) { - conn = cconn; - break; - } - if(cconn->tcpstateflags == UIP_TIME_WAIT) { - if(conn == 0 || - cconn->timer > conn->timer) { - conn = cconn; - } - } - } - - if(conn == 0) { - return 0; - } - - conn->tcpstateflags = UIP_SYN_SENT; - - conn->snd_nxt[0] = iss[0]; - conn->snd_nxt[1] = iss[1]; - conn->snd_nxt[2] = iss[2]; - conn->snd_nxt[3] = iss[3]; - - conn->rcv_nxt[0] = 0; - conn->rcv_nxt[1] = 0; - conn->rcv_nxt[2] = 0; - conn->rcv_nxt[3] = 0; - - conn->initialmss = conn->mss = UIP_TCP_MSS; - - conn->len = 1; /* TCP length of the SYN is one. */ - conn->nrtx = 0; - conn->timer = 1; /* Send the SYN next time around. */ - conn->rto = UIP_RTO; - conn->sa = 0; - conn->sv = 16; /* Initial value of the RTT variance. */ - conn->lport = uip_htons(lastport); - conn->rport = rport; - uip_ipaddr_copy(&conn->ripaddr, ripaddr); - - return conn; -} -#endif /* UIP_TCP && UIP_ACTIVE_OPEN */ -/*---------------------------------------------------------------------------*/ -void -remove_ext_hdr(struct net_buf *buf) -{ - /* Remove ext header before TCP/UDP processing. */ - if(uip_ext_len(buf) > 0) { - PRINTF("Cutting ext-header before processing (extlen: %d, uiplen: %d)\n", - uip_ext_len(buf), uip_len(buf)); - if(uip_len(buf) < UIP_IPH_LEN + uip_ext_len(buf)) { - PRINTF("ERROR: uip_len too short compared to ext len\n"); - uip_ext_len(buf) = 0; - uip_len(buf) = 0; - return; - } - memmove(((uint8_t *)UIP_TCP_BUF(buf)), - (uint8_t *)UIP_TCP_BUF(buf) + uip_ext_len(buf), - uip_len(buf) - UIP_IPH_LEN - uip_ext_len(buf)); - - uip_len(buf) -= uip_ext_len(buf); - ip_buf_len(buf) = uip_len(buf); - - /* Update the IP length. */ - UIP_IP_BUF(buf)->len[0] = (uip_len(buf) - UIP_IPH_LEN) >> 8; - UIP_IP_BUF(buf)->len[1] = (uip_len(buf) - UIP_IPH_LEN) & 0xff; - uip_ext_len(buf) = 0; - } -} -/*---------------------------------------------------------------------------*/ -#if UIP_UDP -struct uip_udp_conn * -uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport) -{ - register struct uip_udp_conn *conn; - uint8_t c; - - /* Find an unused local port. */ - again: - ++lastport; - - if(lastport >= 32000) { - lastport = 4096; - } - - for(c = 0; c < UIP_UDP_CONNS; ++c) { - if(uip_udp_conns[c].lport == uip_htons(lastport)) { - goto again; - } - } - - conn = 0; - for(c = 0; c < UIP_UDP_CONNS; ++c) { - if(uip_udp_conns[c].lport == 0) { - conn = &uip_udp_conns[c]; - break; - } - } - - if(conn == 0) { - return 0; - } - - conn->lport = UIP_HTONS(lastport); - conn->rport = rport; - if(ripaddr == NULL) { - memset(&conn->ripaddr, 0, sizeof(uip_ipaddr_t)); - } else { - uip_ipaddr_copy(&conn->ripaddr, ripaddr); - } - conn->ttl = uip_ds6_if.cur_hop_limit; - - return conn; -} -#endif /* UIP_UDP */ -/*---------------------------------------------------------------------------*/ -#if UIP_TCP -void -uip_unlisten(uint16_t port) -{ - uint8_t c; - for(c = 0; c < UIP_LISTENPORTS; ++c) { - if(uip_listenports[c] == port) { - uip_listenports[c] = 0; - return; - } - } -} -/*---------------------------------------------------------------------------*/ -void -uip_listen(uint16_t port) -{ - uint8_t c; - for(c = 0; c < UIP_LISTENPORTS; ++c) { - if(uip_listenports[c] == 0) { - uip_listenports[c] = port; - return; - } - } -} -#endif -/*---------------------------------------------------------------------------*/ - -#if UIP_CONF_IPV6_REASSEMBLY -#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN) - -static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE]; - -static uint8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)]; -/*the first byte of an IP fragment is aligned on an 8-byte boundary */ - -static const uint8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f, - 0x0f, 0x07, 0x03, 0x01}; -static uint16_t uip_reasslen; -static uint8_t uip_reassflags; - -#define UIP_REASS_FLAG_LASTFRAG 0x01 -#define UIP_REASS_FLAG_FIRSTFRAG 0x02 -#define UIP_REASS_FLAG_ERROR_MSG 0x04 - - -/* - * See RFC 2460 for a description of fragmentation in IPv6 - * A typical Ipv6 fragment - * +------------------+--------+--------------+ - * | Unfragmentable |Fragment| first | - * | Part | Header | fragment | - * +------------------+--------+--------------+ - */ - - -struct etimer uip_reass_timer; /* timer for reassembly */ -uint8_t uip_reass_on; /* equal to 1 if we are currently reassembling a packet */ - -static uint32_t uip_id; /* For every packet that is to be fragmented, the source - node generates an Identification value that is present - in all the fragments */ -#define IP_MF 0x0001 - -static uint16_t -uip_reass(void) -{ - uint16_t offset=0; - uint16_t len; - uint16_t i; - - /* If ip_reasstmr is zero, no packet is present in the buffer */ - /* We first write the unfragmentable part of IP header into the reassembly - buffer. The reset the other reassembly variables. */ - if(uip_reass_on == 0) { - PRINTF("Starting reassembly\n"); - memcpy(FBUF, UIP_IP_BUF(buf), uip_ext_len(buf) + UIP_IPH_LEN); - /* temporary in case we do not receive the fragment with offset 0 first */ - etimer_set(&uip_reass_timer, UIP_REASS_MAXAGE*CLOCK_SECOND, &tcpip_process); - uip_reass_on = 1; - uip_reassflags = 0; - uip_id = UIP_FRAG_BUF->id; - /* Clear the bitmap. */ - memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap)); - } - /* - * Check if the incoming fragment matches the one currently present - * in the reasembly buffer. If so, we proceed with copying the fragment - * into the buffer. - */ - if(uip_ipaddr_cmp(&FBUF->srcipaddr, &UIP_IP_BUF(buf)->srcipaddr) && - uip_ipaddr_cmp(&FBUF->destipaddr, &UIP_IP_BUF(buf)->destipaddr) && - UIP_FRAG_BUF->id == uip_id) { - len = uip_len(buf) - uip_ext_len(buf) - UIP_IPH_LEN - UIP_FRAGH_LEN; - offset = (uip_ntohs(UIP_FRAG_BUF->offsetresmore) & 0xfff8); - /* in byte, originaly in multiple of 8 bytes*/ - PRINTF("len %d\n", len); - PRINTF("offset %d\n", offset); - if(offset == 0){ - uip_reassflags |= UIP_REASS_FLAG_FIRSTFRAG; - /* - * The Next Header field of the last header of the Unfragmentable - * Part is obtained from the Next Header field of the first - * fragment's Fragment header. - */ - *uip_next_hdr = UIP_FRAG_BUF->next; - memcpy(FBUF, UIP_IP_BUF(buf), uip_ext_len(buf) + UIP_IPH_LEN); - PRINTF("src "); - PRINT6ADDR(&FBUF->srcipaddr); - PRINTF("dest "); - PRINT6ADDR(&FBUF->destipaddr); - PRINTF("next %d\n", UIP_IP_BUF(buf)->proto); - - } - - /* If the offset or the offset + fragment length overflows the - reassembly buffer, we discard the entire packet. */ - if(offset > UIP_REASS_BUFSIZE || - offset + len > UIP_REASS_BUFSIZE) { - uip_reass_on = 0; - etimer_stop(&uip_reass_timer); - return 0; - } - - /* If this fragment has the More Fragments flag set to zero, it is the - last fragment*/ - if((uip_ntohs(UIP_FRAG_BUF->offsetresmore) & IP_MF) == 0) { - uip_reassflags |= UIP_REASS_FLAG_LASTFRAG; - /*calculate the size of the entire packet*/ - uip_reasslen = offset + len; - PRINTF("LAST FRAGMENT reasslen %d\n", uip_reasslen); - } else { - /* If len is not a multiple of 8 octets and the M flag of that fragment - is 1, then that fragment must be discarded and an ICMP Parameter - Problem, Code 0, message should be sent to the source of the fragment, - pointing to the Payload Length field of the fragment packet. */ - if(len % 8 != 0){ - uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 4); - uip_reassflags |= UIP_REASS_FLAG_ERROR_MSG; - /* not clear if we should interrupt reassembly, but it seems so from - the conformance tests */ - uip_reass_on = 0; - etimer_stop(&uip_reass_timer); - return uip_len(buf); - } - } - - /* Copy the fragment into the reassembly buffer, at the right - offset. */ - memcpy((uint8_t *)FBUF + UIP_IPH_LEN + uip_ext_len(buf) + offset, - (uint8_t *)UIP_FRAG_BUF + UIP_FRAGH_LEN, len); - - /* Update the bitmap. */ - if(offset >> 6 == (offset + len) >> 6) { - uip_reassbitmap[offset >> 6] |= - bitmap_bits[(offset >> 3) & 7] & - ~bitmap_bits[((offset + len) >> 3) & 7]; - } else { - /* If the two endpoints are in different bytes, we update the - bytes in the endpoints and fill the stuff inbetween with - 0xff. */ - uip_reassbitmap[offset >> 6] |= bitmap_bits[(offset >> 3) & 7]; - - for(i = (1 + (offset >> 6)); i < ((offset + len) >> 6); ++i) { - uip_reassbitmap[i] = 0xff; - } - uip_reassbitmap[(offset + len) >> 6] |= - ~bitmap_bits[((offset + len) >> 3) & 7]; - } - - /* Finally, we check if we have a full packet in the buffer. We do - this by checking if we have the last fragment and if all bits - in the bitmap are set. */ - - if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) { - /* Check all bytes up to and including all but the last byte in - the bitmap. */ - for(i = 0; i < (uip_reasslen >> 6); ++i) { - if(uip_reassbitmap[i] != 0xff) { - return 0; - } - } - /* Check the last byte in the bitmap. It should contain just the - right amount of bits. */ - if(uip_reassbitmap[uip_reasslen >> 6] != - (uint8_t)~bitmap_bits[(uip_reasslen >> 3) & 7]) { - return 0; - } - - /* If we have come this far, we have a full packet in the - buffer, so we copy it to uip_buf. We also reset the timer. */ - uip_reass_on = 0; - etimer_stop(&uip_reass_timer); - - uip_reasslen += UIP_IPH_LEN + uip_ext_len(buf); - memcpy(UIP_IP_BUF(buf), FBUF, uip_reasslen); - UIP_IP_BUF(buf)->len[0] = ((uip_reasslen - UIP_IPH_LEN) >> 8); - UIP_IP_BUF(buf)->len[1] = ((uip_reasslen - UIP_IPH_LEN) & 0xff); - PRINTF("REASSEMBLED PAQUET %d (%d)\n", uip_reasslen, - (UIP_IP_BUF(buf)->len[0] << 8) | UIP_IP_BUF(buf)->len[1]); - - return uip_reasslen; - - } - } else { - PRINTF("Already reassembling another paquet\n"); - } - return 0; -} - -void -uip_reass_over(struct net_buf *buf) -{ - /* to late, we abandon the reassembly of the packet */ - - uip_reass_on = 0; - etimer_stop(&uip_reass_timer); - - if(uip_reassflags & UIP_REASS_FLAG_FIRSTFRAG){ - PRINTF("FRAG INTERRUPTED TOO LATE\n"); - /* If the first fragment has been received, an ICMP Time Exceeded - -- Fragment Reassembly Time Exceeded message should be sent to the - source of that fragment. */ - /** \note - * We don't have a complete packet to put in the error message. - * We could include the first fragment but since its not mandated by - * any RFC, we decided not to include it as it reduces the size of - * the packet. - */ - uip_len(buf) = 0; - uip_ext_len(buf) = 0; - memcpy(UIP_IP_BUF(buf), FBUF, UIP_IPH_LEN); /* copy the header for src - and dest address*/ - uip_icmp6_error_output(ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_REASSEMBLY, 0); - - UIP_STAT(++uip_stat.ip.sent); - uip_flags(buf) = 0; - } -} - -#endif /* UIP_CONF_IPV6_REASSEMBLY */ - -/*---------------------------------------------------------------------------*/ -#if UIP_TCP -static void -uip_add_rcv_nxt(struct net_buf *buf, uint16_t n) -{ - uip_add32(uip_conn(buf)->rcv_nxt, n); - uip_conn(buf)->rcv_nxt[0] = uip_acc32[0]; - uip_conn(buf)->rcv_nxt[1] = uip_acc32[1]; - uip_conn(buf)->rcv_nxt[2] = uip_acc32[2]; - uip_conn(buf)->rcv_nxt[3] = uip_acc32[3]; -} -#endif -/*---------------------------------------------------------------------------*/ - -/** - * \brief Process the options in Destination and Hop By Hop extension headers - */ -static uint8_t -ext_hdr_options_process(struct net_buf *buf) -{ - /* - * Length field in the extension header: length of the header in units of - * 8 bytes, excluding the first 8 bytes - * length field in an option : the length of data in the option - */ - if (((UIP_EXT_BUF(buf)->len << 3) + 8) > buf->len) { - PRINTF("Corrupted packet, extension header %d too long (max %d bytes)\n", - (UIP_EXT_BUF(buf)->len << 3) + 8, buf->len); - return 1; /* invalid packet, drop it */ - } - - uip_ext_opt_offset(buf) = 2; - while(uip_ext_opt_offset(buf) < ((UIP_EXT_BUF(buf)->len << 3) + 8)) { - switch(UIP_EXT_HDR_OPT_BUF(buf)->type) { - /* - * for now we do not support any options except padding ones - * PAD1 does not make sense as the header must be 8bytes aligned, - * hence we can only have - */ - case UIP_EXT_HDR_OPT_PAD1: - PRINTF("Processing PAD1 option\n"); - uip_ext_opt_offset(buf) += 1; - break; - case UIP_EXT_HDR_OPT_PADN: - PRINTF("Processing PADN option\n"); - uip_ext_opt_offset(buf) += UIP_EXT_HDR_OPT_PADN_BUF(buf)->opt_len + 2; - break; - case UIP_EXT_HDR_OPT_RPL: - /* Fixes situation when a node that is not using RPL - * joins a network which does. The received packages will include the - * RPL header and processed by the "default" case of the switch - * (0x63 & 0xC0 = 0x40). Hence, the packet is discarded as the header - * is considered invalid. - * Using this fix, the header is ignored, and the next header (if - * present) is processed. - */ -#if UIP_CONF_IPV6_RPL - PRINTF("Processing RPL option\n"); - if(rpl_verify_header(buf, uip_ext_opt_offset(buf))) { - PRINTF("RPL Option Error: Dropping Packet\n"); - return 1; - } -#endif /* UIP_CONF_IPV6_RPL */ - uip_ext_opt_offset(buf) += (UIP_EXT_HDR_OPT_BUF(buf)->len) + 2; - return 0; - default: - /* - * check the two highest order bits of the option - * - 00 skip over this option and continue processing the header. - * - 01 discard the packet. - * - 10 discard the packet and, regardless of whether or not the - * packet's Destination Address was a multicast address, send an - * ICMP Parameter Problem, Code 2, message to the packet's - * Source Address, pointing to the unrecognized Option Type. - * - 11 discard the packet and, only if the packet's Destination - * Address was not a multicast address, send an ICMP Parameter - * Problem, Code 2, message to the packet's Source Address, - * pointing to the unrecognized Option Type. - */ - PRINTF("MSB %x\n", UIP_EXT_HDR_OPT_BUF(buf)->type); - switch(UIP_EXT_HDR_OPT_BUF(buf)->type & 0xC0) { - case 0: - break; - case 0x40: - return 1; - case 0xC0: - if(uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr)) { - return 1; - } - case 0x80: - uip_icmp6_error_output(buf, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, - (uint32_t)UIP_IPH_LEN + uip_ext_len(buf) + uip_ext_opt_offset(buf)); - return 2; - } - /* in the cases were we did not discard, update ext_opt* */ - uip_ext_opt_offset(buf) += UIP_EXT_HDR_OPT_BUF(buf)->len + 2; - break; - } - } - return 0; -} - -#if UIP_TCP -static inline void handle_tcp_retransmit_timer(struct net_buf *not_used, - void *ptr) -{ - struct uip_conn *conn = ptr; - - PRINTF("%s: connection %p buf %p\n", __func__, conn, conn ? conn->buf : 0); - if (conn && conn->buf) { - conn->timer = 0; - if (uip_process(&conn->buf, UIP_TIMER)) { - tcpip_resend_syn(conn, conn->buf); - } - } -} - -static inline void tcp_set_retrans_timer(struct uip_conn *conn) -{ - ctimer_set(NULL, &conn->retransmit_timer, CLOCK_SECOND, - &handle_tcp_retransmit_timer, conn); -} - -static inline void tcp_cancel_retrans_timer(struct uip_conn *conn) -{ - ctimer_stop(&conn->retransmit_timer); -} -#endif /* UIP_TCP */ - -/*---------------------------------------------------------------------------*/ -uint8_t -uip_process(struct net_buf **buf_out, uint8_t flag) -{ - struct net_buf *buf = *buf_out; -#if UIP_TCP - register struct uip_conn *uip_connr = uip_conn(buf); - uint8_t c; -#endif /* UIP_TCP */ -#if UIP_UDP - int i; - if(flag == UIP_UDP_SEND_CONN) { - goto udp_send; - } -#endif /* UIP_UDP */ - -#if UIP_TCP - if(flag != UIP_TCP_SEND_CONN) { -#endif - uip_sappdata(buf) = uip_appdata(buf) = &uip_buf(buf)[UIP_IPTCPH_LEN + UIP_LLH_LEN]; -#if UIP_TCP - } -#endif - /* Check if we were invoked because of a poll request for a - particular connection. */ -#if UIP_TCP - if(flag == UIP_POLL_REQUEST || flag == UIP_TCP_SEND_CONN) { - - /* If the connection is not found, and we are initiating the - * connection, try to get it. - */ - if (!uip_connr) { - uip_connr = net_context_get_internal_connection(ip_buf_context(buf)); - if (!uip_connr) { - PRINTF("No matching connection found for buf %p\n", buf); - ip_buf_sent_status(buf) = -ENOTCONN; - return 0; - } else { - uip_set_conn(buf) = uip_connr; - PRINTF("Using connection %p for buf %p\n", uip_conn(buf), buf); - } - } - - if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED && - !uip_outstanding(uip_connr)) { - if (flag == UIP_POLL) { - uip_flags(buf) = UIP_POLL; - } - UIP_APPCALL(buf); - goto appsend; -#if UIP_ACTIVE_OPEN - } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) { - if (uip_connr->nrtx > UIP_MAXSYNRTX) { - /* SYN has been sent too many times, just stop the connection. - */ - PRINTF("Too many SYN sent, dropping connection %p\n", uip_connr); - net_context_set_connection_status(ip_buf_context(buf), -ETIMEDOUT); - goto drop; - } - - /* In the SYN_SENT state, we retransmit out SYN. */ - UIP_TCP_BUF(buf)->flags = 0; - goto tcp_send_syn; -#endif /* UIP_ACTIVE_OPEN */ - } - if (flag == UIP_TCP_SEND_CONN) { - switch (uip_connr->tcpstateflags & UIP_TS_MASK) { - case UIP_CLOSED: - case UIP_FIN_WAIT_1: - case UIP_FIN_WAIT_2: - case UIP_CLOSING: - case UIP_TIME_WAIT: - ip_buf_sent_status(buf) = -ECONNABORTED; - goto drop; - } - - if (uip_outstanding(uip_connr)) { - ip_buf_sent_status(buf) = -EAGAIN; - PRINTF("Retry to send packet len %d, outstanding data len %d, " - "conn %p\n", uip_len(buf), uip_outstanding(uip_connr), - uip_connr); - flag = UIP_TIMER; - goto tcp_retry; - } - } - goto drop; - } -#else /* TCP */ - if(flag == UIP_POLL_REQUEST) { - goto drop; - } -#endif /* UIP_TCP */ - /* Check if we were invoked because of the perodic timer fireing. */ - if(flag == UIP_TIMER) { - /* Reset the length variables. */ -#if UIP_TCP - uip_len(buf) = 0; - uip_slen(buf) = 0; - - /* Increase the initial sequence number. */ - if(++iss[3] == 0) { - if(++iss[2] == 0) { - if(++iss[1] == 0) { - ++iss[0]; - } - } - } - tcp_retry: - /* - * Check if the connection is in a state in which we simply wait - * for the connection to time out. If so, we increase the - * connection's timer and remove the connection if it times - * out. - */ - if(uip_connr->tcpstateflags == UIP_TIME_WAIT || - uip_connr->tcpstateflags == UIP_FIN_WAIT_2) { - ++(uip_connr->timer); - if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) { - uip_connr->tcpstateflags = UIP_CLOSED; - } - } else if(uip_connr->tcpstateflags != UIP_CLOSED) { - if (!uip_connr->buf) { - /* There cannot be any data pending if buf is NULL */ - uip_outstanding(uip_connr) = 0; - } - - /* - * If the connection has outstanding data, we increase the - * connection's timer and see if it has reached the RTO value - * in which case we retransmit. - */ - if(uip_outstanding(uip_connr)) { - if(uip_connr->timer-- == 0) { - if(uip_connr->nrtx == UIP_MAXRTX || - ((uip_connr->tcpstateflags == UIP_SYN_SENT || - uip_connr->tcpstateflags == UIP_SYN_RCVD) && - uip_connr->nrtx == UIP_MAXSYNRTX)) { - uip_connr->tcpstateflags = UIP_CLOSED; - /* - * We call UIP_APPCALL() with uip_flags set to - * UIP_TIMEDOUT to inform the application that the - * connection has timed out. - */ - uip_flags(buf) = UIP_TIMEDOUT; - UIP_APPCALL(buf); - - /* We also send a reset packet to the remote host. */ - UIP_TCP_BUF(buf)->flags = TCP_RST | TCP_ACK; - goto tcp_send_nodata; - } - - /* Exponential backoff. */ - uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4? - 4: - uip_connr->nrtx); - ++(uip_connr->nrtx); - - /* - * Ok, so we need to retransmit. We do this differently - * depending on which state we are in. In ESTABLISHED, we - * call upon the application so that it may prepare the - * data for the retransmit. In SYN_RCVD, we resend the - * SYNACK that we sent earlier and in LAST_ACK we have to - * retransmit our FINACK. - */ - UIP_STAT(++uip_stat.tcp.rexmit); - switch(uip_connr->tcpstateflags & UIP_TS_MASK) { - case UIP_SYN_RCVD: - /* In the SYN_RCVD state, we should retransmit our SYNACK. */ - goto tcp_send_synack; - -#if UIP_ACTIVE_OPEN - case UIP_SYN_SENT: - /* In the SYN_SENT state, we retransmit out SYN. */ - UIP_TCP_BUF(buf)->flags = 0; - goto tcp_send_syn; -#endif /* UIP_ACTIVE_OPEN */ - - case UIP_ESTABLISHED: - /* - * In the ESTABLISHED state, we call upon the application - * to do the actual retransmit after which we jump into - * the code for sending out the packet (the apprexmit - * label). - */ - uip_flags(buf) = UIP_REXMIT; - UIP_APPCALL(buf); - goto apprexmit; - - case UIP_FIN_WAIT_1: - case UIP_CLOSING: - case UIP_LAST_ACK: - /* In all these states we should retransmit a FINACK. */ - goto tcp_send_finack; - } - } - } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) { - /* - * If there was no need for a retransmission, we poll the - * application for new data. - */ - uip_flags(buf) = UIP_POLL; - UIP_APPCALL(buf); - goto appsend; - } - } - goto drop; -#endif /* UIP_TCP */ - } -#if UIP_UDP - if(flag == UIP_UDP_TIMER) { - if(uip_udp_conn(buf)->lport != 0) { - uip_set_conn(buf) = NULL; - uip_sappdata(buf) = uip_appdata(buf) = &uip_buf(buf)[UIP_IPUDPH_LEN + UIP_LLH_LEN]; - uip_len(buf) = uip_slen(buf) = 0; - uip_flags(buf) = UIP_POLL; - UIP_UDP_APPCALL(buf); - goto udp_send; - } else { - goto drop; - } - } -#endif /* UIP_UDP */ - - - /* This is where the input processing starts. */ - UIP_STAT(++uip_stat.ip.recv); - - /* Start of IP input header processing code. */ - - /* Check validity of the IP header. */ - if((UIP_IP_BUF(buf)->vtc & 0xf0) != 0x60) { /* IP version and header length. */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.vhlerr); - UIP_LOG("ipv6: invalid version."); - goto drop; - } - /* - * Check the size of the packet. If the size reported to us in - * uip_len is smaller the size reported in the IP header, we assume - * that the packet has been corrupted in transit. If the size of - * uip_len is larger than the size reported in the IP packet header, - * the packet has been padded and we set uip_len to the correct - * value.. - */ - - if((UIP_IP_BUF(buf)->len[0] << 8) + UIP_IP_BUF(buf)->len[1] <= uip_len(buf)) { - uip_len(buf) = (UIP_IP_BUF(buf)->len[0] << 8) + UIP_IP_BUF(buf)->len[1] + UIP_IPH_LEN; - /* - * The length reported in the IPv6 header is the - * length of the payload that follows the - * header. However, uIP uses the uip_len variable - * for holding the size of the entire packet, - * including the IP header. For IPv4 this is not a - * problem as the length field in the IPv4 header - * contains the length of the entire packet. But - * for IPv6 we need to add the size of the IPv6 - * header (40 bytes). - */ - } else { - UIP_LOG("ip: packet shorter than reported in IP header."); - PRINTF("IPv6 packet size %d buf len %d\n", - (UIP_IP_BUF(buf)->len[0] << 8) + UIP_IP_BUF(buf)->len[1], - uip_len(buf)); - goto drop; - } - - PRINTF("IPv6 packet received from "); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF(" to "); - PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr); - PRINTF("\n"); - - if(uip_is_addr_mcast(&UIP_IP_BUF(buf)->srcipaddr)){ - UIP_STAT(++uip_stat.ip.drop); - PRINTF("Dropping packet, src is mcast\n"); - goto drop; - } - -#if UIP_CONF_ROUTER - /* - * Next header field processing. In IPv6, we can have extension headers, - * if present, the Hop-by-Hop Option must be processed before forwarding - * the packet. - */ - uip_next_hdr = &UIP_IP_BUF->proto; - uip_ext_len(buf) = 0; - uip_ext_bitmap = 0; - if(*uip_next_hdr == UIP_PROTO_HBHO) { -#if UIP_CONF_IPV6_CHECKS - uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO; -#endif /* UIP_CONF_IPV6_CHECKS */ - switch(ext_hdr_options_process()) { - case 0: - /* continue */ - uip_next_hdr = &UIP_EXT_BUF->next; - uip_ext_len(buf) += (UIP_EXT_BUF->len << 3) + 8; - break; - case 1: - PRINTF("Dropping packet after extension header processing\n"); - /* silently discard */ - goto drop; - case 2: - PRINTF("Sending error message after extension header processing\n"); - /* send icmp error message (created in ext_hdr_options_process) - * and discard*/ - goto send; - } - } - - /* - * Process Packets with a routable multicast destination: - * - We invoke the multicast engine and let it do its thing - * (cache, forward etc). - * - We never execute the datagram forwarding logic in this file here. When - * the engine returns, forwarding has been handled if and as required. - * - Depending on the return value, we either discard or deliver up the stack - * - * All multicast engines must hook in here. After this function returns, we - * expect UIP_BUF to be unmodified - */ -#if UIP_CONF_IPV6_MULTICAST - if(uip_is_addr_mcast_routable(&UIP_IP_BUF->destipaddr)) { - if(UIP_MCAST6.in() == UIP_MCAST6_ACCEPT) { - /* Deliver up the stack */ - goto process; - } else { - /* Don't deliver up the stack */ - goto drop; - } - } -#endif /* UIP_IPV6_CONF_MULTICAST */ - - /* TBD Some Parameter problem messages */ - if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) && - !uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) { - if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr) && - !uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) && - !uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) && - !uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr) && - !uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) { - - - /* Check MTU */ - if(uip_len > UIP_LINK_MTU) { - uip_icmp6_error_output(ICMP6_PACKET_TOO_BIG, 0, UIP_LINK_MTU); - UIP_STAT(++uip_stat.ip.drop); - goto send; - } - /* Check Hop Limit */ - if(UIP_IP_BUF->ttl <= 1) { - uip_icmp6_error_output(ICMP6_TIME_EXCEEDED, - ICMP6_TIME_EXCEED_TRANSIT, 0); - UIP_STAT(++uip_stat.ip.drop); - goto send; - } - -#if UIP_CONF_IPV6_RPL - if(rpl_update_header_empty()) { - /* Packet can not be forwarded */ - PRINTF("RPL Forward Option Error\n"); - goto drop; - } -#endif /* UIP_CONF_IPV6_RPL */ - - UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1; - PRINTF("Forwarding packet to "); - PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF("\n"); - UIP_STAT(++uip_stat.ip.forwarded); - goto send; - } else { - if((uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)) && - (!uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) && - (!uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) && - (!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) && - (!uip_ds6_is_addr_onlink((&UIP_IP_BUF->destipaddr)))) { - PRINTF("LL source address with off link destination, dropping\n"); - uip_icmp6_error_output(ICMP6_DST_UNREACH, - ICMP6_DST_UNREACH_NOTNEIGHBOR, 0); - goto send; - } - PRINTF("Dropping packet, not for me and link local or multicast\n"); - UIP_STAT(++uip_stat.ip.drop); - goto drop; - } - } -#else /* UIP_CONF_ROUTER */ - if(!uip_ds6_is_my_addr(&UIP_IP_BUF(buf)->destipaddr) && - !uip_ds6_is_my_maddr(&UIP_IP_BUF(buf)->destipaddr) && - !uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr) && - !uip_is_addr_loopback(&UIP_IP_BUF(buf)->destipaddr)) { - PRINTF("Dropping packet, not for me\n"); - UIP_STAT(++uip_stat.ip.drop); - goto drop; - } - - /* - * Next header field processing. In IPv6, we can have extension headers, - * they are processed here - */ - uip_next_hdr(buf) = &UIP_IP_BUF(buf)->proto; - uip_ext_len(buf) = 0; - uip_ext_bitmap(buf) = 0; -#endif /* UIP_CONF_ROUTER */ - -#if UIP_CONF_ROUTER -#if UIP_CONF_IPV6_MULTICAST - process: -#endif -#endif - - while(1) { - switch(*(uip_next_hdr(buf))){ -#if UIP_TCP - case UIP_PROTO_TCP: - /* TCP, for both IPv4 and IPv6 */ - goto tcp_input; -#endif /* UIP_TCP */ -#if UIP_UDP - case UIP_PROTO_UDP: - /* UDP, for both IPv4 and IPv6 */ - goto udp_input; -#endif /* UIP_UDP */ - case UIP_PROTO_ICMP6: - /* ICMPv6 */ - goto icmp6_input; - case UIP_PROTO_HBHO: - PRINTF("Processing hbh header\n"); - /* Hop by hop option header */ -#if UIP_CONF_IPV6_CHECKS - /* Hop by hop option header. If we saw one HBH already, drop */ - if(uip_ext_bitmap(buf) & UIP_EXT_HDR_BITMAP_HBHO) { - goto bad_hdr; - } else { - uip_ext_bitmap(buf) |= UIP_EXT_HDR_BITMAP_HBHO; - } -#endif /*UIP_CONF_IPV6_CHECKS*/ - switch(ext_hdr_options_process(buf)) { - case 0: - /*continue*/ - uip_next_hdr(buf) = &UIP_EXT_BUF(buf)->next; - uip_ext_len(buf) += (UIP_EXT_BUF(buf)->len << 3) + 8; - break; - case 1: - /*silently discard*/ - goto drop; - case 2: - /* send icmp error message (created in ext_hdr_options_process) - * and discard*/ - goto send; - } - break; - case UIP_PROTO_DESTO: -#if UIP_CONF_IPV6_CHECKS - /* Destination option header. if we saw two already, drop */ - PRINTF("Processing desto header\n"); - if(uip_ext_bitmap(buf) & UIP_EXT_HDR_BITMAP_DESTO1) { - if(uip_ext_bitmap(buf) & UIP_EXT_HDR_BITMAP_DESTO2) { - goto bad_hdr; - } else{ - uip_ext_bitmap(buf) |= UIP_EXT_HDR_BITMAP_DESTO2; - } - } else { - uip_ext_bitmap(buf) |= UIP_EXT_HDR_BITMAP_DESTO1; - } -#endif /*UIP_CONF_IPV6_CHECKS*/ - switch(ext_hdr_options_process(buf)) { - case 0: - /*continue*/ - uip_next_hdr(buf) = &UIP_EXT_BUF(buf)->next; - uip_ext_len(buf) += (UIP_EXT_BUF(buf)->len << 3) + 8; - break; - case 1: - /*silently discard*/ - goto drop; - case 2: - /* send icmp error message (created in ext_hdr_options_process) - * and discard*/ - goto send; - } - break; - case UIP_PROTO_ROUTING: -#if UIP_CONF_IPV6_CHECKS - /* Routing header. If we saw one already, drop */ - if(uip_ext_bitmap(buf) & UIP_EXT_HDR_BITMAP_ROUTING) { - goto bad_hdr; - } else { - uip_ext_bitmap(buf) |= UIP_EXT_HDR_BITMAP_ROUTING; - } -#endif /*UIP_CONF_IPV6_CHECKS*/ - /* - * Routing Header length field is in units of 8 bytes, excluding - * As per RFC2460 section 4.4, if routing type is unrecognized: - * if segments left = 0, ignore the header - * if segments left > 0, discard packet and send icmp error pointing - * to the routing type - */ - - PRINTF("Processing Routing header\n"); - if(UIP_ROUTING_BUF(buf)->seg_left > 0) { - uip_icmp6_error_output(buf, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, UIP_IPH_LEN + uip_ext_len(buf) + 2); - UIP_STAT(++uip_stat.ip.drop); - UIP_LOG("ip6: unrecognized routing type"); - goto send; - } - uip_next_hdr(buf) = &UIP_EXT_BUF(buf)->next; - uip_ext_len(buf) += (UIP_EXT_BUF(buf)->len << 3) + 8; - break; - case UIP_PROTO_FRAG: - /* Fragmentation header:call the reassembly function, then leave */ -#if UIP_CONF_IPV6_REASSEMBLY - PRINTF("Processing frag header\n"); - uip_len(buf) = uip_reass(); - if(uip_len(buf) == 0) { - goto drop; - } - if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG){ - /* we are not done with reassembly, this is an error message */ - goto send; - } - /*packet is reassembled, reset the next hdr to the beginning - of the IP header and restart the parsing of the reassembled pkt*/ - PRINTF("Processing reassembled packet\n"); - uip_ext_len(buf) = 0; - uip_ext_bitmap(buf) = 0; - uip_next_hdr(buf) = &UIP_IP_BUF(buf)->proto; - break; -#else /* UIP_CONF_IPV6_REASSEMBLY */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.fragerr); - UIP_LOG("ip: fragment dropped."); - goto drop; -#endif /* UIP_CONF_IPV6_REASSEMBLY */ - case UIP_PROTO_NONE: - goto drop; - default: - goto bad_hdr; - } - } - bad_hdr: - /* - * RFC 2460 send error message parameterr problem, code unrecognized - * next header, pointing to the next header field - */ - uip_icmp6_error_output(buf, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER, (uint32_t)(uip_next_hdr(buf) - (uint8_t *)UIP_IP_BUF(buf))); - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.protoerr); - UIP_LOG("ip6: unrecognized header"); - goto send; - /* End of headers processing */ - - icmp6_input: - /* This is IPv6 ICMPv6 processing code. */ - PRINTF("icmp6_input: length %d type: %d \n", uip_len(buf), UIP_ICMP_BUF(buf)->type); - -#if UIP_CONF_IPV6_CHECKS - /* Compute and check the ICMP header checksum */ - if(uip_icmp6chksum(buf) != 0xffff) { - UIP_STAT(++uip_stat.icmp.drop); - UIP_STAT(++uip_stat.icmp.chkerr); - UIP_LOG("icmpv6: bad checksum."); - PRINTF("icmpv6: bad checksum."); - goto drop; - } -#endif /*UIP_CONF_IPV6_CHECKS*/ - - UIP_STAT(++uip_stat.icmp.recv); - /* - * Here we process incoming ICMPv6 packets - * For echo request, we send echo reply - * For ND pkts, we call the appropriate function in uip-nd6.c - * We do not treat Error messages for now - * If no pkt is to be sent as an answer to the incoming one, we - * "goto drop". Else we just break; then at the after the "switch" - * we "goto send" - */ -#if UIP_CONF_ICMP6 - UIP_ICMP6_APPCALL(UIP_ICMP_BUF(buf)->type); -#endif /*UIP_CONF_ICMP6*/ - - /* - * Search generic input handlers. - * The handler is in charge of setting uip_len to 0 - */ - if(uip_icmp6_input(buf, UIP_ICMP_BUF(buf)->type, - UIP_ICMP_BUF(buf)->icode) == UIP_ICMP6_INPUT_ERROR) { - PRINTF("Unknown ICMPv6 message type/code %d\n", UIP_ICMP_BUF(buf)->type); - UIP_STAT(++uip_stat.icmp.drop); - UIP_STAT(++uip_stat.icmp.typeerr); - UIP_LOG("icmp6: unknown ICMPv6 message."); - uip_len(buf) = 0; - } - - if(uip_len(buf) > 0) { - goto send; - } else { - goto drop; - } - /* End of IPv6 ICMP processing. */ - - -#if UIP_UDP - /* UDP input processing. */ - udp_input: - - remove_ext_hdr(buf); - - PRINTF("Receiving UDP packet\n"); - - /* UDP processing is really just a hack. We don't do anything to the - UDP/IP headers, but let the UDP application do all the hard - work. If the application sets uip_slen, it has a packet to - send. */ -#if UIP_UDP_CHECKSUMS - uip_len(buf) = uip_len(buf) - UIP_IPUDPH_LEN; - uip_appdata(buf) = &uip_buf(buf)[UIP_IPUDPH_LEN + UIP_LLH_LEN]; - /* XXX hack: UDP/IPv6 receivers should drop packets with UDP - checksum 0. Here, we explicitly receive UDP packets with checksum - 0. This is to be able to debug code that for one reason or - another miscomputes UDP checksums. The reception of zero UDP - checksums should be turned into a configration option. */ - if(UIP_UDP_BUF(buf)->udpchksum != 0 && uip_udpchksum(buf) != 0xffff) { - UIP_STAT(++uip_stat.udp.drop); - UIP_STAT(++uip_stat.udp.chkerr); - PRINTF("udp: bad checksum 0x%04x 0x%04x\n", UIP_UDP_BUF(buf)->udpchksum, - uip_udpchksum(buf)); - goto drop; - } -#else /* UIP_UDP_CHECKSUMS */ - uip_len(buf) = uip_len(buf) - UIP_IPUDPH_LEN; -#endif /* UIP_UDP_CHECKSUMS */ - - /* Make sure that the UDP destination port number is not zero. */ - if(UIP_UDP_BUF(buf)->destport == 0) { - PRINTF("udp: zero port.\n"); - goto drop; - } - - /* Demultiplex this UDP packet between the UDP "connections". */ - for(i = 0; i < UIP_UDP_CONNS; i++) { - /* If the local UDP port is non-zero, the connection is considered - to be used. If so, the local port number is checked against the - destination port number in the received packet. If the two port - numbers match, the remote port number is checked if the - connection is bound to a remote port. Finally, if the - connection is bound to a remote IP address, the source IP - address of the packet is checked. */ -#if 0 - PRINTF("%d: %p lport %d <- %d rport %d <- %d addr ", - i, &uip_udp_conns[i], - uip_ntohs(uip_udp_conns[i].lport), uip_ntohs(UIP_UDP_BUF(buf)->destport), - uip_ntohs(uip_udp_conns[i].rport), uip_ntohs(UIP_UDP_BUF(buf)->srcport)); - PRINT6ADDR(&uip_udp_conns[i].ripaddr); - PRINTF(" <- "); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF("\n"); -#endif /* 0 */ - if(uip_udp_conns[i].lport != 0 && - UIP_UDP_BUF(buf)->destport == uip_udp_conns[i].lport && - (uip_udp_conns[i].rport == 0 || - UIP_UDP_BUF(buf)->srcport == uip_udp_conns[i].rport) && - (uip_is_addr_unspecified(&uip_udp_conns[i].ripaddr) || - uip_ipaddr_cmp(&UIP_IP_BUF(buf)->srcipaddr, &uip_udp_conns[i].ripaddr))) { - uip_set_udp_conn(buf) = &uip_udp_conns[i]; - goto udp_found; - } - } - uip_set_udp_conn(buf) = NULL; - PRINTF("udp: no matching connection found\n"); - UIP_STAT(++uip_stat.udp.drop); - -#if UIP_UDP_SEND_UNREACH_NOPORT - uip_icmp6_error_output(buf, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0); - goto send; -#else - uip_len(buf) = 0; - goto drop; -#endif - - udp_found: - PRINTF("In udp_found\n"); - UIP_STAT(++uip_stat.udp.recv); - - uip_set_conn(buf) = NULL; - uip_flags(buf) = UIP_NEWDATA; - uip_sappdata(buf) = uip_appdata(buf) = &uip_buf(buf)[UIP_IPUDPH_LEN + UIP_LLH_LEN]; - uip_slen(buf) = 0; - UIP_UDP_APPCALL(buf); - if(uip_slen(buf) == 0) { - /* If the application does not want to send anything, then uip_slen(buf) - * will be 0. In this case we MUST NOT set uip_len(buf) to 0 as that would - * cause the net_buf to be released by rx fiber. In this case it is - * application responsibility to release the buffer. Returning 0 here - * will mean that tcpip.c:packet_input() will not try to call - * tcpip_ipv6_output(). - */ - return 0; - } - - udp_send: - PRINTF("In udp_send\n"); - - uip_len(buf) = uip_slen(buf) + UIP_IPUDPH_LEN; - - /* For IPv6, the IP length field does not include the IPv6 IP header - length. */ - UIP_IP_BUF(buf)->len[0] = ((uip_len(buf) - UIP_IPH_LEN) >> 8); - UIP_IP_BUF(buf)->len[1] = ((uip_len(buf) - UIP_IPH_LEN) & 0xff); - - UIP_IP_BUF(buf)->ttl = uip_udp_conn(buf)->ttl; - UIP_IP_BUF(buf)->proto = UIP_PROTO_UDP; - - UIP_UDP_BUF(buf)->udplen = UIP_HTONS(uip_slen(buf) + UIP_UDPH_LEN); - UIP_UDP_BUF(buf)->udpchksum = 0; - - UIP_UDP_BUF(buf)->srcport = uip_udp_conn(buf)->lport; - UIP_UDP_BUF(buf)->destport = uip_udp_conn(buf)->rport; - - uip_ipaddr_copy(&UIP_IP_BUF(buf)->destipaddr, &uip_udp_conn(buf)->ripaddr); - uip_ds6_select_src(&UIP_IP_BUF(buf)->srcipaddr, &UIP_IP_BUF(buf)->destipaddr); - - uip_appdata(buf) = &uip_buf(buf)[UIP_LLH_LEN + UIP_IPTCPH_LEN]; - -#if UIP_UDP_CHECKSUMS - /* Calculate UDP checksum. */ - UIP_UDP_BUF(buf)->udpchksum = ~(uip_udpchksum(buf)); - if(UIP_UDP_BUF(buf)->udpchksum == 0) { - UIP_UDP_BUF(buf)->udpchksum = 0xffff; - } -#endif /* UIP_UDP_CHECKSUMS */ - -#if UIP_CONF_IPV6_RPL - rpl_insert_header(buf); -#endif /* UIP_CONF_IPV6_RPL */ - - UIP_STAT(++uip_stat.udp.sent); - goto ip_send_nolen; -#endif /* UIP_UDP */ - -#if UIP_TCP - /* TCP input processing. */ - tcp_input: - - remove_ext_hdr(buf); - - UIP_STAT(++uip_stat.tcp.recv); - PRINTF("Receiving TCP packet\n"); - /* Start of TCP input header processing code. */ - - if(uip_tcpchksum(buf) != 0xffff) { /* Compute and check the TCP - checksum. */ - UIP_STAT(++uip_stat.tcp.drop); - UIP_STAT(++uip_stat.tcp.chkerr); - PRINTF("tcp: bad checksum 0x%04x 0x%04x\n", UIP_TCP_BUF(buf)->tcpchksum, - uip_tcpchksum(buf)); - goto drop; - } - - /* Make sure that the TCP port number is not zero. */ - if(UIP_TCP_BUF(buf)->destport == 0 || UIP_TCP_BUF(buf)->srcport == 0) { - PRINTF("tcp: zero port."); - goto drop; - } - - /* Demultiplex this segment. */ - /* First check any active connections. */ - for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1]; - ++uip_connr) { - if(uip_connr->tcpstateflags != UIP_CLOSED && - UIP_TCP_BUF(buf)->destport == uip_connr->lport && - UIP_TCP_BUF(buf)->srcport == uip_connr->rport && - uip_ipaddr_cmp(&UIP_IP_BUF(buf)->srcipaddr, &uip_connr->ripaddr)) { - goto found; - } - } - - /* If we didn't find and active connection that expected the packet, - either this packet is an old duplicate, or this is a SYN packet - destined for a connection in LISTEN. If the SYN flag isn't set, - it is an old packet and we send a RST. */ - if((UIP_TCP_BUF(buf)->flags & TCP_CTL) != TCP_SYN) { - goto reset; - } - - tmp16 = UIP_TCP_BUF(buf)->destport; - /* Next, check listening connections. */ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - if(tmp16 == uip_listenports[c]) { - goto found_listen; - } - } - - /* No matching connection found, so we send a RST packet. */ - UIP_STAT(++uip_stat.tcp.synrst); - - reset: - PRINTF("In reset\n"); - /* We do not send resets in response to resets. */ - if(UIP_TCP_BUF(buf)->flags & TCP_RST) { - goto drop; - } - - UIP_STAT(++uip_stat.tcp.rst); - - UIP_TCP_BUF(buf)->flags = TCP_RST | TCP_ACK; - uip_len(buf) = UIP_IPTCPH_LEN; - UIP_TCP_BUF(buf)->tcpoffset = 5 << 4; - - /* Flip the seqno and ackno fields in the TCP header. */ - c = UIP_TCP_BUF(buf)->seqno[3]; - UIP_TCP_BUF(buf)->seqno[3] = UIP_TCP_BUF(buf)->ackno[3]; - UIP_TCP_BUF(buf)->ackno[3] = c; - - c = UIP_TCP_BUF(buf)->seqno[2]; - UIP_TCP_BUF(buf)->seqno[2] = UIP_TCP_BUF(buf)->ackno[2]; - UIP_TCP_BUF(buf)->ackno[2] = c; - - c = UIP_TCP_BUF(buf)->seqno[1]; - UIP_TCP_BUF(buf)->seqno[1] = UIP_TCP_BUF(buf)->ackno[1]; - UIP_TCP_BUF(buf)->ackno[1] = c; - - c = UIP_TCP_BUF(buf)->seqno[0]; - UIP_TCP_BUF(buf)->seqno[0] = UIP_TCP_BUF(buf)->ackno[0]; - UIP_TCP_BUF(buf)->ackno[0] = c; - - /* We also have to increase the sequence number we are - acknowledging. If the least significant byte overflowed, we need - to propagate the carry to the other bytes as well. */ - if(++UIP_TCP_BUF(buf)->ackno[3] == 0) { - if(++UIP_TCP_BUF(buf)->ackno[2] == 0) { - if(++UIP_TCP_BUF(buf)->ackno[1] == 0) { - ++UIP_TCP_BUF(buf)->ackno[0]; - } - } - } - - /* Swap port numbers. */ - tmp16 = UIP_TCP_BUF(buf)->srcport; - UIP_TCP_BUF(buf)->srcport = UIP_TCP_BUF(buf)->destport; - UIP_TCP_BUF(buf)->destport = tmp16; - - /* Swap IP addresses. */ - uip_ipaddr_copy(&UIP_IP_BUF(buf)->destipaddr, &UIP_IP_BUF(buf)->srcipaddr); - uip_ds6_select_src(&UIP_IP_BUF(buf)->srcipaddr, &UIP_IP_BUF(buf)->destipaddr); - /* And send out the RST packet! */ - goto tcp_send_noconn; - - /* This label will be jumped to if we matched the incoming packet - with a connection in LISTEN. In that case, we should create a new - connection and send a SYNACK in return. */ - found_listen: - PRINTF("In found listen\n"); - /* First we check if there are any connections avaliable. Unused - connections are kept in the same table as used connections, but - unused ones have the tcpstate set to CLOSED. Also, connections in - TIME_WAIT are kept track of and we'll use the oldest one if no - CLOSED connections are found. Thanks to Eddie C. Dost for a very - nice algorithm for the TIME_WAIT search. */ - uip_connr = 0; - for(c = 0; c < UIP_CONNS; ++c) { - if(uip_conns[c].tcpstateflags == UIP_CLOSED) { - uip_connr = &uip_conns[c]; - break; - } - if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) { - if(uip_connr == 0 || - uip_conns[c].timer > uip_connr->timer) { - uip_connr = &uip_conns[c]; - } - } - } - - if(uip_connr == 0) { - /* All connections are used already, we drop packet and hope that - the remote end will retransmit the packet at a time when we - have more spare connections. */ - UIP_STAT(++uip_stat.tcp.syndrop); - UIP_LOG("tcp: found no unused connections."); - goto drop; - } - uip_set_conn(buf) = uip_connr; - - /* Fill in the necessary fields for the new connection. */ - uip_connr->rto = uip_connr->timer = UIP_RTO; - uip_connr->sa = 0; - uip_connr->sv = 4; - uip_connr->nrtx = 0; - uip_connr->lport = UIP_TCP_BUF(buf)->destport; - uip_connr->rport = UIP_TCP_BUF(buf)->srcport; - uip_ipaddr_copy(&uip_connr->ripaddr, &UIP_IP_BUF(buf)->srcipaddr); - uip_connr->tcpstateflags = UIP_SYN_RCVD; - - uip_connr->snd_nxt[0] = iss[0]; - uip_connr->snd_nxt[1] = iss[1]; - uip_connr->snd_nxt[2] = iss[2]; - uip_connr->snd_nxt[3] = iss[3]; - uip_connr->len = 1; - - if (flag == UIP_TCP_SEND_CONN) { - /* So we are trying send some data to other host */ - if (uip_connr->buf && uip_connr->buf != buf) { - uip_connr->buf = ip_buf_ref(buf); - } - } - - /* rcv_nxt should be the seqno from the incoming packet + 1. */ - uip_connr->rcv_nxt[3] = UIP_TCP_BUF(buf)->seqno[3]; - uip_connr->rcv_nxt[2] = UIP_TCP_BUF(buf)->seqno[2]; - uip_connr->rcv_nxt[1] = UIP_TCP_BUF(buf)->seqno[1]; - uip_connr->rcv_nxt[0] = UIP_TCP_BUF(buf)->seqno[0]; - uip_add_rcv_nxt(buf, 1); - - /* Parse the TCP MSS option, if present. */ - if((UIP_TCP_BUF(buf)->tcpoffset & 0xf0) > 0x50) { - for(c = 0; c < ((UIP_TCP_BUF(buf)->tcpoffset >> 4) - 5) << 2 ;) { - opt = uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + c]; - if(opt == TCP_OPT_END) { - /* End of options. */ - break; - } else if(opt == TCP_OPT_NOOP) { - ++c; - /* NOP option. */ - } else if(opt == TCP_OPT_MSS && - uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { - /* An MSS option with the right option length. */ - tmp16 = ((uint16_t)uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | - (uint16_t)uip_buf(buf)[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c]; - uip_connr->initialmss = uip_connr->mss = - tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; - - /* And we are done processing options. */ - break; - } else { - /* All other options have a length field, so that we easily - can skip past them. */ - if(uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { - /* If the length field is zero, the options are malformed - and we don't process them further. */ - break; - } - c += uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; - } - } - } - - /* Our response will be a SYNACK. */ -#if UIP_ACTIVE_OPEN - tcp_send_synack: - UIP_TCP_BUF(buf)->flags = TCP_ACK; - -tcp_send_syn: - UIP_TCP_BUF(buf)->flags |= TCP_SYN; - tcp_set_retrans_timer(uip_connr); -#else /* UIP_ACTIVE_OPEN */ - tcp_send_synack: - UIP_TCP_BUF(buf)->flags = TCP_SYN | TCP_ACK; -#endif /* UIP_ACTIVE_OPEN */ - - /* We send out the TCP Maximum Segment Size option with our - SYNACK. */ - UIP_TCP_BUF(buf)->optdata[0] = TCP_OPT_MSS; - UIP_TCP_BUF(buf)->optdata[1] = TCP_OPT_MSS_LEN; - UIP_TCP_BUF(buf)->optdata[2] = (UIP_TCP_MSS) / 256; - UIP_TCP_BUF(buf)->optdata[3] = (UIP_TCP_MSS) & 255; - uip_len(buf) = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN; - UIP_TCP_BUF(buf)->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4; - goto tcp_send; - - /* This label will be jumped to if we found an active connection. */ - found: - PRINTF("In found\n"); - uip_set_conn(buf) = uip_connr; - uip_flags(buf) = 0; - /* We do a very naive form of TCP reset processing; we just accept - any RST and kill our connection. We should in fact check if the - sequence number of this reset is wihtin our advertised window - before we accept the reset. */ - if(UIP_TCP_BUF(buf)->flags & TCP_RST) { - uip_connr->tcpstateflags = UIP_CLOSED; - UIP_LOG("tcp: got reset, aborting connection."); - uip_flags(buf) = UIP_ABORT; - UIP_APPCALL(buf); - goto drop; - } - - if (flag != UIP_TCP_SEND_CONN) { - /* If flag is set to UIP_TCP_SEND_CONN, then it means that we are - * trying to send the actual packet coming from user. In this case - * do not mess with the packet length. - */ - - /* Calculate the length of the data, if the application has sent - any data to us. */ - c = (UIP_TCP_BUF(buf)->tcpoffset >> 4) << 2; - /* uip_len will contain the length of the actual TCP data. This is - calculated by subtracing the length of the TCP header (in - c) and the length of the IP header (20 bytes). */ - uip_len(buf) = uip_len(buf) - c - UIP_IPH_LEN; - } - - /* First, check if the sequence number of the incoming packet is - what we're expecting next. If not, we send out an ACK with the - correct numbers in, unless we are in the SYN_RCVD state and - receive a SYN, in which case we should retransmit our SYNACK - (which is done futher down). */ - if(!((((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && - ((UIP_TCP_BUF(buf)->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) || - (((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) && - ((UIP_TCP_BUF(buf)->flags & TCP_CTL) == TCP_SYN)))) { - if((uip_len(buf) > 0 || ((UIP_TCP_BUF(buf)->flags & (TCP_SYN | TCP_FIN)) != 0)) && - (UIP_TCP_BUF(buf)->seqno[0] != uip_connr->rcv_nxt[0] || - UIP_TCP_BUF(buf)->seqno[1] != uip_connr->rcv_nxt[1] || - UIP_TCP_BUF(buf)->seqno[2] != uip_connr->rcv_nxt[2] || - UIP_TCP_BUF(buf)->seqno[3] != uip_connr->rcv_nxt[3])) { - - if((UIP_TCP_BUF(buf)->flags & TCP_SYN)) { - if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) { - goto tcp_send_synack; -#if UIP_ACTIVE_OPEN - } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) { - goto tcp_send_syn; -#endif - } - } - goto tcp_send_ack; - } - } - - /* Next, check if the incoming segment acknowledges any outstanding - data. If so, we update the sequence number, reset the length of - the outstanding data, calculate RTT estimations, and reset the - retransmission timer. */ - if((UIP_TCP_BUF(buf)->flags & TCP_ACK) && uip_outstanding(uip_connr)) { - uip_add32(uip_connr->snd_nxt, uip_connr->len); - - if(UIP_TCP_BUF(buf)->ackno[0] == uip_acc32[0] && - UIP_TCP_BUF(buf)->ackno[1] == uip_acc32[1] && - UIP_TCP_BUF(buf)->ackno[2] == uip_acc32[2] && - UIP_TCP_BUF(buf)->ackno[3] == uip_acc32[3]) { - /* Update sequence number. */ - uip_connr->snd_nxt[0] = uip_acc32[0]; - uip_connr->snd_nxt[1] = uip_acc32[1]; - uip_connr->snd_nxt[2] = uip_acc32[2]; - uip_connr->snd_nxt[3] = uip_acc32[3]; - - /* Do RTT estimation, unless we have done retransmissions. */ - if(uip_connr->nrtx == 0) { - signed char m; - m = uip_connr->rto - uip_connr->timer; - /* This is taken directly from VJs original code in his paper */ - m = m - (uip_connr->sa >> 3); - uip_connr->sa += m; - if(m < 0) { - m = -m; - } - m = m - (uip_connr->sv >> 2); - uip_connr->sv += m; - uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv; - - } - /* Set the acknowledged flag. */ - uip_flags(buf) = UIP_ACKDATA; - /* Reset the retransmission timer. */ - uip_connr->timer = uip_connr->rto; - - /* Reset length of outstanding data. */ - uip_connr->len = 0; - } - - } - - /* Do different things depending on in what state the connection is. */ - switch(uip_connr->tcpstateflags & UIP_TS_MASK) { - /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not - implemented, since we force the application to close when the - peer sends a FIN (hence the application goes directly from - ESTABLISHED to LAST_ACK). */ - case UIP_SYN_RCVD: - /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and - we are waiting for an ACK that acknowledges the data we sent - out the last time. Therefore, we want to have the UIP_ACKDATA - flag set. If so, we enter the ESTABLISHED state. */ - if(uip_flags(buf) & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_ESTABLISHED; - uip_flags(buf) = UIP_CONNECTED; - uip_connr->len = 0; - if(uip_len(buf) > 0) { - uip_flags(buf) |= UIP_NEWDATA; - uip_add_rcv_nxt(buf, uip_len(buf)); - } - uip_slen(buf) = 0; - UIP_APPCALL(buf); - goto appsend; - } - /* We need to retransmit the SYNACK */ - if((UIP_TCP_BUF(buf)->flags & TCP_CTL) == TCP_SYN) { - goto tcp_send_synack; - } - goto drop; -#if UIP_ACTIVE_OPEN - case UIP_SYN_SENT: - /* In SYN_SENT, we wait for a SYNACK that is sent in response to - our SYN. The rcv_nxt is set to sequence number in the SYNACK - plus one, and we send an ACK. We move into the ESTABLISHED - state. */ - if((uip_flags(buf) & UIP_ACKDATA) && - (UIP_TCP_BUF(buf)->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) { - - /* Parse the TCP MSS option, if present. */ - if((UIP_TCP_BUF(buf)->tcpoffset & 0xf0) > 0x50) { - for(c = 0; c < ((UIP_TCP_BUF(buf)->tcpoffset >> 4) - 5) << 2 ;) { - opt = uip_buf(buf)[UIP_IPTCPH_LEN + UIP_LLH_LEN + c]; - if(opt == TCP_OPT_END) { - /* End of options. */ - break; - } else if(opt == TCP_OPT_NOOP) { - ++c; - /* NOP option. */ - } else if(opt == TCP_OPT_MSS && - uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { - /* An MSS option with the right option length. */ - tmp16 = (uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | - uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c]; - uip_connr->initialmss = - uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; - - /* And we are done processing options. */ - break; - } else { - /* All other options have a length field, so that we easily - can skip past them. */ - if(uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { - /* If the length field is zero, the options are malformed - and we don't process them further. */ - break; - } - c += uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; - } - } - } - uip_connr->tcpstateflags = UIP_ESTABLISHED; - uip_connr->rcv_nxt[0] = UIP_TCP_BUF(buf)->seqno[0]; - uip_connr->rcv_nxt[1] = UIP_TCP_BUF(buf)->seqno[1]; - uip_connr->rcv_nxt[2] = UIP_TCP_BUF(buf)->seqno[2]; - uip_connr->rcv_nxt[3] = UIP_TCP_BUF(buf)->seqno[3]; - uip_add_rcv_nxt(buf, 1); - uip_flags(buf) = UIP_CONNECTED | UIP_NEWDATA; - uip_connr->len = 0; - uip_len(buf) = 0; - uip_slen(buf) = 0; - ip_buf_sent_status(buf) = 0; - uip_set_conn(buf) = uip_connr; - - if (uip_connr->buf) { - /* Now that we know the original connection request, clear - * the buf in connr - */ - net_context_set_connection_status(ip_buf_context(uip_connr->buf), 0); - net_context_set_internal_connection(ip_buf_context(uip_connr->buf), - uip_connr); - tcp_cancel_retrans_timer(uip_connr); - - /* We received ACK for syn */ - if (uip_connr->buf) { - net_context_set_connection_status(ip_buf_context(uip_connr->buf), -EINPROGRESS); - } - - /* Now send the pending data */ - buf = uip_connr->buf; - *buf_out = buf; - - uip_flags(buf) = UIP_CONNECTED; - } - /* Right now we have received SYN-ACK so we can now start to send data. - * The UIP_APPCALL() will cause a call to this function by the - * net_context.c TCP process thread which will call - * handle_tcp_connection(). - */ - UIP_APPCALL(buf); - PRINTF("Returning now buf %p ref %p\n", buf, buf->ref); - return 0; - } - /* Inform the application that the connection failed */ - uip_flags(buf) = UIP_ABORT; - UIP_APPCALL(buf); - /* The connection is closed after we send the RST */ - uip_conn(buf)->tcpstateflags = UIP_CLOSED; - goto reset; -#endif /* UIP_ACTIVE_OPEN */ - - case UIP_ESTABLISHED: - /* In the ESTABLISHED state, we call upon the application to feed - data into the uip_buf. If the UIP_ACKDATA flag is set, the - application should put new data into the buffer, otherwise we are - retransmitting an old segment, and the application should put that - data into the buffer. - - If the incoming packet is a FIN, we should close the connection on - this side as well, and we send out a FIN and enter the LAST_ACK - state. We require that there is no outstanding data; otherwise the - sequence numbers will be screwed up. */ - - if(UIP_TCP_BUF(buf)->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) { - if(uip_outstanding(uip_connr)) { - goto drop; - } - uip_add_rcv_nxt(buf, 1 + uip_len(buf)); - uip_flags(buf) |= UIP_CLOSE; - if(uip_len(buf) > 0) { - uip_flags(buf) |= UIP_NEWDATA; - } - UIP_APPCALL(buf); - uip_connr->len = 1; - uip_connr->tcpstateflags = UIP_LAST_ACK; - uip_connr->nrtx = 0; - tcp_send_finack: - UIP_TCP_BUF(buf)->flags = TCP_FIN | TCP_ACK; - goto tcp_send_nodata; - } - - /* Check the URG flag. If this is set, the segment carries urgent - data that we must pass to the application. */ - if((UIP_TCP_BUF(buf)->flags & TCP_URG) != 0) { -#if UIP_URGDATA > 0 - uip_urglen = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]; - if(uip_urglen > uip_len) { - /* There is more urgent data in the next segment to come. */ - uip_urglen = uip_len; - } - uip_add_rcv_nxt(uip_urglen); - uip_len -= uip_urglen; - uip_urgdata = uip_appdata; - uip_appdata += uip_urglen; - } else { - uip_urglen = 0; -#else /* UIP_URGDATA > 0 */ - uip_appdata(buf) = ((char *)uip_appdata(buf)) + ((UIP_TCP_BUF(buf)->urgp[0] << 8) | UIP_TCP_BUF(buf)->urgp[1]); - uip_len(buf) -= (UIP_TCP_BUF(buf)->urgp[0] << 8) | UIP_TCP_BUF(buf)->urgp[1]; -#endif /* UIP_URGDATA > 0 */ - } - - /* If uip_len > 0 we have TCP data in the packet, and we flag this - by setting the UIP_NEWDATA flag and update the sequence number - we acknowledge. If the application has stopped the dataflow - using uip_stop(), we must not accept any data packets from the - remote host. */ - if(uip_len(buf) > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) { - uip_flags(buf) |= UIP_NEWDATA; - uip_add_rcv_nxt(buf, uip_len(buf)); - } - - /* Check if the available buffer space advertised by the other end - is smaller than the initial MSS for this connection. If so, we - set the current MSS to the window size to ensure that the - application does not send more data than the other end can - handle. - - If the remote host advertises a zero window, we set the MSS to - the initial MSS so that the application will send an entire MSS - of data. This data will not be acknowledged by the receiver, - and the application will retransmit it. This is called the - "persistent timer" and uses the retransmission mechanim. - */ - tmp16 = ((uint16_t)UIP_TCP_BUF(buf)->wnd[0] << 8) + (uint16_t)UIP_TCP_BUF(buf)->wnd[1]; - if(tmp16 > uip_connr->initialmss || - tmp16 == 0) { - tmp16 = uip_connr->initialmss; - } - uip_connr->mss = tmp16; - - /* If this packet constitutes an ACK for outstanding data (flagged - by the UIP_ACKDATA flag, we should call the application since it - might want to send more data. If the incoming packet had data - from the peer (as flagged by the UIP_NEWDATA flag), the - application must also be notified. - - When the application is called, the global variable uip_len - contains the length of the incoming data. The application can - access the incoming data through the global pointer - uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN - bytes into the uip_buf array. - - If the application wishes to send any data, this data should be - put into the uip_appdata and the length of the data should be - put into uip_len. If the application don't have any data to - send, uip_len must be set to 0. */ - if(uip_flags(buf) & (UIP_NEWDATA | UIP_ACKDATA)) { - if(flag != UIP_TCP_SEND_CONN) { - /* Do not reset the slen because we are being called - * directly by the application. - */ - uip_slen(buf) = 0; - } - - if (uip_connr->buf) { - net_context_tcp_set_pending(ip_buf_context(uip_connr->buf), NULL); - net_context_set_internal_connection(ip_buf_context(uip_connr->buf), - uip_connr); - - /* At this point we have received ACK to data in uip_connr->buf */ - - /* This is not an error but tells net_core.c:net_send() that - * user should be able to send now more data. - */ - net_context_set_connection_status(ip_buf_context(uip_connr->buf), - EISCONN); - - /* Eventually the uip_connr->buf will be freed - * by net_core.c:net_send() - */ - - tcp_cancel_retrans_timer(uip_connr); - - } else { - /* We have no pending data so this will cause ACK to be sent to - * peer in few lines below. - */ - uip_flags(buf) |= UIP_NEWDATA; - } - - UIP_APPCALL(buf); - - appsend: - - if(uip_flags(buf) & UIP_ABORT) { - uip_slen(buf) = 0; - uip_connr->tcpstateflags = UIP_CLOSED; - UIP_TCP_BUF(buf)->flags = TCP_RST | TCP_ACK; - goto tcp_send_nodata; - } - - if(uip_flags(buf) & UIP_CLOSE) { - uip_slen(buf) = 0; - uip_connr->len = 1; - uip_connr->tcpstateflags = UIP_FIN_WAIT_1; - uip_connr->nrtx = 0; - UIP_TCP_BUF(buf)->flags = TCP_FIN | TCP_ACK; - goto tcp_send_nodata; - } - - /* If uip_slen > 0, the application has data to be sent. */ - if(uip_slen(buf) > 0) { - - /* If the connection has acknowledged data, the contents of - the ->len variable should be discarded. */ - if((uip_flags(buf) & UIP_ACKDATA) != 0) { - uip_connr->len = 0; - } - - /* If the ->len variable is non-zero the connection has - already data in transit and cannot send anymore right - now. */ - if(uip_connr->len == 0) { - - /* The application cannot send more than what is allowed by - the mss (the minumum of the MSS and the available - window). */ - if(uip_slen(buf) > uip_connr->mss) { - uip_slen(buf) = uip_connr->mss; - } - - /* Remember how much data we send out now so that we know - when everything has been acknowledged. */ - uip_connr->len = uip_slen(buf); - - PRINTF("Setting connection %p to pending length %d\n", - uip_connr, uip_connr->len); - - if (uip_connr->buf) { - if (uip_connr->buf != buf) { - PRINTF("Data packet %p already pending....\n", - uip_connr->buf); - } - } else { - uip_connr->buf = ip_buf_ref(buf); - } - - } else { - - /* If the application already had unacknowledged data, we - make sure that the application does not send (i.e., - retransmit) out more than it previously sent out. */ - uip_slen(buf) = uip_connr->len; - } - } - uip_connr->nrtx = 0; - apprexmit: - uip_appdata(buf) = uip_sappdata(buf); - - /* If the application has data to be sent, or if the incoming - packet had new data in it, we must send out a packet. */ - if(uip_slen(buf) > 0 && uip_connr->len > 0) { - /* Add the length of the IP and TCP headers. */ - uip_len(buf) = uip_connr->len + UIP_TCPIP_HLEN; - /* We always set the ACK flag in response packets. */ - UIP_TCP_BUF(buf)->flags = TCP_ACK | TCP_PSH; - /* Send the packet. */ - goto tcp_send_noopts; - } - /* If there is no data to send, just send out a pure ACK if - there is newdata. */ - if(uip_flags(buf) & UIP_NEWDATA) { - uip_len(buf) = UIP_TCPIP_HLEN; - UIP_TCP_BUF(buf)->flags = TCP_ACK; - goto tcp_send_noopts; - } - } - goto drop; - case UIP_LAST_ACK: - /* We can close this connection if the peer has acknowledged our - FIN. This is indicated by the UIP_ACKDATA flag. */ - if(uip_flags(buf) & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_CLOSED; - uip_flags(buf) = UIP_CLOSE; - UIP_APPCALL(buf); - } - break; - - case UIP_FIN_WAIT_1: - /* The application has closed the connection, but the remote host - hasn't closed its end yet. Thus we do nothing but wait for a - FIN from the other side. */ - if(uip_len(buf) > 0) { - uip_add_rcv_nxt(buf, uip_len(buf)); - } - if(UIP_TCP_BUF(buf)->flags & TCP_FIN) { - if(uip_flags(buf) & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - uip_connr->len = 0; - } else { - uip_connr->tcpstateflags = UIP_CLOSING; - } - uip_add_rcv_nxt(buf, 1); - uip_flags(buf) = UIP_CLOSE; - UIP_APPCALL(buf); - goto tcp_send_ack; - } else if(uip_flags(buf) & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_FIN_WAIT_2; - uip_connr->len = 0; - goto drop; - } - if(uip_len(buf) > 0) { - goto tcp_send_ack; - } - goto drop; - - case UIP_FIN_WAIT_2: - if(uip_len(buf) > 0) { - uip_add_rcv_nxt(buf, uip_len(buf)); - } - if(UIP_TCP_BUF(buf)->flags & TCP_FIN) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - uip_add_rcv_nxt(buf, 1); - uip_flags(buf) = UIP_CLOSE; - UIP_APPCALL(buf); - goto tcp_send_ack; - } - if(uip_len(buf) > 0) { - goto tcp_send_ack; - } - goto drop; - - case UIP_TIME_WAIT: - goto tcp_send_ack; - - case UIP_CLOSING: - if(uip_flags(buf) & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - } - } - goto drop; - - /* We jump here when we are ready to send the packet, and just want - to set the appropriate TCP sequence numbers in the TCP header. */ - tcp_send_ack: - PRINTF("In tcp_send_ack\n"); - UIP_TCP_BUF(buf)->flags = TCP_ACK; - - tcp_send_nodata: - if (flag != UIP_TCP_SEND_CONN) { - PRINTF("In tcp_send_nodata\n"); - uip_len(buf) = UIP_IPTCPH_LEN; - buf->len = UIP_IPTCPH_LEN; - } - - tcp_send_noopts: - UIP_TCP_BUF(buf)->tcpoffset = (UIP_TCPH_LEN / 4) << 4; - - /* We're done with the input processing. We are now ready to send a - reply. Our job is to fill in all the fields of the TCP and IP - headers before calculating the checksum and finally send the - packet. */ - tcp_send: - PRINTF("In tcp_send\n"); - - UIP_TCP_BUF(buf)->ackno[0] = uip_connr->rcv_nxt[0]; - UIP_TCP_BUF(buf)->ackno[1] = uip_connr->rcv_nxt[1]; - UIP_TCP_BUF(buf)->ackno[2] = uip_connr->rcv_nxt[2]; - UIP_TCP_BUF(buf)->ackno[3] = uip_connr->rcv_nxt[3]; - - UIP_TCP_BUF(buf)->seqno[0] = uip_connr->snd_nxt[0]; - UIP_TCP_BUF(buf)->seqno[1] = uip_connr->snd_nxt[1]; - UIP_TCP_BUF(buf)->seqno[2] = uip_connr->snd_nxt[2]; - UIP_TCP_BUF(buf)->seqno[3] = uip_connr->snd_nxt[3]; - - UIP_TCP_BUF(buf)->srcport = uip_connr->lport; - UIP_TCP_BUF(buf)->destport = uip_connr->rport; - - uip_ipaddr_copy(&UIP_IP_BUF(buf)->destipaddr, &uip_connr->ripaddr); - uip_ds6_select_src(&UIP_IP_BUF(buf)->srcipaddr, &UIP_IP_BUF(buf)->destipaddr); - PRINTF("Sending TCP packet to "); - PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr); - PRINTF(" from "); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF("\n"); - - if(uip_connr->tcpstateflags & UIP_STOPPED) { - /* If the connection has issued uip_stop(), we advertise a zero - window so that the remote host will stop sending data. */ - UIP_TCP_BUF(buf)->wnd[0] = UIP_TCP_BUF(buf)->wnd[1] = 0; - } else { - UIP_TCP_BUF(buf)->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8); - UIP_TCP_BUF(buf)->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); - } - - tcp_send_noconn: - UIP_IP_BUF(buf)->proto = UIP_PROTO_TCP; - - UIP_IP_BUF(buf)->ttl = uip_ds6_if.cur_hop_limit; - UIP_IP_BUF(buf)->len[0] = ((uip_len(buf) - UIP_IPH_LEN) >> 8); - UIP_IP_BUF(buf)->len[1] = ((uip_len(buf) - UIP_IPH_LEN) & 0xff); - - UIP_TCP_BUF(buf)->urgp[0] = UIP_TCP_BUF(buf)->urgp[1] = 0; - - /* Calculate TCP checksum. */ - UIP_TCP_BUF(buf)->tcpchksum = 0; - UIP_TCP_BUF(buf)->tcpchksum = ~(uip_tcpchksum(buf)); - UIP_STAT(++uip_stat.tcp.sent); - -#endif /* UIP_TCP */ -#if UIP_UDP - ip_send_nolen: -#endif - UIP_IP_BUF(buf)->vtc = 0x60; - UIP_IP_BUF(buf)->tcflow = 0x00; - UIP_IP_BUF(buf)->flow = 0x00; - send: - PRINTF("Sending packet with length %d (%d)\n", uip_len(buf), - (UIP_IP_BUF(buf)->len[0] << 8) | UIP_IP_BUF(buf)->len[1]); - - UIP_STAT(++uip_stat.ip.sent); - /* Return and let the caller do the actual transmission. */ - uip_flags(buf) = 0; - buf->len = uip_len(buf); - return 1; - - drop: - uip_len(buf) = 0; - uip_ext_len(buf) = 0; - uip_ext_bitmap(buf) = 0; - uip_flags(buf) = 0; - -#if UIP_TCP - /* Clear any pending packet */ - if (uip_connr && uip_connr->buf) { - tcp_cancel_retrans_timer(uip_connr); - switch (uip_connr->tcpstateflags & UIP_TS_MASK) { - case UIP_FIN_WAIT_1: - case UIP_FIN_WAIT_2: - case UIP_CLOSING: - case UIP_TIME_WAIT: - ip_buf_unref(uip_connr->buf); - uip_connr->buf = NULL; - } - } -#endif - - return 0; -} -/*---------------------------------------------------------------------------*/ -uint16_t -uip_htons(uint16_t val) -{ - return UIP_HTONS(val); -} - -uint32_t -uip_htonl(uint32_t val) -{ - return UIP_HTONL(val); -} -/*---------------------------------------------------------------------------*/ -#if UIP_TCP -void -uip_send(struct net_buf *buf, const void *data, int len) -{ - int copylen; -#define MIN(a,b) ((a) < (b)? (a): (b)) - - uip_sappdata(buf) = ip_buf_appdata(buf); - - if(uip_sappdata(buf) != NULL) { - copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN - - (int)((char *)uip_sappdata(buf) - - (char *)&uip_buf(buf)[UIP_LLH_LEN + UIP_TCPIP_HLEN])); - } else { - copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN); - } - if(copylen > 0) { - uip_slen(buf) = copylen; - if(data != uip_sappdata(buf)) { - if(uip_sappdata(buf) == NULL) { - memmove((char *)&uip_buf(buf)[UIP_LLH_LEN + UIP_TCPIP_HLEN], - (data), uip_slen(buf)); - } else { - memmove(uip_sappdata(buf), (data), uip_slen(buf)); - } - } - if (uip_process(&buf, UIP_TCP_SEND_CONN)) { - int ret; - - ret = tcpip_ipv6_output(buf); - if (!ret) { - PRINTF("Packet %p sending failed.\n", buf); - ip_buf_sent_status(buf) = -EAGAIN; - } - } - } -} -#endif /* UIP_TCP */ -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/linkaddr.c b/net/ip/contiki/linkaddr.c deleted file mode 100644 index 3dca0ec5f064ef729c2c79bb766c9ae26fa35a4c..0000000000000000000000000000000000000000 --- a/net/ip/contiki/linkaddr.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Functions for manipulating Rime addresses - * \author - * Adam Dunkels - */ - -/** - * \addtogroup linkaddr - * @{ - */ - -#include "contiki/linkaddr.h" -#include - -linkaddr_t linkaddr_node_addr; -#if LINKADDR_SIZE == 2 -const linkaddr_t linkaddr_null = { { 0, 0 } }; -#else /*LINKADDR_SIZE == 2*/ -#if LINKADDR_SIZE == 8 -const linkaddr_t linkaddr_null = { { 0, 0, 0, 0, 0, 0, 0, 0 } }; -#else /*LINKADDR_SIZE == 8*/ -#if LINKADDR_SIZE == 6 -const linkaddr_t linkaddr_null = { { 0, 0, 0, 0, 0, 0 } }; -#endif /*LINKADDR_SIZE == 6*/ -#endif /*LINKADDR_SIZE == 8*/ -#endif /*LINKADDR_SIZE == 2*/ - - -/*---------------------------------------------------------------------------*/ -void -linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src) -{ - memcpy(dest, src, LINKADDR_SIZE); -} -/*---------------------------------------------------------------------------*/ -int -linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2) -{ - return (memcmp(addr1, addr2, LINKADDR_SIZE) == 0); -} -/*---------------------------------------------------------------------------*/ -void -linkaddr_set_node_addr(linkaddr_t *t) -{ - linkaddr_copy(&linkaddr_node_addr, t); -} -/*---------------------------------------------------------------------------*/ -linkaddr_t *linkaddr_get_node_addr(int *addr_len) -{ - if (addr_len) { - *addr_len = LINKADDR_SIZE; - } - - return &linkaddr_node_addr; -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/linkaddr.h b/net/ip/contiki/linkaddr.h deleted file mode 100644 index 9e8f3e7672f49743616649936f6c57432b68e557..0000000000000000000000000000000000000000 --- a/net/ip/contiki/linkaddr.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header file for the Rime address representation - * \author - * Adam Dunkels - */ - -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup linkaddr Rime addresses - * @{ - * - * The linkaddr module is an abstract representation of addresses in - * Rime. - * - */ - -#ifndef LINKADDR_H_ -#define LINKADDR_H_ - -#include "contiki-conf.h" - -#ifdef LINKADDR_CONF_SIZE -#define LINKADDR_SIZE LINKADDR_CONF_SIZE -#else /* LINKADDR_SIZE */ -#define LINKADDR_SIZE 2 -#endif /* LINKADDR_SIZE */ - -typedef union { - unsigned char u8[LINKADDR_SIZE]; -#if LINKADDR_SIZE == 2 - uint16_t u16; -#endif /* LINKADDR_SIZE == 2 */ -} linkaddr_t; - -typedef union { - uint8_t u8[8]; - uint16_t u16[4]; -} linkaddr_extended_t; - -/** - * \brief Copy a Rime address - * \param dest The destination - * \param from The source - * - * This function copies a Rime address from one location - * to another. - * - */ -void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *from); - -/** - * \brief Compare two Rime addresses - * \param addr1 The first address - * \param addr2 The second address - * \return Non-zero if the addresses are the same, zero if they are different - * - * This function compares two Rime addresses and returns - * the result of the comparison. The function acts like - * the '==' operator and returns non-zero if the addresses - * are the same, and zero if the addresses are different. - * - */ -int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2); - - -/** - * \brief Set the address of the current node - * \param addr The address - * - * This function sets the Rime address of the node. - * - */ -void linkaddr_set_node_addr(linkaddr_t *addr); - -linkaddr_t *linkaddr_get_node_addr(int *addr_len); - -/** - * \brief The Rime address of the node - * - * This variable contains the Rime address of the - * node. This variable should not be changed directly; - * rather, the linkaddr_set_node_addr() function should be - * used. - * - */ -extern linkaddr_t linkaddr_node_addr; - -/** - * \brief The null Rime address - * - * This variable contains the null Rime address. The null - * address is used in route tables to indicate that the - * table entry is unused. Nodes with no configured address - * has the null address. Nodes with their node address set - * to the null address will have problems communicating - * with other nodes. - * - */ -extern const linkaddr_t linkaddr_null; - -#endif /* LINKADDR_H_ */ -/** @} */ -/** @} */ diff --git a/net/ip/contiki/llsec/anti-replay.c b/net/ip/contiki/llsec/anti-replay.c deleted file mode 100644 index 0db4d6b72335e7714a52d4ba29fe88b3ac52c49f..0000000000000000000000000000000000000000 --- a/net/ip/contiki/llsec/anti-replay.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2014, Hasso-Plattner-Institut. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Protects against replay attacks by comparing with the last - * unicast or broadcast frame counter of the sender. - * \author - * Konrad Krentz - */ - -/** - * \addtogroup llsec802154 - * @{ - */ - -#include - -#include "contiki/llsec/anti-replay.h" -#include "contiki/packetbuf.h" - -/* This node's current frame counter value */ -static uint32_t counter; - -/*---------------------------------------------------------------------------*/ -void -anti_replay_set_counter(struct net_buf *buf) -{ - frame802154_frame_counter_t reordered_counter; - - reordered_counter.u32 = LLSEC802154_HTONL(++counter); - - packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, reordered_counter.u16[0]); - packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, reordered_counter.u16[1]); -} -/*---------------------------------------------------------------------------*/ -uint32_t -anti_replay_get_counter(struct net_buf *buf) -{ - frame802154_frame_counter_t disordered_counter; - - disordered_counter.u16[0] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1); - disordered_counter.u16[1] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3); - - return LLSEC802154_HTONL(disordered_counter.u32); -} -/*---------------------------------------------------------------------------*/ -void -anti_replay_init_info(struct net_buf *buf, struct anti_replay_info *info) -{ - info->last_broadcast_counter - = info->last_unicast_counter - = anti_replay_get_counter(buf); -} -/*---------------------------------------------------------------------------*/ -int -anti_replay_was_replayed(struct net_buf *buf, struct anti_replay_info *info) -{ - uint32_t received_counter; - - received_counter = anti_replay_get_counter(buf); - - if(packetbuf_holds_broadcast(buf)) { - /* broadcast */ - if(received_counter <= info->last_broadcast_counter) { - return 1; - } else { - info->last_broadcast_counter = received_counter; - return 0; - } - } else { - /* unicast */ - if(received_counter <= info->last_unicast_counter) { - return 1; - } else { - info->last_unicast_counter = received_counter; - return 0; - } - } -} -/*---------------------------------------------------------------------------*/ - -/** @} */ diff --git a/net/ip/contiki/llsec/anti-replay.h b/net/ip/contiki/llsec/anti-replay.h deleted file mode 100644 index 4300a9e95ca6e800e46c48a7e0fcfbdab05a7561..0000000000000000000000000000000000000000 --- a/net/ip/contiki/llsec/anti-replay.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2014, Hasso-Plattner-Institut. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Interface to anti-replay mechanisms. - * \author - * Konrad Krentz - */ - -/** - * \addtogroup llsec802154 - * @{ - */ - -#ifndef ANTI_REPLAY_H -#define ANTI_REPLAY_H - -#include - -#include "contiki.h" - -struct anti_replay_info { - uint32_t last_broadcast_counter; - uint32_t last_unicast_counter; -}; - -/** - * \brief Sets the frame counter packetbuf attributes. - */ -void anti_replay_set_counter(struct net_buf *buf); - -/** - * \brief Gets the frame counter from packetbuf. - */ -uint32_t anti_replay_get_counter(struct net_buf *buf); - -/** - * \brief Initializes the anti-replay information about the sender - * \param info Anti-replay information about the sender - */ -void anti_replay_init_info(struct net_buf *buf, struct anti_replay_info *info); - -/** - * \brief Checks if received frame was replayed - * \param info Anti-replay information about the sender - * \retval 0 <-> received frame was not replayed - */ -int anti_replay_was_replayed(struct net_buf *buf, struct anti_replay_info *info); - -#endif /* ANTI_REPLAY_H */ - -/** @} */ diff --git a/net/ip/contiki/llsec/ccm-star.c b/net/ip/contiki/llsec/ccm-star.c deleted file mode 100644 index 9a9ba94f4a94d9be6beaaf656e4f7e9a6d3a69aa..0000000000000000000000000000000000000000 --- a/net/ip/contiki/llsec/ccm-star.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2013, Hasso-Plattner-Institut. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * AES_128-based CCM* implementation. - * \author - * Konrad Krentz - */ - -/** - * \addtogroup llsec802154 - * @{ - */ - -#include - -#include "contiki/llsec/ccm-star.h" -#include "contiki/llsec/llsec802154.h" -#include "contiki/packetbuf.h" -#include "lib/aes-128.h" -#include - -/*---------------------------------------------------------------------------*/ -static void -set_nonce(struct net_buf *buf, uint8_t *nonce, - uint8_t flags, - const uint8_t *extended_source_address, - uint8_t counter) -{ - /* 1 byte|| 8 bytes || 4 bytes || 1 byte || 2 bytes */ - /* flags || extended_source_address || frame_counter || sec_lvl || counter */ - - nonce[0] = flags; - memcpy(nonce + 1, extended_source_address, 8); - nonce[9] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8; - nonce[10] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff; - nonce[11] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) >> 8; - nonce[12] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) & 0xff; - nonce[13] = packetbuf_attr(buf, PACKETBUF_ATTR_SECURITY_LEVEL); - nonce[14] = 0; - nonce[15] = counter; -} -/*---------------------------------------------------------------------------*/ -/* XORs the block m[pos] ... m[pos + 15] with K_{counter} */ -static void -ctr_step(struct net_buf *buf, const uint8_t *extended_source_address, - uint8_t pos, - uint8_t *m_and_result, - uint8_t m_len, - uint8_t counter) -{ - uint8_t a[AES_128_BLOCK_SIZE]; - uint8_t i; - - set_nonce(buf, a, CCM_STAR_ENCRYPTION_FLAGS, extended_source_address, counter); - AES_128.encrypt(a); - - for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) { - m_and_result[pos + i] ^= a[i]; - } -} -/*---------------------------------------------------------------------------*/ -static void -mic(struct net_buf *buf, const uint8_t *extended_source_address, - uint8_t *result, - uint8_t mic_len) -{ - uint8_t x[AES_128_BLOCK_SIZE]; - uint8_t pos; - uint8_t i; - uint8_t a_len; - uint8_t *a; -#if LLSEC802154_USES_ENCRYPTION - uint8_t shall_encrypt; - uint8_t m_len; - uint8_t *m; - - shall_encrypt = packetbuf_attr(buf, PACKETBUF_ATTR_SECURITY_LEVEL) & (1 << 2); - if(shall_encrypt) { - a_len = packetbuf_hdrlen(buf); - m_len = packetbuf_datalen(buf); - } else { - a_len = packetbuf_totlen(buf); - m_len = 0; - } - set_nonce(x, - CCM_STAR_AUTH_FLAGS(a_len, mic_len), - extended_source_address, - m_len); -#else /* LLSEC802154_USES_ENCRYPTION */ - a_len = packetbuf_totlen(buf); - set_nonce(buf, x, - CCM_STAR_AUTH_FLAGS(a_len, mic_len), - extended_source_address, - 0); -#endif /* LLSEC802154_USES_ENCRYPTION */ - AES_128.encrypt(x); - - a = packetbuf_hdrptr(buf); - if(a_len) { - x[1] = x[1] ^ a_len; - for(i = 2; (i - 2 < a_len) && (i < AES_128_BLOCK_SIZE); i++) { - x[i] ^= a[i - 2]; - } - - AES_128.encrypt(x); - - pos = 14; - while(pos < a_len) { - for(i = 0; (pos + i < a_len) && (i < AES_128_BLOCK_SIZE); i++) { - x[i] ^= a[pos + i]; - } - pos += AES_128_BLOCK_SIZE; - AES_128.encrypt(x); - } - } - -#if LLSEC802154_USES_ENCRYPTION - if(shall_encrypt) { - m = a + a_len; - pos = 0; - while(pos < m_len) { - for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) { - x[i] ^= m[pos + i]; - } - pos += AES_128_BLOCK_SIZE; - AES_128.encrypt(x); - } - } -#endif /* LLSEC802154_USES_ENCRYPTION */ - - ctr_step(buf, extended_source_address, 0, x, AES_128_BLOCK_SIZE, 0); - - memcpy(result, x, mic_len); -} -/*---------------------------------------------------------------------------*/ -static void -ctr(struct net_buf *buf, const uint8_t *extended_source_address) -{ - uint8_t m_len; - uint8_t *m; - uint8_t pos; - uint8_t counter; - - m_len = packetbuf_datalen(buf); - m = (uint8_t *) packetbuf_dataptr(buf); - - pos = 0; - counter = 1; - while(pos < m_len) { - ctr_step(buf, extended_source_address, pos, m, m_len, counter++); - pos += AES_128_BLOCK_SIZE; - } -} -/*---------------------------------------------------------------------------*/ -const struct ccm_star_driver ccm_star_driver = { - mic, - ctr -}; -/*---------------------------------------------------------------------------*/ - -/** @} */ diff --git a/net/ip/contiki/llsec/ccm-star.h b/net/ip/contiki/llsec/ccm-star.h deleted file mode 100644 index 66fc7ffab94fdad2d98fb32b99bff0b74748c0df..0000000000000000000000000000000000000000 --- a/net/ip/contiki/llsec/ccm-star.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2013, Hasso-Plattner-Institut. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * CCM* header file. - * \author - * Konrad Krentz - */ - -/** - * \addtogroup llsec802154 - * @{ - */ - -#ifndef CCM_STAR_H_ -#define CCM_STAR_H_ - -#include - -#include "contiki.h" -#include "contiki/mac/frame802154.h" - -/* see RFC 3610 */ -#define CCM_STAR_AUTH_FLAGS(Adata, M) ((Adata ? (1 << 6) : 0) | (((M - 2) >> 1) << 3) | 1) -#define CCM_STAR_ENCRYPTION_FLAGS 1 - -#ifdef CCM_STAR_CONF -#define CCM_STAR CCM_STAR_CONF -#else /* CCM_STAR_CONF */ -#define CCM_STAR ccm_star_driver -#endif /* CCM_STAR_CONF */ - -/** - * Structure of CCM* drivers. - */ -struct ccm_star_driver { - - /** - * \brief Generates a MIC over the frame in the packetbuf. - * \param result The generated MIC will be put here - * \param mic_len <= 16; set to LLSEC802154_MIC_LENGTH to be compliant - */ - void (* mic)(struct net_buf *buf, const uint8_t *extended_source_address, - uint8_t *result, - uint8_t mic_len); - - /** - * \brief XORs the frame in the packetbuf with the key stream. - */ - void (* ctr)(struct net_buf *buf, const uint8_t *extended_source_address); -}; - -extern const struct ccm_star_driver CCM_STAR; - -#endif /* CCM_STAR_H_ */ - -/** @} */ diff --git a/net/ip/contiki/llsec/llsec.h b/net/ip/contiki/llsec/llsec.h deleted file mode 100644 index 527ba04a48fb11325948faa4ca82440f7af540f9..0000000000000000000000000000000000000000 --- a/net/ip/contiki/llsec/llsec.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2013, Hasso-Plattner-Institut. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Link layer security header file. - * \author - * Konrad Krentz - */ - -/** - * \ingroup net - * \defgroup llsec Link Layer Security - * - * Layer for implementing link layer security. - * - * NETSTACK_LLSEC sits in between NETSTACK_MAC and NETSTACK_NETWORK - * protocols. All NETSTACK_MAC protocols invoke NETSTACK_LLSEC.input() - * for incoming packets. Likewise, all NETSTACK_NETWORK protocols - * invoke NETSTACK_LLSEC.send(...) for outgoing packets. - * - * The bootstrap function of llsec_drivers can be used to defer the start - * of upper layers so as to bootstrap pairwise keys. Only contiki-sky-main.c - * supports this at the moment. - * - * @{ - */ - -#include -#include -#include "contiki/mac/mac.h" - -#ifndef LLSEC_H_ -#define LLSEC_H_ - -typedef void (* llsec_on_bootstrapped_t)(void); - -/** - * The structure of a link layer security driver. - */ -struct llsec_driver { - char *name; - - /** Bootstraps link layer security and thereafter starts upper layers. */ - void (* bootstrap)(llsec_on_bootstrapped_t on_bootstrapped); - - /** Secures outgoing frames before passing them to NETSTACK_MAC. */ - uint8_t (* send)(struct net_buf *buf, mac_callback_t sent_callback, - bool last_fragment, void *ptr); - - /** - * Once the NETSTACK_FRAMER wrote the headers, the LLSEC driver - * can generate a MIC over the entire frame. - * \return Returns != 0 <-> success - */ - int (* on_frame_created)(void); - - /** - * Decrypts incoming frames; - * filters out injected or replayed frames. - */ - uint8_t (* input)(struct net_buf *buf); - - /** Returns the security-related overhead per frame in bytes */ - uint8_t (* get_overhead)(void); -}; - -#endif /* LLSEC_H_ */ - -/** @} */ diff --git a/net/ip/contiki/llsec/llsec802154.h b/net/ip/contiki/llsec/llsec802154.h deleted file mode 100644 index 66b6f9d327efba2f0b4d5bbb226faf61cc5d7a1a..0000000000000000000000000000000000000000 --- a/net/ip/contiki/llsec/llsec802154.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2013, Hasso-Plattner-Institut. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Common functionality of 802.15.4-compliant llsec_drivers. - * \author - * Konrad Krentz - */ - -/** - * \addtogroup llsec - * @{ - */ - -/** - * \defgroup llsec802154 Link Layer Security Common Functionality - * - * Common functionality of 802.15.4-compliant llsec_drivers. - * - * @{ - */ - -#ifndef LLSEC802154_H_ -#define LLSEC802154_H_ - -#include "contiki/mac/frame802154.h" -#include "contiki/ip/uip.h" - -#ifdef LLSEC802154_CONF_SECURITY_LEVEL -#define LLSEC802154_SECURITY_LEVEL LLSEC802154_CONF_SECURITY_LEVEL -#else /* LLSEC802154_CONF_SECURITY_LEVEL */ -#define LLSEC802154_SECURITY_LEVEL FRAME802154_SECURITY_LEVEL_NONE -#endif /* LLSEC802154_CONF_SECURITY_LEVEL */ - -#if ((LLSEC802154_SECURITY_LEVEL < 0) || (LLSEC802154_SECURITY_LEVEL > 7)) -#error "unsupported security level" -#endif - -#define LLSEC802154_SECURITY_LEVEL_MIC (LLSEC802154_SECURITY_LEVEL & 3) -#if LLSEC802154_SECURITY_LEVEL_MIC -#define LLSEC802154_MIC_LENGTH (2 << LLSEC802154_SECURITY_LEVEL_MIC) -#else -#define LLSEC802154_MIC_LENGTH 0 -#endif - -#ifdef LLSEC802154_CONF_USES_ENCRYPTION -#define LLSEC802154_USES_ENCRYPTION LLSEC802154_CONF_USES_ENCRYPTION -#else /* LLSEC802154_CONF_USES_ENCRYPTION */ -#define LLSEC802154_USES_ENCRYPTION (LLSEC802154_SECURITY_LEVEL & (1 << 2)) -#endif /* LLSEC802154_CONF_USES_ENCRYPTION */ - -#ifdef LLSEC802154_CONF_USES_EXPLICIT_KEYS -#define LLSEC802154_USES_EXPLICIT_KEYS LLSEC802154_CONF_USES_EXPLICIT_KEYS -#else /* LLSEC802154_CONF_USES_EXPLICIT_KEYS */ -#define LLSEC802154_USES_EXPLICIT_KEYS 0 -#endif /* LLSEC802154_CONF_USES_EXPLICIT_KEYS */ - -#if UIP_BYTE_ORDER == UIP_LITTLE_ENDIAN -#define LLSEC802154_HTONS(n) (n) -#define LLSEC802154_HTONL(n) (n) -#else /* UIP_CONF_BYTE_ORDER == UIP_LITTLE_ENDIAN */ -#define LLSEC802154_HTONS(n) (uint16_t)((((uint16_t) (n)) << 8) | (((uint16_t) (n)) >> 8)) -#define LLSEC802154_HTONL(n) (((uint32_t)UIP_HTONS(n) << 16) | UIP_HTONS((uint32_t)(n) >> 16)) -#endif /* UIP_CONF_BYTE_ORDER == UIP_LITTLE_ENDIAN */ - -#endif /* LLSEC802154_H_ */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/llsec/nullsec.c b/net/ip/contiki/llsec/nullsec.c deleted file mode 100644 index 68c245a9fa9dc732f7725c44815cfda134554d68..0000000000000000000000000000000000000000 --- a/net/ip/contiki/llsec/nullsec.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2013, Hasso-Plattner-Institut. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Insecure link layer security driver. - * \author - * Konrad Krentz - */ - -/** - * \addtogroup nullsec - * @{ - */ - -#include - -#include "contiki/llsec/nullsec.h" -#include "contiki/mac/frame802154.h" -#include "contiki/netstack.h" -#include "contiki/packetbuf.h" - -#define DEBUG 0 -#include "contiki/ip/uip-debug.h" - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif - -/*---------------------------------------------------------------------------*/ -static void -bootstrap(llsec_on_bootstrapped_t on_bootstrapped) -{ - on_bootstrapped(); -} -/*---------------------------------------------------------------------------*/ -static uint8_t -send(struct net_buf *buf, mac_callback_t sent, bool last_fragment, void *ptr) -{ - packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME); - return NETSTACK_MAC.send(buf, sent, last_fragment, ptr); -} -/*---------------------------------------------------------------------------*/ -static int -on_frame_created(void) -{ - return 1; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -input(struct net_buf *buf) -{ - return NETSTACK_FRAGMENT.reassemble(buf); -} -/*---------------------------------------------------------------------------*/ -static uint8_t -get_overhead(void) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -const struct llsec_driver nullsec_driver = { - "nullsec", - bootstrap, - send, - on_frame_created, - input, - get_overhead -}; -/*---------------------------------------------------------------------------*/ - -/** @} */ diff --git a/net/ip/contiki/llsec/nullsec.h b/net/ip/contiki/llsec/nullsec.h deleted file mode 100644 index 419ff06f0b788344f78f18da3e0e7175d9061220..0000000000000000000000000000000000000000 --- a/net/ip/contiki/llsec/nullsec.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2013, Hasso-Plattner-Institut. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Insecure link layer security driver. - * \author - * Konrad Krentz - */ - -/** - * \addtogroup llsec - * @{ - */ - -/** - * \defgroup nullsec LLSEC driver with zero security (NULLSEC) - * - * Insecure link layer security driver. - * - * @{ - */ - -#ifndef NULLSEC_H_ -#define NULLSEC_H_ - -#include "contiki/llsec/llsec.h" - -extern const struct llsec_driver nullsec_driver; - -#endif /* NULLSEC_H_ */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/mac/csma.c b/net/ip/contiki/mac/csma.c deleted file mode 100644 index e439b28bfbe40393c60ec5f2cc9f033cb50ab88a..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/csma.c +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * A Carrier Sense Multiple Access (CSMA) MAC layer - * \author - * Adam Dunkels - */ - -#include - -#include "contiki/mac/csma.h" -#include "contiki/packetbuf.h" -#include "contiki/queuebuf.h" - -#include "sys/ctimer.h" -#include "sys/clock.h" - -#include "lib/random.h" - -#include "contiki/netstack.h" - -#include "lib/list.h" -#include "lib/memb.h" - -#include - -#include - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_15_4_MAC -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif - -#ifndef CSMA_MAX_BACKOFF_EXPONENT -#ifdef CSMA_CONF_MAX_BACKOFF_EXPONENT -#define CSMA_MAX_BACKOFF_EXPONENT CSMA_CONF_MAX_BACKOFF_EXPONENT -#else -#define CSMA_MAX_BACKOFF_EXPONENT 3 -#endif /* CSMA_CONF_MAX_BACKOFF_EXPONENT */ -#endif /* CSMA_MAX_BACKOFF_EXPONENT */ - -#ifndef CSMA_MAX_MAC_TRANSMISSIONS -#ifdef CSMA_CONF_MAX_MAC_TRANSMISSIONS -#define CSMA_MAX_MAC_TRANSMISSIONS CSMA_CONF_MAX_MAC_TRANSMISSIONS -#else -#define CSMA_MAX_MAC_TRANSMISSIONS 3 -#endif /* CSMA_CONF_MAX_MAC_TRANSMISSIONS */ -#endif /* CSMA_MAX_MAC_TRANSMISSIONS */ - -#if CSMA_MAX_MAC_TRANSMISSIONS < 1 -#error CSMA_CONF_MAX_MAC_TRANSMISSIONS must be at least 1. -#error Change CSMA_CONF_MAX_MAC_TRANSMISSIONS in contiki-conf.h or in your Makefile. -#endif /* CSMA_CONF_MAX_MAC_TRANSMISSIONS < 1 */ - -/* Packet metadata */ -struct qbuf_metadata { - mac_callback_t sent; - void *cptr; - uint8_t max_transmissions; -}; - -/* Every neighbor has its own packet queue */ -struct neighbor_queue { - struct neighbor_queue *next; - linkaddr_t addr; - struct ctimer transmit_timer; - uint8_t transmissions; - uint8_t collisions, deferrals; - LIST_STRUCT(queued_packet_list); -}; - -/* The maximum number of co-existing neighbor queues */ -#ifdef CSMA_CONF_MAX_NEIGHBOR_QUEUES -#define CSMA_MAX_NEIGHBOR_QUEUES CSMA_CONF_MAX_NEIGHBOR_QUEUES -#else -#define CSMA_MAX_NEIGHBOR_QUEUES 2 -#endif /* CSMA_CONF_MAX_NEIGHBOR_QUEUES */ - -/* The maximum number of pending packet per neighbor */ -#ifdef CSMA_CONF_MAX_PACKET_PER_NEIGHBOR -#define CSMA_MAX_PACKET_PER_NEIGHBOR CSMA_CONF_MAX_PACKET_PER_NEIGHBOR -#else -#define CSMA_MAX_PACKET_PER_NEIGHBOR MAX_QUEUED_PACKETS -#endif /* CSMA_CONF_MAX_PACKET_PER_NEIGHBOR */ - -#define MAX_QUEUED_PACKETS QUEUEBUF_NUM -MEMB(neighbor_memb, struct neighbor_queue, CSMA_MAX_NEIGHBOR_QUEUES); -MEMB(packet_memb, struct rdc_buf_list, MAX_QUEUED_PACKETS); -MEMB(metadata_memb, struct qbuf_metadata, MAX_QUEUED_PACKETS); - -static void packet_sent(struct net_buf *buf, void *ptr, int status, int num_transmissions); -static void transmit_packet_list(struct net_buf *buf, void *ptr); - -/*---------------------------------------------------------------------------*/ -static struct neighbor_queue * -neighbor_queue_from_addr(struct net_buf *buf, const linkaddr_t *addr) -{ - struct neighbor_queue *n = list_head(uip_neighbor_list(buf)); - while(n != NULL) { - if(linkaddr_cmp(&n->addr, addr)) { - return n; - } - n = list_item_next(n); - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -static clock_time_t -default_timebase(void) -{ - clock_time_t time; - /* The retransmission time must be proportional to the channel - check interval of the underlying radio duty cycling layer. */ - time = NETSTACK_RDC.channel_check_interval(); - - /* If the radio duty cycle has no channel check interval (i.e., it - does not turn the radio off), we make the retransmission time - proportional to the configured MAC channel check rate. */ - if(time == 0) { - time = CLOCK_SECOND / NETSTACK_RDC_CHANNEL_CHECK_RATE; - } - return time; -} -/*---------------------------------------------------------------------------*/ -static void -free_packet(struct net_buf *buf, struct neighbor_queue *n, struct rdc_buf_list *p) -{ - if(p != NULL) { - /* Remove packet from list and deallocate */ - list_remove(n->queued_packet_list, p); - - queuebuf_free(p->buf); - memb_free(&metadata_memb, p->ptr); - memb_free(&packet_memb, p); - PRINTF("csma: free_queued_packet, queue length %d, free packets %d\n", - list_length(n->queued_packet_list), memb_numfree(&packet_memb)); - if(list_head(n->queued_packet_list) != NULL) { - /* There is a next packet. We reset current tx information */ - n->transmissions = 0; - n->collisions = 0; - n->deferrals = 0; - transmit_packet_list(buf, n); - } else { - /* This was the last packet in the queue, we free the neighbor */ - list_remove(uip_neighbor_list(buf), n); - memb_free(&neighbor_memb, n); - } - } -} -/*---------------------------------------------------------------------------*/ -static void -transmit_packet_list(struct net_buf *buf, void *ptr) -{ - struct neighbor_queue *n = ptr; - if(n) { - struct rdc_buf_list *q = list_head(n->queued_packet_list); - if(q != NULL) { - PRINTF("csma: preparing number %d %p, queue len %d\n", n->transmissions, q, - list_length(n->queued_packet_list)); - /* Send packets in the neighbor's list */ - NETSTACK_RDC.send_list(buf, packet_sent, n, q); - } - } -} -/*---------------------------------------------------------------------------*/ -static void -packet_sent(struct net_buf *buf, void *ptr, int status, int num_transmissions) -{ - struct neighbor_queue *n; - struct rdc_buf_list *q; - struct qbuf_metadata *metadata; - clock_time_t time = 0; - mac_callback_t sent; - void *cptr; - int num_tx; - int backoff_exponent; - int backoff_transmissions; - - n = ptr; - if(n == NULL) { - return; - } - switch(status) { - case MAC_TX_OK: - case MAC_TX_NOACK: - n->transmissions += num_transmissions; - break; - case MAC_TX_COLLISION: - n->collisions += num_transmissions; - n->transmissions += num_transmissions; - break; - case MAC_TX_DEFERRED: - n->deferrals += num_transmissions; - break; - } - - /* Find out what packet this callback refers to */ - for(q = list_head(n->queued_packet_list); - q != NULL; q = list_item_next(q)) { - if(queuebuf_attr(q->buf, PACKETBUF_ATTR_MAC_SEQNO) == - packetbuf_attr(buf, PACKETBUF_ATTR_MAC_SEQNO)) { - break; - } - } - - if(q != NULL) { - metadata = (struct qbuf_metadata *)q->ptr; - - if(metadata != NULL) { - sent = metadata->sent; - cptr = metadata->cptr; - num_tx = n->transmissions; - if(status == MAC_TX_COLLISION || - status == MAC_TX_NOACK) { - - /* If the transmission was not performed because of a - collision or noack, we must retransmit the packet. */ - - switch(status) { - case MAC_TX_COLLISION: - PRINTF("csma: rexmit collision %d transmission %d\n", - n->collisions, n->transmissions); - break; - case MAC_TX_NOACK: - PRINTF("csma: rexmit noack %d\n", n->transmissions); - break; - default: - PRINTF("csma: rexmit err %d, %d\n", status, n->transmissions); - } - - /* The retransmission time must be proportional to the channel - check interval of the underlying radio duty cycling layer. */ - time = default_timebase(); - - /* The retransmission time uses a truncated exponential backoff - * so that the interval between the transmissions increase with - * each retransmit. */ - backoff_exponent = num_tx; - - /* Truncate the exponent if needed. */ - if(backoff_exponent > CSMA_MAX_BACKOFF_EXPONENT) { - backoff_exponent = CSMA_MAX_BACKOFF_EXPONENT; - } - - /* Proceed to exponentiation. */ - backoff_transmissions = 1 << backoff_exponent; - - /* Pick a time for next transmission, within the interval: - * [time, time + 2^backoff_exponent * time[ */ - time = time + (random_rand() % (backoff_transmissions * time)); - - if(n->transmissions < metadata->max_transmissions) { - PRINTF("csma: retransmitting with time %lu %p\n", time, q); - ctimer_set(buf, &n->transmit_timer, time, - transmit_packet_list, n); - /* This is needed to correctly attribute energy that we spent - transmitting this packet. */ - queuebuf_update_attr_from_packetbuf(buf, q->buf); - } else { - PRINTF("csma: drop with status %d after %d transmissions, %d collisions\n", - status, n->transmissions, n->collisions); - free_packet(buf, n, q); - mac_call_sent_callback(buf, sent, cptr, status, num_tx); - } - } else { - if(status == MAC_TX_OK) { - PRINTF("csma: rexmit ok %d\n", n->transmissions); - } else { - PRINTF("csma: rexmit failed %d: %d\n", n->transmissions, status); - } - free_packet(buf, n, q); - mac_call_sent_callback(buf, sent, cptr, status, num_tx); - } - } else { - PRINTF("csma: no metadata\n"); - } - } else { - PRINTF("csma: seqno %d not found\n", packetbuf_attr(buf, PACKETBUF_ATTR_MAC_SEQNO)); - } -} -/*---------------------------------------------------------------------------*/ -static uint8_t -send_packet(struct net_buf *buf, mac_callback_t sent, bool last_fragment, void *ptr) -{ - struct rdc_buf_list *q; - struct neighbor_queue *n; - static uint8_t initialized = 0; - static uint16_t seqno; - const linkaddr_t *addr = packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER); - - if (!buf) { - UIP_LOG("csma: send_packet(): net_buf is NULL, cannot send packet"); - return 0; - } - - if(!initialized) { - initialized = 1; - /* Initialize the sequence number to a random value as per 802.15.4. */ - seqno = random_rand(); - } - - if(seqno == 0) { - /* PACKETBUF_ATTR_MAC_SEQNO cannot be zero, due to a pecuilarity - in framer-802154.c. */ - seqno++; - } - packetbuf_set_attr(buf, PACKETBUF_ATTR_MAC_SEQNO, seqno++); - - /* Look for the neighbor entry */ - n = neighbor_queue_from_addr(buf, addr); - if(n == NULL) { - /* Allocate a new neighbor entry */ - n = memb_alloc(&neighbor_memb); - if(n != NULL) { - /* Init neighbor entry */ - linkaddr_copy(&n->addr, addr); - n->transmissions = 0; - n->collisions = 0; - n->deferrals = 0; - /* Init packet list for this neighbor */ - LIST_STRUCT_INIT(n, queued_packet_list); - /* Add neighbor to the list */ - list_add(uip_neighbor_list(buf), n); - } - } - - if(n != NULL) { - /* Add packet to the neighbor's queue */ - if(list_length(n->queued_packet_list) < CSMA_MAX_PACKET_PER_NEIGHBOR) { - q = memb_alloc(&packet_memb); - if(q != NULL) { - q->ptr = memb_alloc(&metadata_memb); - if(q->ptr != NULL) { - q->buf = queuebuf_new_from_packetbuf(buf); - if(q->buf != NULL) { - struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr; - /* Neighbor and packet successfully allocated */ - if(packetbuf_attr(buf, PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS) == 0) { - /* Use default configuration for max transmissions */ - metadata->max_transmissions = CSMA_MAX_MAC_TRANSMISSIONS; - } else { - metadata->max_transmissions = - packetbuf_attr(buf, PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS); - } - metadata->sent = sent; - metadata->cptr = ptr; - - if(packetbuf_attr(buf, PACKETBUF_ATTR_PACKET_TYPE) == - PACKETBUF_ATTR_PACKET_TYPE_ACK) { - list_push(n->queued_packet_list, q); - } else { - list_add(n->queued_packet_list, q); - } - - PRINTF("csma: send_packet, queue length %d, free packets %d\n", - list_length(n->queued_packet_list), memb_numfree(&packet_memb)); - /* if received packet is last fragment/only one packet start sending - * packets in list, do not start any timer.*/ - if (last_fragment) { - transmit_packet_list(buf, n); - } - return 1; - } - memb_free(&metadata_memb, q->ptr); - PRINTF("csma: could not allocate queuebuf, dropping packet\n"); - } - memb_free(&packet_memb, q); - PRINTF("csma: could not allocate queuebuf, dropping packet\n"); - } - /* The packet allocation failed. Remove and free neighbor entry if empty. */ - if(list_length(n->queued_packet_list) == 0) { - list_remove(uip_neighbor_list(buf), n); - memb_free(&neighbor_memb, n); - } - } else { - PRINTF("csma: Neighbor queue full\n"); - } - PRINTF("csma: could not allocate packet, dropping packet\n"); - } else { - PRINTF("csma: could not allocate neighbor, dropping packet\n"); - } - mac_call_sent_callback(buf, sent, ptr, MAC_TX_ERR, 1); - return 0; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -input_packet(struct net_buf *buf) -{ - return NETSTACK_LLSEC.input(buf); -} -/*---------------------------------------------------------------------------*/ -static int -on(void) -{ - return NETSTACK_RDC.on(); -} -/*---------------------------------------------------------------------------*/ -static int -off(int keep_radio_on) -{ - return NETSTACK_RDC.off(keep_radio_on); -} -/*---------------------------------------------------------------------------*/ -static unsigned short -channel_check_interval(void) -{ - if(NETSTACK_RDC.channel_check_interval) { - return NETSTACK_RDC.channel_check_interval(); - } - return 0; -} -/*---------------------------------------------------------------------------*/ -static void -init(void) -{ - queuebuf_init(); - - memb_init(&packet_memb); - memb_init(&metadata_memb); - memb_init(&neighbor_memb); -} -/*---------------------------------------------------------------------------*/ -const struct mac_driver csma_driver = { - "CSMA", - init, - send_packet, - input_packet, - on, - off, - channel_check_interval, -}; -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/mac/csma.h b/net/ip/contiki/mac/csma.h deleted file mode 100644 index c2f06eb6ba96f8aeb0eb522d51eaa42977283211..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/csma.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * A MAC stack protocol that performs retransmissions when the - * underlying MAC layer has problems with collisions - * \author - * Adam Dunkels - */ - -#ifndef CSMA_H_ -#define CSMA_H_ - -#include "contiki/mac/mac.h" -#include "dev/radio.h" - -extern const struct mac_driver csma_driver; - -const struct mac_driver *csma_init(const struct mac_driver *r); - -#endif /* CSMA_H_ */ diff --git a/net/ip/contiki/mac/frame802154.c b/net/ip/contiki/mac/frame802154.c deleted file mode 100644 index e3ebe2e62f642929d2e38c88bc0110fd70a043b4..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/frame802154.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * - * Copyright (c) 2008, Swedish Institute of Computer Science - * All rights reserved. - * - * Additional fixes for AVR contributed by: - * - * Colin O'Flynn coflynn@newae.com - * Eric Gnoske egnoske@gmail.com - * Blake Leverett bleverett@gmail.com - * Mike Vidales mavida404@gmail.com - * Kevin Brown kbrown3@uccs.edu - * Nate Bohlmann nate@elfwerks.com - * - * Additional fixes for MSP430 contributed by: - * Joakim Eriksson - * Niclas Finne - * Nicolas Tsiftes - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ -/* - * \brief This file is where the main functions that relate to frame - * manipulation will reside. - */ - -/** - * \file - * \brief 802.15.4 frame creation and parsing functions - * - * This file converts to and from a structure to a packed 802.15.4 - * frame. - */ - -/** - * \addtogroup frame802154 - * @{ - */ - -#include "sys/cc.h" -#include "contiki/mac/frame802154.h" -#include "contiki/llsec/llsec802154.h" -#include "contiki/linkaddr.h" -#include - -/** - * \brief Structure that contains the lengths of the various addressing and security fields - * in the 802.15.4 header. This structure is used in \ref frame802154_create() - */ -typedef struct { - uint8_t dest_pid_len; /**< Length (in bytes) of destination PAN ID field */ - uint8_t dest_addr_len; /**< Length (in bytes) of destination address field */ - uint8_t src_pid_len; /**< Length (in bytes) of source PAN ID field */ - uint8_t src_addr_len; /**< Length (in bytes) of source address field */ - uint8_t aux_sec_len; /**< Length (in bytes) of aux security header field */ -} field_length_t; - -/*----------------------------------------------------------------------------*/ -CC_INLINE static uint8_t -addr_len(uint8_t mode) -{ - switch(mode) { - case FRAME802154_SHORTADDRMODE: /* 16-bit address */ - return 2; - case FRAME802154_LONGADDRMODE: /* 64-bit address */ - return 8; - default: - return 0; - } -} -/*----------------------------------------------------------------------------*/ -#if LLSEC802154_USES_EXPLICIT_KEYS -static uint8_t -get_key_id_len(uint8_t key_id_mode) -{ - switch(key_id_mode) { - case FRAME802154_1_BYTE_KEY_ID_MODE: - return 1; - case FRAME802154_5_BYTE_KEY_ID_MODE: - return 5; - case FRAME802154_9_BYTE_KEY_ID_MODE: - return 9; - default: - return 0; - } -} -#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ -/*----------------------------------------------------------------------------*/ -static void -field_len(frame802154_t *p, field_length_t *flen) -{ - /* init flen to zeros */ - memset(flen, 0, sizeof(field_length_t)); - - /* Determine lengths of each field based on fcf and other args */ - if(p->fcf.dest_addr_mode & 3) { - flen->dest_pid_len = 2; - } - if(p->fcf.src_addr_mode & 3) { - flen->src_pid_len = 2; - } - - /* Set PAN ID compression bit if src pan id matches dest pan id. */ - if(p->fcf.dest_addr_mode & 3 && p->fcf.src_addr_mode & 3 && - p->src_pid == p->dest_pid) { - p->fcf.panid_compression = 1; - - /* compressed header, only do dest pid */ - flen->src_pid_len = 0; - } else { - p->fcf.panid_compression = 0; - } - - /* determine address lengths */ - flen->dest_addr_len = addr_len(p->fcf.dest_addr_mode & 3); - flen->src_addr_len = addr_len(p->fcf.src_addr_mode & 3); - -#if LLSEC802154_SECURITY_LEVEL - /* Aux security header */ - if(p->fcf.security_enabled & 1) { - flen->aux_sec_len = 5 -#if LLSEC802154_USES_EXPLICIT_KEYS - + get_key_id_len(p->aux_hdr.security_control.key_id_mode); -#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ - ; - } -#endif /* LLSEC802154_SECURITY_LEVEL */ -} -/*----------------------------------------------------------------------------*/ -/** - * \brief Calculates the length of the frame header. This function is - * meant to be called by a higher level function, that interfaces to a MAC. - * - * \param p Pointer to frame802154_t_t struct, which specifies the - * frame to send. - * - * \return The length of the frame header. - */ -int -frame802154_hdrlen(frame802154_t *p) -{ - field_length_t flen; - field_len(p, &flen); - return 3 + flen.dest_pid_len + flen.dest_addr_len + - flen.src_pid_len + flen.src_addr_len + flen.aux_sec_len; -} -/*----------------------------------------------------------------------------*/ -/** - * \brief Creates a frame for transmission over the air. This function is - * meant to be called by a higher level function, that interfaces to a MAC. - * - * \param p Pointer to frame802154_t struct, which specifies the - * frame to send. - * - * \param buf Pointer to the buffer to use for the frame. - * - * \param buf_len The length of the buffer to use for the frame. - * - * \return The length of the frame header or 0 if there was - * insufficient space in the buffer for the frame headers. -*/ -int -frame802154_create(frame802154_t *p, uint8_t *buf, int buf_len) -{ - int c; - field_length_t flen; - uint8_t pos; -#if LLSEC802154_USES_EXPLICIT_KEYS - uint8_t key_id_mode; -#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ - - field_len(p, &flen); - - if(3 + flen.dest_pid_len + flen.dest_addr_len + - flen.src_pid_len + flen.src_addr_len + flen.aux_sec_len > buf_len) { - /* Too little space for headers. */ - return 0; - } - - /* OK, now we have field lengths. Time to actually construct */ - /* the outgoing frame, and store it in buf */ - buf[0] = (p->fcf.frame_type & 7) | - ((p->fcf.security_enabled & 1) << 3) | - ((p->fcf.frame_pending & 1) << 4) | - ((p->fcf.ack_required & 1) << 5) | - ((p->fcf.panid_compression & 1) << 6); - buf[1] = ((p->fcf.dest_addr_mode & 3) << 2) | - ((p->fcf.frame_version & 3) << 4) | - ((p->fcf.src_addr_mode & 3) << 6); - - /* sequence number */ - buf[2] = p->seq; - pos = 3; - - /* Destination PAN ID */ - if(flen.dest_pid_len == 2) { - buf[pos++] = p->dest_pid & 0xff; - buf[pos++] = (p->dest_pid >> 8) & 0xff; - } - - /* Destination address */ - for(c = flen.dest_addr_len; c > 0; c--) { - buf[pos++] = p->dest_addr[c - 1]; - } - - /* Source PAN ID */ - if(flen.src_pid_len == 2) { - buf[pos++] = p->src_pid & 0xff; - buf[pos++] = (p->src_pid >> 8) & 0xff; - } - - /* Source address */ - for(c = flen.src_addr_len; c > 0; c--) { - buf[pos++] = p->src_addr[c - 1]; - } - -#if LLSEC802154_SECURITY_LEVEL - /* Aux header */ - if(flen.aux_sec_len) { - buf[pos++] = p->aux_hdr.security_control.security_level -#if LLSEC802154_USES_EXPLICIT_KEYS - | (p->aux_hdr.security_control.key_id_mode << 3) -#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ - ; - memcpy(buf + pos, p->aux_hdr.frame_counter.u8, 4); - pos += 4; - -#if LLSEC802154_USES_EXPLICIT_KEYS - key_id_mode = p->aux_hdr.security_control.key_id_mode; - if(key_id_mode) { - c = (key_id_mode - 1) * 4; - memcpy(buf + pos, p->aux_hdr.key_source.u8, c); - pos += c; - buf[pos++] = p->aux_hdr.key_index; - } -#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ - } -#endif /* LLSEC802154_SECURITY_LEVEL */ - - return (int)pos; -} -/*----------------------------------------------------------------------------*/ -/** - * \brief Parses an input frame. Scans the input frame to find each - * section, and stores the information of each section in a - * frame802154_t structure. - * - * \param data The input data from the radio chip. - * \param len The size of the input data - * \param pf The frame802154_t struct to store the parsed frame information. - */ -int -frame802154_parse(uint8_t *data, int len, frame802154_t *pf) -{ - uint8_t *p; - frame802154_fcf_t fcf; - int c; -#if LLSEC802154_USES_EXPLICIT_KEYS - uint8_t key_id_mode; -#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ - - if(len < 3) { - return 0; - } - - p = data; - - /* decode the FCF */ - fcf.frame_type = p[0] & 7; - fcf.security_enabled = (p[0] >> 3) & 1; - fcf.frame_pending = (p[0] >> 4) & 1; - fcf.ack_required = (p[0] >> 5) & 1; - fcf.panid_compression = (p[0] >> 6) & 1; - - fcf.dest_addr_mode = (p[1] >> 2) & 3; - fcf.frame_version = (p[1] >> 4) & 3; - fcf.src_addr_mode = (p[1] >> 6) & 3; - - /* copy fcf and seqNum */ - memcpy(&pf->fcf, &fcf, sizeof(frame802154_fcf_t)); - pf->seq = p[2]; - p += 3; /* Skip first three bytes */ - - /* Destination address, if any */ - if(fcf.dest_addr_mode) { - /* Destination PAN */ - pf->dest_pid = p[0] + (p[1] << 8); - p += 2; - - /* Destination address */ -/* l = addr_len(fcf.dest_addr_mode); */ -/* for(c = 0; c < l; c++) { */ -/* pf->dest_addr.u8[c] = p[l - c - 1]; */ -/* } */ -/* p += l; */ - if(fcf.dest_addr_mode == FRAME802154_SHORTADDRMODE) { - linkaddr_copy((linkaddr_t *)&(pf->dest_addr), &linkaddr_null); - pf->dest_addr[0] = p[1]; - pf->dest_addr[1] = p[0]; - p += 2; - } else if(fcf.dest_addr_mode == FRAME802154_LONGADDRMODE) { - for(c = 0; c < 8; c++) { - pf->dest_addr[c] = p[7 - c]; - } - p += 8; - } - } else { - linkaddr_copy((linkaddr_t *)&(pf->dest_addr), &linkaddr_null); - pf->dest_pid = 0; - } - - /* Source address, if any */ - if(fcf.src_addr_mode) { - /* Source PAN */ - if(!fcf.panid_compression) { - pf->src_pid = p[0] + (p[1] << 8); - p += 2; - } else { - pf->src_pid = pf->dest_pid; - } - - /* Source address */ -/* l = addr_len(fcf.src_addr_mode); */ -/* for(c = 0; c < l; c++) { */ -/* pf->src_addr.u8[c] = p[l - c - 1]; */ -/* } */ -/* p += l; */ - if(fcf.src_addr_mode == FRAME802154_SHORTADDRMODE) { - linkaddr_copy((linkaddr_t *)&(pf->src_addr), &linkaddr_null); - pf->src_addr[0] = p[1]; - pf->src_addr[1] = p[0]; - p += 2; - } else if(fcf.src_addr_mode == FRAME802154_LONGADDRMODE) { - for(c = 0; c < 8; c++) { - pf->src_addr[c] = p[7 - c]; - } - p += 8; - } - } else { - linkaddr_copy((linkaddr_t *)&(pf->src_addr), &linkaddr_null); - pf->src_pid = 0; - } - -#if LLSEC802154_SECURITY_LEVEL - if(fcf.security_enabled) { - pf->aux_hdr.security_control.security_level = p[0] & 7; -#if LLSEC802154_USES_EXPLICIT_KEYS - pf->aux_hdr.security_control.key_id_mode = (p[0] >> 3) & 3; -#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ - p += 1; - - memcpy(pf->aux_hdr.frame_counter.u8, p, 4); - p += 4; - -#if LLSEC802154_USES_EXPLICIT_KEYS - key_id_mode = pf->aux_hdr.security_control.key_id_mode; - if(key_id_mode) { - c = (key_id_mode - 1) * 4; - memcpy(pf->aux_hdr.key_source.u8, p, c); - p += c; - pf->aux_hdr.key_index = p[0]; - p += 1; - } -#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ - } -#endif /* LLSEC802154_SECURITY_LEVEL */ - - /* header length */ - c = p - data; - /* payload length */ - pf->payload_len = (len - c); - /* payload */ - pf->payload = p; - - /* return header length if successful */ - return c > len ? 0 : c; -} -/** \} */ diff --git a/net/ip/contiki/mac/frame802154.h b/net/ip/contiki/mac/frame802154.h deleted file mode 100644 index cb08ed26cd708801d72d1f8e256331a19d5c9eb6..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/frame802154.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2008, Swedish Institute of Computer Science - * All rights reserved. - * - * Additional fixes for AVR contributed by: - * Colin O'Flynn coflynn@newae.com - * Eric Gnoske egnoske@gmail.com - * Blake Leverett bleverett@gmail.com - * Mike Vidales mavida404@gmail.com - * Kevin Brown kbrown3@uccs.edu - * Nate Bohlmann nate@elfwerks.com - * - * Additional fixes for MSP430 contributed by: - * Joakim Eriksson - * Niclas Finne - * Nicolas Tsiftes - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \addtogroup net - * @{ - */ - -/** - * \defgroup frame802154 802.15.4 frame creation and parsing - * @{ - */ -/** - * \file - * \brief 802.15.4 frame creation and parsing functions - * - * This file converts to and from a structure to a packed 802.15.4 - * frame. - * - */ - - -/* Includes */ -#ifndef FRAME_802154_H -#define FRAME_802154_H - -#include "contiki-conf.h" - -#ifdef IEEE802154_CONF_PANID -#define IEEE802154_PANID IEEE802154_CONF_PANID -#else /* IEEE802154_CONF_PANID */ -#define IEEE802154_PANID 0xABCD -#endif /* IEEE802154_CONF_PANID */ - -/* Macros & Defines */ - -/** \brief These are some definitions of values used in the FCF. See the 802.15.4 spec for details. - * \name FCF element values definitions - * @{ - */ -#define FRAME802154_BEACONFRAME (0x00) -#define FRAME802154_DATAFRAME (0x01) -#define FRAME802154_ACKFRAME (0x02) -#define FRAME802154_CMDFRAME (0x03) - -#define FRAME802154_BEACONREQ (0x07) - -#define FRAME802154_IEEERESERVED (0x00) -#define FRAME802154_NOADDR (0x00) /**< Only valid for ACK or Beacon frames. */ -#define FRAME802154_SHORTADDRMODE (0x02) -#define FRAME802154_LONGADDRMODE (0x03) - -#define FRAME802154_NOBEACONS (0x0F) - -#define FRAME802154_BROADCASTADDR (0xFFFF) -#define FRAME802154_BROADCASTPANDID (0xFFFF) - -#define FRAME802154_IEEE802154_2003 (0x00) -#define FRAME802154_IEEE802154_2006 (0x01) - -#define FRAME802154_SECURITY_LEVEL_NONE (0) -#define FRAME802154_SECURITY_LEVEL_MIC_32 (1) -#define FRAME802154_SECURITY_LEVEL_MIC_64 (2) -#define FRAME802154_SECURITY_LEVEL_MIC_128 (3) -#define FRAME802154_SECURITY_LEVEL_ENC (4) -#define FRAME802154_SECURITY_LEVEL_ENC_MIC_32 (5) -#define FRAME802154_SECURITY_LEVEL_ENC_MIC_64 (6) -#define FRAME802154_SECURITY_LEVEL_ENC_MIC_128 (7) - -#define FRAME802154_IMPLICIT_KEY (0) -#define FRAME802154_1_BYTE_KEY_ID_MODE (1) -#define FRAME802154_5_BYTE_KEY_ID_MODE (2) -#define FRAME802154_9_BYTE_KEY_ID_MODE (3) - -/** - * @brief The IEEE 802.15.4 frame has a number of constant/fixed fields that - * can be counted to make frame construction and max payload - * calculations easier. - * - * These include: - * 1. FCF - 2 bytes - Fixed - * 2. Sequence number - 1 byte - Fixed - * 3. Addressing fields - 4 - 20 bytes - Variable - * 4. Aux security header - 0 - 14 bytes - Variable - * 5. CRC - 2 bytes - Fixed - */ - -/** - * \brief Defines the bitfields of the frame control field (FCF). - */ -typedef struct { - uint8_t frame_type; /**< 3 bit. Frame type field, see 802.15.4 */ - uint8_t security_enabled; /**< 1 bit. True if security is used in this frame */ - uint8_t frame_pending; /**< 1 bit. True if sender has more data to send */ - uint8_t ack_required; /**< 1 bit. Is an ack frame required? */ - uint8_t panid_compression; /**< 1 bit. Is this a compressed header? */ - /* uint8_t reserved; */ /**< 3 bit. Unused bits */ - uint8_t dest_addr_mode; /**< 2 bit. Destination address mode, see 802.15.4 */ - uint8_t frame_version; /**< 2 bit. 802.15.4 frame version */ - uint8_t src_addr_mode; /**< 2 bit. Source address mode, see 802.15.4 */ -} frame802154_fcf_t; - -/** \brief 802.15.4 security control bitfield. See section 7.6.2.2.1 in 802.15.4 specification */ -typedef struct { - uint8_t security_level; /**< 3 bit. security level */ - uint8_t key_id_mode; /**< 2 bit. Key identifier mode */ - uint8_t reserved; /**< 3 bit. Reserved bits */ -} frame802154_scf_t; - -typedef union { - uint32_t u32; - uint16_t u16[2]; - uint8_t u8[4]; -} frame802154_frame_counter_t; - -typedef union { - uint16_t u16[4]; - uint8_t u8[8]; -} frame802154_key_source_t; - -/** \brief 802.15.4 Aux security header */ -typedef struct { - frame802154_scf_t security_control; /**< Security control bitfield */ - frame802154_frame_counter_t frame_counter; /**< Frame counter, used for security */ - frame802154_key_source_t key_source; /**< Key Source subfield */ - uint8_t key_index; /**< Key Index subfield */ -} frame802154_aux_hdr_t; - -/** \brief Parameters used by the frame802154_create() function. These - * parameters are used in the 802.15.4 frame header. See the 802.15.4 - * specification for details. - */ -typedef struct { - /* The fields dest_addr and src_addr must come first to ensure they are aligned to the - * CPU word size. Needed as they are accessed directly as linkaddr_t*. Note we cannot use - * the type linkaddr_t directly here, as we always need 8 bytes, not LINKADDR_SIZE bytes. */ - uint8_t dest_addr[8]; /**< Destination address */ - uint8_t src_addr[8]; /**< Source address */ - frame802154_fcf_t fcf; /**< Frame control field */ - uint8_t seq; /**< Sequence number */ - uint16_t dest_pid; /**< Destination PAN ID */ - uint16_t src_pid; /**< Source PAN ID */ - frame802154_aux_hdr_t aux_hdr; /**< Aux security header */ - uint8_t *payload; /**< Pointer to 802.15.4 payload */ - int payload_len; /**< Length of payload field */ -} frame802154_t; - -/* Prototypes */ - -int frame802154_hdrlen(frame802154_t *p); -int frame802154_create(frame802154_t *p, uint8_t *buf, int buf_len); -int frame802154_parse(uint8_t *data, int length, frame802154_t *pf); - -/** @} */ -#endif /* FRAME_802154_H */ -/** @} */ -/** @} */ diff --git a/net/ip/contiki/mac/framer-802154.c b/net/ip/contiki/mac/framer-802154.c deleted file mode 100644 index 18931c67bf57a45a7018d23f28d187fa947b0050..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/framer-802154.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (c) 2009, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -/** - * \file - * MAC framer for IEEE 802.15.4 - * \author - * Niclas Finne - * Joakim Eriksson - */ - -#include - -#include "contiki/mac/framer-802154.h" -#include "contiki/mac/frame802154.h" -#include "contiki/llsec/llsec802154.h" -#include "contiki/packetbuf.h" -#include "lib/random.h" -#include - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_15_4_FRAMING -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -/** \brief The 16-bit identifier of the PAN on which the device is - * sending to. If this value is 0xffff, the device is not - * associated. - */ -static uint16_t mac_dst_pan_id = IEEE802154_PANID; - -/** \brief The 16-bit identifier of the PAN on which the device is - * operating. If this value is 0xffff, the device is not - * associated. - */ -static uint16_t mac_src_pan_id = IEEE802154_PANID; - -#ifdef FRAMER_802154_HANDLER -int FRAMER_802154_HANDLER(frame802154_t *frame); -#endif - -/** \brief The sequence number (0x00 - 0xff) added to the transmitted - * data or MAC command frame. The default is a random value within - * the range. - */ -uint8_t -framer_802154_next_seqno(void) -{ - static uint8_t mac_dsn; - static uint8_t initialized = 0; - if(!initialized) { - initialized = 1; - mac_dsn = random_rand() & 0xff; - } - /* Ensure that the sequence number 0 is not used as it would bypass the PACKETBUF_PARAM_MAC_SEQNO check. */ - if(mac_dsn == 0) { - mac_dsn++; - } - return mac_dsn++; -} -/*---------------------------------------------------------------------------*/ -uint16_t -framer_802154_get_pan_id(void) -{ - return mac_src_pan_id; -} -/*---------------------------------------------------------------------------*/ -void -framer_802154_set_pan_id(uint16_t pan) -{ - mac_dst_pan_id = pan; - mac_src_pan_id = pan; -} -/*---------------------------------------------------------------------------*/ -static int -is_broadcast_addr(uint8_t mode, uint8_t *addr) -{ - int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8; - while(i-- > 0) { - if(addr[i] != 0xff) { - return 0; - } - } - return 1; -} -/*---------------------------------------------------------------------------*/ -static int -create_frame(struct net_buf *buf, int do_create) -{ - frame802154_t params; - int hdr_len; - - /* init to zeros */ - memset(¶ms, 0, sizeof(params)); - - /* Build the FCF. */ - params.fcf.frame_type = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_TYPE); - params.fcf.frame_pending = packetbuf_attr(buf, PACKETBUF_ATTR_PENDING); - if(packetbuf_holds_broadcast(buf)) { - params.fcf.ack_required = 0; - } else { - params.fcf.ack_required = packetbuf_attr(buf, PACKETBUF_ATTR_MAC_ACK); - } - params.fcf.panid_compression = 0; - - /* Insert IEEE 802.15.4 (2006) version bits. */ - params.fcf.frame_version = FRAME802154_IEEE802154_2006; - -#if LLSEC802154_SECURITY_LEVEL - if(packetbuf_attr(buf, PACKETBUF_ATTR_SECURITY_LEVEL)) { - params.fcf.security_enabled = 1; - } - /* Setting security-related attributes */ - params.aux_hdr.security_control.security_level = packetbuf_attr(buf, PACKETBUF_ATTR_SECURITY_LEVEL); - params.aux_hdr.frame_counter.u16[0] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1); - params.aux_hdr.frame_counter.u16[1] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3); -#if LLSEC802154_USES_EXPLICIT_KEYS - params.aux_hdr.security_control.key_id_mode = packetbuf_attr(buf, PACKETBUF_ATTR_KEY_ID_MODE); - params.aux_hdr.key_index = packetbuf_attr(buf, PACKETBUF_ATTR_KEY_INDEX); - params.aux_hdr.key_source.u16[0] = packetbuf_attr(buf, PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1); -#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ -#endif /* LLSEC802154_SECURITY_LEVEL */ - - /* Increment and set the data sequence number. */ - if(!do_create) { - /* Only length calculation - no sequence number is needed and - should not be consumed. */ - - } else if(packetbuf_attr(buf, PACKETBUF_ATTR_MAC_SEQNO)) { - params.seq = packetbuf_attr(buf, PACKETBUF_ATTR_MAC_SEQNO); - - } else { - params.seq = framer_802154_next_seqno(); - packetbuf_set_attr(buf, PACKETBUF_ATTR_MAC_SEQNO, params.seq); - } - - /* Complete the addressing fields. */ - /** - \todo For phase 1 the addresses are all long. We'll need a mechanism - in the rime attributes to tell the mac to use long or short for phase 2. - */ - if(LINKADDR_SIZE == 2) { - /* Use short address mode if linkaddr size is short. */ - params.fcf.src_addr_mode = FRAME802154_SHORTADDRMODE; - } else { - params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE; - } - params.dest_pid = mac_dst_pan_id; - - if(packetbuf_holds_broadcast(buf)) { - /* Broadcast requires short address mode. */ - params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; - params.dest_addr[0] = 0xFF; - params.dest_addr[1] = 0xFF; - - } else { - linkaddr_copy((linkaddr_t *)¶ms.dest_addr, - packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER)); - /* Use short address mode if linkaddr size is small */ - if(LINKADDR_SIZE == 2) { - params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; - } else { - params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE; - } - } - - /* Set the source PAN ID to the global variable. */ - params.src_pid = mac_src_pan_id; - - /* - * Set up the source address using only the long address mode for - * phase 1. - */ - linkaddr_copy((linkaddr_t *)¶ms.src_addr, &linkaddr_node_addr); - - params.payload = packetbuf_dataptr(buf); - params.payload_len = packetbuf_datalen(buf); - hdr_len = frame802154_hdrlen(¶ms); - if(!do_create) { - /* Only calculate header length */ - return hdr_len; - - } else if(packetbuf_hdralloc(buf, hdr_len)) { - frame802154_create(¶ms, packetbuf_hdrptr(buf), hdr_len); - - PRINTF("15.4-OUT: %2X ", params.fcf.frame_type); - PRINTLLADDR((const uip_lladdr_t *)params.dest_addr); - PRINTF(" %d %u (%u)\n", hdr_len, packetbuf_datalen(buf), packetbuf_totlen(buf)); - - return hdr_len; - } else { - PRINTF("15.4-OUT: too large header: %u\n", hdr_len); - return FRAMER_FAILED; - } -} -/*---------------------------------------------------------------------------*/ -static int -hdr_length(struct net_buf *buf) -{ - return create_frame(buf, 0); -} -/*---------------------------------------------------------------------------*/ -static int -create(struct net_buf *buf) -{ - return create_frame(buf, 1); -} -/*---------------------------------------------------------------------------*/ -static int -parse(struct net_buf *buf) -{ - frame802154_t frame; - int hdr_len; - - hdr_len = frame802154_parse(packetbuf_dataptr(buf), packetbuf_datalen(buf), &frame); - - if(hdr_len && packetbuf_hdrreduce(buf, hdr_len)) { - packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_TYPE, frame.fcf.frame_type); - - if(frame.fcf.dest_addr_mode) { - if(frame.dest_pid != mac_src_pan_id && - frame.dest_pid != FRAME802154_BROADCASTPANDID) { - /* Packet to another PAN */ - PRINTF("15.4: for another pan %u (0x%x)\n", frame.dest_pid, - frame.dest_pid); - return FRAMER_FAILED; - } - if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { - packetbuf_set_addr(buf, PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr); - } - } - packetbuf_set_addr(buf, PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr); - packetbuf_set_attr(buf, PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending); - /* packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, frame.fcf.ack_required);*/ - packetbuf_set_attr(buf, PACKETBUF_ATTR_PACKET_ID, frame.seq); - -#if LLSEC802154_SECURITY_LEVEL - if(frame.fcf.security_enabled) { - packetbuf_set_attr(buf, PACKETBUF_ATTR_SECURITY_LEVEL, frame.aux_hdr.security_control.security_level); - packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, frame.aux_hdr.frame_counter.u16[0]); - packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, frame.aux_hdr.frame_counter.u16[1]); -#if LLSEC802154_USES_EXPLICIT_KEYS - packetbuf_set_attr(buf, PACKETBUF_ATTR_KEY_ID_MODE, frame.aux_hdr.security_control.key_id_mode); - packetbuf_set_attr(buf, PACKETBUF_ATTR_KEY_INDEX, frame.aux_hdr.key_index); - packetbuf_set_attr(buf, PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1, frame.aux_hdr.key_source.u16[0]); -#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ - } -#endif /* LLSEC802154_SECURITY_LEVEL */ - - PRINTF("15.4-IN: %2X ", frame.fcf.frame_type); - PRINTLLADDR((const uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_SENDER)); - PRINTF(" "); - PRINTLLADDR((const uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER)); - PRINTF(" %d %u (%u)\n", hdr_len, packetbuf_datalen(buf), packetbuf_totlen(buf)); - -#ifdef FRAMER_802154_HANDLER - if(FRAMER_802154_HANDLER(&frame)) { - return FRAMER_FRAME_HANDLED; - } -#endif - - return hdr_len; - } - return FRAMER_FAILED; -} -/*---------------------------------------------------------------------------*/ -const struct framer framer_802154 = { - hdr_length, - create, - framer_canonical_create_and_secure, - parse -}; -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/mac/framer-802154.h b/net/ip/contiki/mac/framer-802154.h deleted file mode 100644 index dc981280550ac36fcb71ce18fe5a1823bdf0ebf7..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/framer-802154.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2009, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -/** - * \file - * A MAC framer for IEEE 802.15.4 - * \author - * Niclas Finne - * Joakim Eriksson - */ - -#ifndef FRAMER_802154_H_ -#define FRAMER_802154_H_ - -#include "contiki/mac/framer.h" - -extern const struct framer framer_802154; - -uint8_t framer_802154_next_seqno(void); -uint16_t framer_802154_get_pan_id(void); -void framer_802154_set_pan_id(uint16_t panid); - -#endif /* FRAMER_802154_H_ */ diff --git a/net/ip/contiki/mac/framer-nullmac.c b/net/ip/contiki/mac/framer-nullmac.c deleted file mode 100644 index 3f70121a1210d15dacacedf16002d6e29e23e728..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/framer-nullmac.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2009, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -/** - * \file - * MAC framer for nullmac - * \author - * Niclas Finne - * Joakim Eriksson - */ - -#include "contiki/mac/framer-nullmac.h" -#include "contiki/packetbuf.h" - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_15_4_FRAMING -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -struct nullmac_hdr { - linkaddr_t receiver; - linkaddr_t sender; -}; - -/*---------------------------------------------------------------------------*/ -static int -hdr_length(struct net_buf *buf) -{ - return sizeof(struct nullmac_hdr); -} -/*---------------------------------------------------------------------------*/ -static int -create(struct net_buf *buf) -{ - struct nullmac_hdr *hdr; - - if(packetbuf_hdralloc(buf, sizeof(struct nullmac_hdr))) { - hdr = packetbuf_hdrptr(buf); - linkaddr_copy(&(hdr->sender), &linkaddr_node_addr); - linkaddr_copy(&(hdr->receiver), packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER)); - return sizeof(struct nullmac_hdr); - } - PRINTF("PNULLMAC-UT: too large header: %u\n", sizeof(struct nullmac_hdr)); - return FRAMER_FAILED; -} -/*---------------------------------------------------------------------------*/ -static int -parse(struct net_buf *buf) -{ - struct nullmac_hdr *hdr; - hdr = packetbuf_dataptr(buf); - if(packetbuf_hdrreduce(buf, sizeof(struct nullmac_hdr))) { - packetbuf_set_addr(buf, PACKETBUF_ADDR_SENDER, &(hdr->sender)); - packetbuf_set_addr(buf, PACKETBUF_ADDR_RECEIVER, &(hdr->receiver)); - - PRINTF("PNULLMAC-IN: "); - PRINTLLADDR((const uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_SENDER)); - PRINTF(" "); - PRINTLLADDR((const uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER)); - PRINTF(" %u (%u)\n", packetbuf_datalen(buf), sizeof(struct nullmac_hdr)); - - return sizeof(struct nullmac_hdr); - } - return FRAMER_FAILED; -} -/*---------------------------------------------------------------------------*/ -const struct framer framer_nullmac = { - hdr_length, - create, - framer_canonical_create_and_secure, - parse -}; diff --git a/net/ip/contiki/mac/framer-nullmac.h b/net/ip/contiki/mac/framer-nullmac.h deleted file mode 100644 index 49789959507e3e475620a05298c3f6d481b2a679..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/framer-nullmac.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2009, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -/** - * \file - * MAC framer for nullmac - * \author - * Niclas Finne - * Joakim Eriksson - */ - -#ifndef FRAMER_NULLMAC_H_ -#define FRAMER_NULLMAC_H_ - -#include "contiki/mac/framer.h" - -extern const struct framer framer_nullmac; - -#endif /* FRAMER_NULLMAC_H_ */ diff --git a/net/ip/contiki/mac/framer.c b/net/ip/contiki/mac/framer.c deleted file mode 100644 index ed905d436f531ffb854f769028d3b424f501420a..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/framer.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2014, Fraunhofer Heinrich-Hertz-Institut. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include "contiki/mac/framer.h" -#include "contiki/packetbuf.h" -#include "contiki/netstack.h" - -/*---------------------------------------------------------------------------*/ -int -framer_canonical_create_and_secure(struct net_buf *buf) -{ - int hdr_len; - - hdr_len = NETSTACK_FRAMER.create(buf); - if(hdr_len >= 0) { - packetbuf_compact(buf); - if(!NETSTACK_LLSEC.on_frame_created()) { - return FRAMER_FAILED; - } - } - return hdr_len; -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/mac/framer.h b/net/ip/contiki/mac/framer.h deleted file mode 100644 index e677ab3f8770d71208cc114bb3b1c43734895e98..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/framer.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2009, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -/** - * \file - * A MAC framer is responsible for constructing and parsing - * the header in MAC frames. At least the sender and receiver - * are required to be encoded in the MAC frame headers. - * \author - * Niclas Finne - * Joakim Eriksson - */ - -#include - -#ifndef FRAMER_H_ -#define FRAMER_H_ - -#define FRAMER_FAILED -1 -#define FRAMER_FRAME_HANDLED -2 - -struct framer { - - int (* length)(struct net_buf *buf); - int (* create)(struct net_buf *buf); - - /** Creates the frame and calls LLSEC.on_frame_created() */ - int (* create_and_secure)(struct net_buf *buf); - int (* parse)(struct net_buf *buf); - -}; - -int framer_canonical_create_and_secure(struct net_buf *buf); - -#endif /* FRAMER_H_ */ diff --git a/net/ip/contiki/mac/handler-802154.c b/net/ip/contiki/mac/handler-802154.c deleted file mode 100644 index 3226bf315454fb09ab1bd3e81fffcfc8fe885fe9..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/handler-802154.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Copyright (c) 2013-2015, Yanzi Networks AB. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -/** - * \file - * A MAC handler for IEEE 802.15.4 - * \author - * Joakim Eriksson - * Niclas Finne - */ - -#include - -#include "contiki/mac/framer-802154.h" -#include "contiki/mac/frame802154.h" -#include "contiki/mac/handler-802154.h" -#include "contiki/packetbuf.h" -#include "contiki/netstack.h" -#include "lib/random.h" -#include "sys/ctimer.h" -#include -#include - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_15_4_MAC -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#define CHANNEL_LOW 11 -#define CHANNEL_HIGH 26 - -#if HANDLER_802154_CONF_STATS -handler_802154_stats_t handler_802154_stats; -#endif /* HANDLER_802154_CONF_STATS */ - -/* ----------------------------------------------------- */ -/* variables for beacon req/resp - active scan */ -/* ----------------------------------------------------- */ -static int current_channel = 0; -static uint8_t chseqno = 0; -static int scan = 0; /* flag if scan is already active */ -static struct ctimer scan_timer; -static struct ctimer beacon_send_timer; - -static void handle_beacon(frame802154_t *frame); -static void handle_beacon_send_timer(struct net_buf *mbuf, void *p); -static int answer_beacon_requests; -static uint16_t panid; -static scan_callback_t callback; -static uint8_t beacon_payload[BEACON_PAYLOAD_BUFFER_SIZE] = { 0xfe, 0x00 }; -static uint8_t beacon_payload_len = 1; -static int others_beacon_reply; - -#ifndef DISABLE_NETSELECT_RANDOM_CHANNEL -#define DISABLE_NETSELECT_RANDOM_CHANNEL 0 -#endif /* DISABLE_NETSELECT_RANDOM_CHANNEL */ -#if (DISABLE_NETSELECT_RANDOM_CHANNEL == 0) -uint8_t channel_list[CHANNEL_HIGH - CHANNEL_LOW + 1]; -uint8_t channel_index; -#endif /* (DISABLE_NETSELECT_RANDOM_CHANNEL == 0) */ -/*---------------------------------------------------------------------------*/ -/* the init function assumes that the framer 802.15.4 is active and - used */ -void -handler_802154_join(uint16_t pid, int answer_beacons) -{ - panid = pid; - framer_802154_set_pan_id(pid); - answer_beacon_requests = answer_beacons; -} -/*---------------------------------------------------------------------------*/ -static void -end_scan(void) -{ - scan = 0; - NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE, - RADIO_RX_MODE_ADDRESS_FILTER | RADIO_RX_MODE_AUTOACK); - if(callback) { - /* nothing more will be scanned now */ - callback(0, NULL, CALLBACK_ACTION_SCAN_END); - } -} -/*---------------------------------------------------------------------------*/ -static void -handle_beacon(frame802154_t *frame) -{ - radio_value_t value; - PRINTF("Beacon received on channel: %d PanID: %x\n", current_channel, frame->src_pid); - if(answer_beacon_requests && - (frame->payload_len == beacon_payload_len) && - (memcmp(beacon_payload, frame->payload, beacon_payload_len) == 0)) { - others_beacon_reply++; - if(others_beacon_reply >= 3) { - /* Abort scheduled beacon transmit */ - ctimer_stop(&beacon_send_timer); - } - } - - /* scanned channel is already increased... */ - if(callback) { - /* pick the channel from the RADIO if it have been changed since we started - the scan - e.g. if we get a beacon later */ - NETSTACK_RADIO.get_value(RADIO_PARAM_CHANNEL, &value); - if(callback(value, frame, CALLBACK_ACTION_RX) == CALLBACK_STATUS_FINISHED) { - /* scan is over - application is satisfied */ - end_scan(); - } - } -} -/*---------------------------------------------------------------------------*/ -static void -handle_beacon_send_timer(struct net_buf *buf, void *p) -{ - struct net_buf *mbuf; - frame802154_t params; - uint8_t len; - - mbuf = l2_buf_get_reserve(0); - if(!mbuf) { - return; - } - - /* init to zeros */ - memset(¶ms, 0, sizeof(params)); - - /* use packetbuf for sending ?? */ - packetbuf_clear(mbuf); - /* Build the FCF. */ - params.fcf.frame_type = FRAME802154_BEACONFRAME; - - /* Insert IEEE 802.15.4 (2006) version bits. */ - params.fcf.frame_version = FRAME802154_IEEE802154_2006; - - /* assume long for now */ - params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE; - linkaddr_copy((linkaddr_t *)¶ms.src_addr, &linkaddr_node_addr); - - /* Set the source PAN ID to the global variable. */ - params.src_pid = panid; - - params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; - params.dest_addr[0] = 0xFF; - params.dest_addr[1] = 0xFF; - - params.dest_pid = 0xffff; - - params.seq = framer_802154_next_seqno(); - - /* Calculate beacon length and copy it to packetbuf */ - beacon_payload_len = handler_802154_calculate_beacon_payload_length(beacon_payload, BEACON_PAYLOAD_BUFFER_SIZE); - packetbuf_copyfrom(mbuf, beacon_payload, beacon_payload_len); - - /* Set payload and payload length */ - params.payload = packetbuf_dataptr(mbuf); - params.payload_len = packetbuf_datalen(mbuf); - - len = frame802154_hdrlen(¶ms); - if(packetbuf_hdralloc(mbuf, len)) { - frame802154_create(¶ms, packetbuf_hdrptr(mbuf), len); - if(NETSTACK_RADIO.send(mbuf, packetbuf_hdrptr(mbuf), - packetbuf_totlen(mbuf)) != RADIO_TX_OK) { - l2_buf_unref(mbuf); - return; - } - - HANDLER_802154_STAT(handler_802154_stats.beacons_sent++); - } -} -/*---------------------------------------------------------------------------*/ -/* called to send a beacon request */ -void -handler_802154_send_beacon_request(void) -{ - struct net_buf *mbuf; - frame802154_t params; - uint8_t len; - - mbuf = l2_buf_get_reserve(0); - if(!mbuf) { - return; - } - - /* init to zeros */ - memset(¶ms, 0, sizeof(params)); - - /* use packetbuf for sending ?? */ - packetbuf_clear(mbuf); - /* Build the FCF. */ - params.fcf.frame_type = FRAME802154_CMDFRAME; - - /* Insert IEEE 802.15.4 (2006) version bits. */ - params.fcf.frame_version = FRAME802154_IEEE802154_2006; - - params.fcf.src_addr_mode = FRAME802154_NOADDR; - - params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; - params.dest_addr[0] = 0xFF; - params.dest_addr[1] = 0xFF; - - params.dest_pid = 0xffff; - - params.seq = chseqno; - - packetbuf_set_datalen(mbuf, 1); - params.payload = packetbuf_dataptr(mbuf); - /* set the type in the payload */ - params.payload[0] = FRAME802154_BEACONREQ; - params.payload_len = packetbuf_datalen(mbuf); - len = frame802154_hdrlen(¶ms); - - if(packetbuf_hdralloc(mbuf, len)) { - frame802154_create(¶ms, packetbuf_hdrptr(mbuf), len); - if(NETSTACK_RADIO.send(mbuf, packetbuf_hdrptr(mbuf), - packetbuf_totlen(mbuf)) != RADIO_TX_OK) { - l2_buf_unref(mbuf); - return; - } - HANDLER_802154_STAT(handler_802154_stats.beacons_reqs_sent++); - } -} -/*---------------------------------------------------------------------------*/ -static void -handle_scan_timer(struct net_buf *mbuf, void *p) -{ - if(!scan) { - return; - } - - if(scan > 1) { - int callback_status; - callback_status = callback(current_channel, NULL, CALLBACK_ACTION_CHANNEL_DONE); - if(callback_status == CALLBACK_STATUS_FINISHED) { - end_scan(); - return; - } else if(callback_status == CALLBACK_STATUS_NEED_MORE_TIME) { - ctimer_reset(&scan_timer); - return; - } - } - - scan++; - -#if DISABLE_NETSELECT_RANDOM_CHANNEL - if(current_channel == 26) { - /* Last channel has been scanned. Report that the process is over. */ - end_scan(); - return; - } - - if(current_channel == 0) { - current_channel = 11; - } else { - current_channel++; - } -#else /* DISABLE_NETSELECT_RANDOM_CHANNEL */ - if(channel_index > (CHANNEL_HIGH - CHANNEL_LOW)) { - /* Last channel has been scanned. Report that the process is over. */ - end_scan(); - return; - } - - if(current_channel == 0) { - /* new scan, randomize channels */ - int i; - int j; - channel_index = 0; - - /* Initialize a random list as shown by Durstenfelds' Fisher–Yates shuffle. */ - for(i = 0; i <= (CHANNEL_HIGH - CHANNEL_LOW); i++) { - j = random_rand() % (i + 1); - if(j != i) { - channel_list[i] = channel_list[j]; - } - channel_list[j] = i + CHANNEL_LOW; - } - -#if DEBUG - PRINTF("New netselect search: channel order: "); - for(i = 0; i <= (CHANNEL_HIGH - CHANNEL_LOW); i++) { - PRINTF("%d ", channel_list[i]); - } - PRINTF("\n"); -#endif - } - current_channel = channel_list[channel_index++]; -#endif /* DISABLE_NETSELECT_RANDOM_CHANNEL */ - - NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE, 0); - NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, current_channel); - - handler_802154_send_beacon_request(); - - ctimer_reset(&scan_timer); -} -/*---------------------------------------------------------------------------*/ -/* - * active scan - will scan all 16 channels in the 802.15.4 network - * NOTE: this assumes 16 channels, starting from 11. Needs to be changed - * if running on other than 2.4 GHz - */ -int -handler_802154_active_scan(scan_callback_t cb) -{ - /* if no scan is active - start one */ - if(!scan) { - callback = cb; - current_channel = 0; -#if (DISABLE_NETSELECT_RANDOM_CHANNEL == 0) - channel_index = 0; -#endif /* (DISABLE_NETSELECT_RANDOM_CHANNEL == 0) */ - scan = 1; - chseqno = framer_802154_next_seqno(); - NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE, 0); - ctimer_set(NULL, &scan_timer, (CLOCK_SECOND * 6) / 10, &handle_scan_timer, callback); - return 1; - } - return 0; -} -/*---------------------------------------------------------------------------*/ -int -handler_802154_frame_received(frame802154_t *frame) -{ - if(answer_beacon_requests && - frame->fcf.frame_type == FRAME802154_CMDFRAME && - frame->payload[0] == FRAME802154_BEACONREQ) { - others_beacon_reply = 0; - ctimer_set(NULL, &beacon_send_timer, - CLOCK_SECOND / 16 + - (CLOCK_SECOND * (random_rand() & 0xff)) / 0x200, - &handle_beacon_send_timer, NULL); - return 1; - } - if(frame->fcf.frame_type == FRAME802154_BEACONFRAME) { - HANDLER_802154_STAT(handler_802154_stats.beacons_received++); - handle_beacon(frame); - return 1; - } - return 0; -} -/*---------------------------------------------------------------------------*/ -/* - * Calculate beacon payload length. - * Return length or -1 on error. - */ -int -handler_802154_calculate_beacon_payload_length(uint8_t *beacon, int maxlen) -{ - int i; - - if(beacon[0] != 0xfe) { - return -1; - } - - for(i = 1; beacon[i] != 0; i += beacon[i]) { - if(i >= maxlen) { - return -1; - } - } - i++; /* include the last 0-length indicator */ - return i; -} -/*---------------------------------------------------------------------------*/ -void -handler_802154_set_answer_beacons(int answer) -{ - answer_beacon_requests = answer; -} -/*---------------------------------------------------------------------------*/ -void -handler_802154_set_beacon_payload(uint8_t *payload, uint8_t len) -{ - if(len <= BEACON_PAYLOAD_BUFFER_SIZE) { - beacon_payload_len = 1; - memset(beacon_payload, 0, BEACON_PAYLOAD_BUFFER_SIZE); - memcpy(beacon_payload, payload, len); - beacon_payload_len = len; - } -} -/*---------------------------------------------------------------------------*/ -/* - * Write current beacon payload length to "len", if non-NULL. - * - * Return pointer to beacon payload buffer. - */ -uint8_t * -handler_802154_get_beacon_payload(uint8_t *len) -{ - if(len) { - *len = beacon_payload_len; - } - return beacon_payload; -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/mac/handler-802154.h b/net/ip/contiki/mac/handler-802154.h deleted file mode 100644 index c2bf25bbf30cbc065fae645372874e2c46636136..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/handler-802154.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2013-2015, Yanzi Networks AB. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -/** - * \file - * A MAC handler for IEEE 802.15.4 - * \author - * Joakim Eriksson - * Niclas Finne - */ - -#ifndef HANDLER_802154_H_ -#define HANDLER_802154_H_ - -#include "contiki/mac/frame802154.h" - -#define BEACON_PAYLOAD_BUFFER_SIZE 128 - -typedef enum { - CALLBACK_ACTION_RX, - CALLBACK_ACTION_CHANNEL_DONE, - CALLBACK_ACTION_SCAN_END, -} callback_action; - -#define CALLBACK_STATUS_CONTINUE 0 -#define CALLBACK_STATUS_NEED_MORE_TIME 1 -#define CALLBACK_STATUS_FINISHED 2 - -typedef int (* scan_callback_t)(uint8_t channel, frame802154_t *frame, callback_action cba); - -void handler_802154_join(uint16_t panid, int answer_beacons); - -int handler_802154_active_scan(scan_callback_t callback); -int handler_802154_calculate_beacon_payload_length(uint8_t *beacon, int maxlen); -void handler_802154_set_beacon_payload(uint8_t *payload, uint8_t len); -uint8_t *handler_802154_get_beacon_payload(uint8_t *len); -void handler_802154_send_beacon_request(void); -void handler_802154_set_answer_beacons(int answer); - -#ifndef HANDLER_802154_CONF_STATS -#define HANDLER_802154_CONF_STATS 0 -#endif - -#if HANDLER_802154_CONF_STATS -/* Statistics for fault management. */ -typedef struct handler_802154_stats { - uint16_t beacons_reqs_sent; - uint16_t beacons_sent; - uint16_t beacons_received; -} handler_802154_stats_t; - -extern handler_802154_stats_t handler_802154_stats; - -#define HANDLER_802154_STAT(code) (code) -#else /* HANDLER_802154_CONF_STATS */ -#define HANDLER_802154_STAT(code) -#endif /* HANDLER_802154_CONF_STATS */ - -#endif /* HANDLER_802154_H_ */ diff --git a/net/ip/contiki/mac/mac-sequence.c b/net/ip/contiki/mac/mac-sequence.c deleted file mode 100644 index 44081a7a15fc85c1aa4843e0dab44235e873dc6a..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/mac-sequence.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Copyright (c) 2013, ADVANSEE - http://www.advansee.com/ - * Benoît Thébaudeau - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * MAC sequence numbers management - * \author - * Adam Dunkels - * Benoît Thébaudeau - */ - -#include - -#include - -#include "contiki-net.h" -#include "contiki/mac/mac-sequence.h" -#include "contiki/packetbuf.h" - -struct seqno { - linkaddr_t sender; - uint8_t seqno; -}; - -#ifdef NETSTACK_CONF_MAC_SEQNO_HISTORY -#define MAX_SEQNOS NETSTACK_CONF_MAC_SEQNO_HISTORY -#else /* NETSTACK_CONF_MAC_SEQNO_HISTORY */ -#define MAX_SEQNOS 16 -#endif /* NETSTACK_CONF_MAC_SEQNO_HISTORY */ -static struct seqno received_seqnos[MAX_SEQNOS]; - -/*---------------------------------------------------------------------------*/ -int -mac_sequence_is_duplicate(struct net_buf *buf) -{ - int i; - - /* - * Check for duplicate packet by comparing the sequence number of the incoming - * packet with the last few ones we saw. - */ - for(i = 0; i < MAX_SEQNOS; ++i) { - if(linkaddr_cmp(packetbuf_addr(buf, PACKETBUF_ADDR_SENDER), - &received_seqnos[i].sender)) { - if(packetbuf_attr(buf, PACKETBUF_ATTR_PACKET_ID) == received_seqnos[i].seqno) { - /* Duplicate packet. */ - return 1; - } - break; - } - } - return 0; -} -/*---------------------------------------------------------------------------*/ -void -mac_sequence_register_seqno(struct net_buf *buf) -{ - int i, j; - - /* Locate possible previous sequence number for this address. */ - for(i = 0; i < MAX_SEQNOS; ++i) { - if(linkaddr_cmp(packetbuf_addr(buf, PACKETBUF_ADDR_SENDER), - &received_seqnos[i].sender)) { - i++; - break; - } - } - - /* Keep the last sequence number for each address as per 802.15.4e. */ - for(j = i - 1; j > 0; --j) { - memcpy(&received_seqnos[j], &received_seqnos[j - 1], sizeof(struct seqno)); - } - received_seqnos[0].seqno = packetbuf_attr(buf, PACKETBUF_ATTR_PACKET_ID); - linkaddr_copy(&received_seqnos[0].sender, - packetbuf_addr(buf, PACKETBUF_ADDR_SENDER)); -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/mac/mac-sequence.h b/net/ip/contiki/mac/mac-sequence.h deleted file mode 100644 index c19e5e4831a12881c669d9fb4957d08f10580b85..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/mac-sequence.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Copyright (c) 2013, ADVANSEE - http://www.advansee.com/ - * Benoît Thébaudeau - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header file for MAC sequence numbers management - * \author - * Adam Dunkels - * Benoît Thébaudeau - */ - -#ifndef MAC_SEQUENCE_H -#define MAC_SEQUENCE_H - -/** - * \brief Tell whether the packetbuf is a duplicate packet - * \return Non-zero if the packetbuf is a duplicate packet, zero otherwise - * - * This function is used to check for duplicate packet by comparing - * the sequence number of the incoming packet with the last few ones - * we saw, filtering with the Rime address. - */ -int mac_sequence_is_duplicate(struct net_buf *buf); - -/** - * \brief Register the sequence number of the packetbuf - * - * This function is used to add the sequence number of the incoming - * packet to the history. - */ -void mac_sequence_register_seqno(struct net_buf *buf); - -#endif /* MAC_SEQUENCE_H */ diff --git a/net/ip/contiki/mac/mac.c b/net/ip/contiki/mac/mac.c deleted file mode 100644 index 3737f543d798378272dabb18b0b437d0ef3cf2d0..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/mac.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#include - -#include "contiki/mac/mac.h" - -#define DEBUG 0 -#include "contiki/ip/uip-debug.h" - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif - -#if NET_MAC_CONF_STATS -net_mac_stats_t net_mac_stats = {0}; -#endif /* NET_MAC_CONF_STATS */ - -/*---------------------------------------------------------------------------*/ -void -mac_call_sent_callback(struct net_buf *buf, mac_callback_t sent, void *ptr, int status, int num_tx) -{ - PRINTF("buf %p mac_callback_t %p ptr %p status %d num_tx %d\n", buf, - (void *)sent, ptr, status, num_tx); - switch(status) { - case MAC_TX_COLLISION: - PRINTF("mac: collision after %d tx\n", num_tx); - break; - case MAC_TX_NOACK: - PRINTF("mac: noack after %d tx\n", num_tx); - break; - case MAC_TX_OK: - PRINTF("mac: sent after %d tx\n", num_tx); - break; - default: - PRINTF("mac: error %d after %d tx\n", status, num_tx); - } - - if(sent) { -#if NET_MAC_CONF_STATS - net_mac_stats.bytes_sent += uip_pkt_buflen(buf); -#endif - sent(buf, ptr, status, num_tx); - } -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/mac/mac.h b/net/ip/contiki/mac/mac.h deleted file mode 100644 index 06c70345add0c98e8568ad09c4bc49ee69e8dca9..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/mac.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * MAC driver header file - * \author - * Adam Dunkels - */ - -#ifndef MAC_H_ -#define MAC_H_ - -#include -#include "contiki-conf.h" -#include "dev/radio.h" - -#include - -#if NET_MAC_CONF_STATS -/* Statistics for sent bytes. */ -typedef struct net_mac_stats { - uint32_t bytes_sent; - uint32_t bytes_received; -} net_mac_stats_t; -extern net_mac_stats_t net_mac_stats; -#endif - -typedef void (* mac_callback_t)(struct net_buf *buf, void *ptr, int status, int transmissions); - -void mac_call_sent_callback(struct net_buf *buf, mac_callback_t sent, void *ptr, int status, int num_tx); - -/** - * The structure of a MAC protocol driver in Contiki. - */ -struct mac_driver { - char *name; - - /** Initialize the MAC driver */ - void (* init)(void); - - /** Send a packet from the Rime buffer */ - uint8_t (* send)(struct net_buf *buf, mac_callback_t sent_callback, - bool last_fragment, void *ptr); - - /** Callback for getting notified of incoming packet. */ - uint8_t (* input)(struct net_buf *buf); - - /** Turn the MAC layer on. */ - int (* on)(void); - - /** Turn the MAC layer off. */ - int (* off)(int keep_radio_on); - - /** Returns the channel check interval, expressed in clock_time_t ticks. */ - unsigned short (* channel_check_interval)(void); -}; - -/* Generic MAC return values. */ -enum { - /**< The MAC layer transmission was OK. */ - MAC_TX_OK, - - /**< The MAC layer transmission could not be performed due to a - collision. */ - MAC_TX_COLLISION, - - /**< The MAC layer did not get an acknowledgment for the packet. */ - MAC_TX_NOACK, - - /**< The MAC layer deferred the transmission for a later time. */ - MAC_TX_DEFERRED, - - /**< The MAC layer transmission could not be performed because of an - error. The upper layer may try again later. */ - MAC_TX_ERR, - - /**< The MAC layer transmission could not be performed because of a - fatal error. The upper layer does not need to try again, as the - error will be fatal then as well. */ - MAC_TX_ERR_FATAL, -}; - -#endif /* MAC_H_ */ diff --git a/net/ip/contiki/mac/nullmac.c b/net/ip/contiki/mac/nullmac.c deleted file mode 100644 index c45cb2e4de822489b390a64c50a788fb455a21d5..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/nullmac.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * A MAC protocol that does not do anything. - * \author - * Adam Dunkels - */ - -#include - -#include "contiki/mac/nullmac.h" -#include "contiki/netstack.h" -#include "contiki/ip/uip.h" -#include "contiki/ip/tcpip.h" -#include "contiki/packetbuf.h" -#include "contiki/netstack.h" - -/*---------------------------------------------------------------------------*/ -static uint8_t -send_packet(struct net_buf *buf, mac_callback_t sent, - bool last_fragment, void *ptr) -{ - NETSTACK_RDC.send(buf, sent, ptr); - return 1; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -packet_input(struct net_buf *buf) -{ - return NETSTACK_LLSEC.input(buf); -} -/*---------------------------------------------------------------------------*/ -static int -on(void) -{ - return NETSTACK_RDC.on(); -} -/*---------------------------------------------------------------------------*/ -static int -off(int keep_radio_on) -{ - return NETSTACK_RDC.off(keep_radio_on); -} -/*---------------------------------------------------------------------------*/ -static unsigned short -channel_check_interval(void) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -static void -init(void) -{ -} -/*---------------------------------------------------------------------------*/ -const struct mac_driver nullmac_driver = { - "nullmac", - init, - send_packet, - packet_input, - on, - off, - channel_check_interval, -}; -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/mac/nullmac.h b/net/ip/contiki/mac/nullmac.h deleted file mode 100644 index 7320f39ff0bf5a35f95bf5b1bd5bef320f888a1c..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/nullmac.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * A MAC protocol implementation that does not do anything. - * \author - * Adam Dunkels - */ - -#ifndef NULLMAC_H_ -#define NULLMAC_H_ - -#include "contiki/mac/mac.h" -#include "dev/radio.h" - -extern const struct mac_driver nullmac_driver; - - -#endif /* NULLMAC_H_ */ diff --git a/net/ip/contiki/mac/rdc.h b/net/ip/contiki/mac/rdc.h deleted file mode 100644 index eea5e10d3ea8ecf93dedd31198246e2825f40c22..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/rdc.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * RDC driver header file - * \author - * Adam Dunkels - * Niclas Finne - */ - -#ifndef RDC_H_ -#define RDC_H_ - -#include - -#include "contiki-conf.h" -#include "contiki/mac/mac.h" - -#ifdef RDC_CONF_WITH_DUPLICATE_DETECTION -#define RDC_WITH_DUPLICATE_DETECTION RDC_CONF_WITH_DUPLICATE_DETECTION -#else /* RDC_CONF_WITH_DUPLICATE_DETECTION */ -/* As frames can be spoofed, the RDC layer should not discard a - frame because it has seen its sequence number already. Replay - protection should be implemented at the LLSEC layer where the - authenticity of frames is verified. */ -#define RDC_WITH_DUPLICATE_DETECTION !LLSEC802154_CONF_SECURITY_LEVEL -#endif /* RDC_CONF_WITH_DUPLICATE_DETECTION */ - -/* List of packets to be sent by RDC layer */ -struct rdc_buf_list { - struct rdc_buf_list *next; - struct queuebuf *buf; - void *ptr; -}; - -/** - * The structure of a RDC (radio duty cycling) driver in Contiki. - */ -struct rdc_driver { - char *name; - - /** Initialize the RDC driver */ - void (* init)(void); - - /** Send a packet from the Rime buffer */ - uint8_t (* send)(struct net_buf *buf, mac_callback_t sent_callback, void *ptr); - - /** Send a packet list */ - uint8_t (* send_list)(struct net_buf *buf, mac_callback_t sent_callback, void *ptr, struct rdc_buf_list *list); - - /** Callback for getting notified of incoming packet. */ - uint8_t (* input)(struct net_buf *buf); - - /** Turn the MAC layer on. */ - int (* on)(void); - - /** Turn the MAC layer off. */ - int (* off)(int keep_radio_on); - - /** Returns the channel check interval, expressed in clock_time_t ticks. */ - unsigned short (* channel_check_interval)(void); -}; - -#endif /* RDC_H_ */ diff --git a/net/ip/contiki/mac/sicslowmac/sicslowmac.c b/net/ip/contiki/mac/sicslowmac/sicslowmac.c deleted file mode 100644 index 514c45014d2bf9030261a86e59e29f6b7e8b33f9..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/sicslowmac/sicslowmac.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (c) 2008, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - - -/** - * \file - * MAC interface for packaging radio packets into 802.15.4 frames - * - * \author - * Adam Dunkels - * Eric Gnoske - * Blake Leverett - * Niclas Finne - * Joakim Eriksson - */ - -#include - -#include - -#include "contiki/mac/sicslowmac/sicslowmac.h" -#include "contiki/mac/frame802154.h" -#include "contiki/packetbuf.h" -#include "contiki/queuebuf.h" -#include "contiki/netstack.h" -#include "lib/random.h" - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_15_4_MAC -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif - -/** \brief The sequence number (0x00 - 0xff) added to the transmitted - * data or MAC command frame. The default is a random value within - * the range. - */ -static uint8_t mac_dsn; - -/** \brief The 16-bit identifier of the PAN on which the device is - * sending to. If this value is 0xffff, the device is not - * associated. - */ -static uint16_t mac_dst_pan_id = IEEE802154_PANID; - -/** \brief The 16-bit identifier of the PAN on which the device is - * operating. If this value is 0xffff, the device is not - * associated. - */ -static uint16_t mac_src_pan_id = IEEE802154_PANID; - -/*---------------------------------------------------------------------------*/ -static int -is_broadcast_addr(uint8_t mode, uint8_t *addr) -{ - int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8; - while(i-- > 0) { - if(addr[i] != 0xff) { - return 0; - } - } - return 1; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -send_packet(struct net_buf *buf, mac_callback_t sent, void *ptr) -{ - frame802154_t params; - uint8_t len; - uint8_t ret = 0; - - /* init to zeros */ - memset(¶ms, 0, sizeof(params)); - - /* Build the FCF. */ - params.fcf.frame_type = FRAME802154_DATAFRAME; - params.fcf.security_enabled = 0; - params.fcf.frame_pending = 0; - params.fcf.ack_required = packetbuf_attr(buf, PACKETBUF_ATTR_RELIABLE); - params.fcf.panid_compression = 0; - - /* Insert IEEE 802.15.4 (2003) version bit. */ - params.fcf.frame_version = FRAME802154_IEEE802154_2003; - - /* Increment and set the data sequence number. */ - params.seq = mac_dsn++; - - /* Complete the addressing fields. */ - /** - \todo For phase 1 the addresses are all long. We'll need a mechanism - in the rime attributes to tell the mac to use long or short for phase 2. - */ - params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE; - params.dest_pid = mac_dst_pan_id; - - if(packetbuf_holds_broadcast(buf)) { - /* Broadcast requires short address mode. */ - params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; - params.dest_addr[0] = 0xFF; - params.dest_addr[1] = 0xFF; - - } else { - linkaddr_copy((linkaddr_t *)¶ms.dest_addr, - packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER)); - params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE; - } - - /* Set the source PAN ID to the global variable. */ - params.src_pid = mac_src_pan_id; - - /* - * Set up the source address using only the long address mode for - * phase 1. - */ -#if NETSTACK_CONF_BRIDGE_MODE - linkaddr_copy((linkaddr_t *)¶ms.src_addr,packetbuf_addr(PACKETBUF_ADDR_SENDER)); -#else - linkaddr_copy((linkaddr_t *)¶ms.src_addr, &linkaddr_node_addr); -#endif - - params.payload = packetbuf_dataptr(buf); - params.payload_len = packetbuf_datalen(buf); - len = frame802154_hdrlen(¶ms); - if(packetbuf_hdralloc(buf, len)) { - frame802154_create(¶ms, packetbuf_hdrptr(buf), len); - - PRINTF("6MAC-UT: type %X dest ", params.fcf.frame_type); - PRINTLLADDR((uip_lladdr_t *)params.dest_addr); - PRINTF(" len %u datalen %u (totlen %u)\n", len, packetbuf_datalen(buf), - packetbuf_totlen(buf)); - - ret = NETSTACK_RADIO.send(buf, packetbuf_hdrptr(buf), packetbuf_totlen(buf)); - if(sent) { - switch(ret) { - case RADIO_TX_OK: - sent(buf, ptr, MAC_TX_OK, 1); - break; - case RADIO_TX_ERR: - sent(buf, ptr, MAC_TX_ERR, 1); - break; - case RADIO_TX_COLLISION: - sent(buf, ptr, MAC_TX_COLLISION, 1); - break; - } - } - } else { - PRINTF("6MAC-UT: too large header: %u\n", len); - } - - return ret; -} -/*---------------------------------------------------------------------------*/ -uint8_t -send_list(struct net_buf *buf, mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) -{ - if(buf_list != NULL) { - queuebuf_to_packetbuf(buf, buf_list->buf); - if (!send_packet(buf, sent, ptr)) { - return 0; - } - } - - return 1; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -input_packet(struct net_buf *buf) -{ - frame802154_t frame; - int len; - - len = packetbuf_datalen(buf); - PRINTF("6MAC: received %d bytes\n", len); - - if(frame802154_parse(packetbuf_dataptr(buf), len, &frame) && - packetbuf_hdrreduce(buf, len - frame.payload_len)) { - if(frame.fcf.dest_addr_mode) { - if(frame.dest_pid != mac_src_pan_id && - frame.dest_pid != FRAME802154_BROADCASTPANDID) { - /* Not broadcast or for our PAN */ - PRINTF("6MAC: for another pan %u (0x%x)\n", frame.dest_pid, - frame.dest_pid); - goto error; - } - if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { - packetbuf_set_addr(buf, PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr); -#if !NETSTACK_CONF_BRIDGE_MODE - if(!linkaddr_cmp(packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER), - &linkaddr_node_addr)) { - /* Not for this node */ - PRINTF("6MAC: not for us, we are "); - PRINTLLADDR((uip_lladdr_t *)&linkaddr_node_addr); - PRINTF(" recipient is "); - PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER)); - PRINTF("\n"); - goto error; - } -#endif - } - } - packetbuf_set_addr(buf, PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr); - - PRINTF("6MAC-IN: type 0x%X sender ", frame.fcf.frame_type); - PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_SENDER)); - PRINTF(" receiver "); - PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER)); - PRINTF(" len %u\n", packetbuf_datalen(buf)); - return NETSTACK_MAC.input(buf); - } else { - PRINTF("6MAC: failed to parse hdr\n"); - } -error: - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -on(void) -{ - return NETSTACK_RADIO.on(); -} -/*---------------------------------------------------------------------------*/ -static int -off(int keep_radio_on) -{ - if(keep_radio_on) { - return NETSTACK_RADIO.on(); - } else { - return NETSTACK_RADIO.off(); - } -} -/*---------------------------------------------------------------------------*/ -static void -init(void) -{ - mac_dsn = random_rand() % 256; - - NETSTACK_RADIO.on(); -} -/*---------------------------------------------------------------------------*/ -static unsigned short -channel_check_interval(void) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -const struct rdc_driver sicslowmac_driver = { - "sicslowmac", - init, - send_packet, - send_list, - input_packet, - on, - off, - channel_check_interval -}; -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/mac/sicslowmac/sicslowmac.h b/net/ip/contiki/mac/sicslowmac/sicslowmac.h deleted file mode 100644 index b6c9b9c2c8bb64052918a76269aa45312a5ce6c7..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/sicslowmac/sicslowmac.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2008, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * MAC interface for packaging radio packets into 802.15.4 frames - * - * \author - * Adam Dunkels - * Eric Gnoske - * Blake Leverett - * Niclas Finne - * Joakim Eriksson - */ - -#ifndef SICSLOWMAC_H_ -#define SICSLOWMAC_H_ - -#include "contiki/mac/rdc.h" -#include "dev/radio.h" - -extern const struct rdc_driver sicslowmac_driver; - -#endif /* SICSLOWMAC_H_ */ diff --git a/net/ip/contiki/mac/simplerdc.c b/net/ip/contiki/mac/simplerdc.c deleted file mode 100644 index 4b4c43b0a2395c19a1164a3abc3949138181bcdb..0000000000000000000000000000000000000000 --- a/net/ip/contiki/mac/simplerdc.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "contiki/mac/mac-sequence.h" -#include "contiki/packetbuf.h" -#include "contiki/queuebuf.h" -#include "contiki/netstack.h" -#include "contiki/llsec/anti-replay.h" -#include - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_15_4_MAC -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#ifndef SIMPLERDC_MAX_RETRANSMISSIONS -#define SIMPLERDC_MAX_RETRANSMISSIONS 3 -#endif - -#define ACK_LEN 3 - -static struct nano_sem ack_lock; -static bool ack_received; - -static inline bool handle_ack_packet(struct net_buf *buf) -{ - if (packetbuf_datalen(buf) == ACK_LEN) { - ack_received = true; - nano_sem_give(&ack_lock); -#ifdef SIMPLERDC_802154_AUTOACK - PRINTF("simplerdc: ignore ACK packet\n"); - return true; -#endif - } - - return false; -} - -#ifdef SIMPLERDC_802154_AUTOACK -static inline bool check_duplicate(struct net_buf *buf) -{ - if (mac_sequence_is_duplicate(buf) != 0) { - PRINTF("simplerdc: duplicated packet seq %u\n", - packetbuf_attr(buf, PACKETBUF_ATTR_MAC_SEQNO)); - return true; - } - - mac_sequence_register_seqno(buf); - - return false; -} -#else -#define check_duplicate(...) (false) -#endif - -#ifdef SIMPLERDC_802154_SEND_ACK -#include "contiki/mac/frame802154.h" - -static inline bool send_ack_packet(struct net_buf *buf, uint8_t *status) -{ - struct net_buf *ack_buf; - frame802154_t frame; - - if (packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_TYPE) != - FRAME802154_DATAFRAME) { - return false; - } - - frame802154_parse(packetbuf_dataptr(buf), - packetbuf_datalen(buf), - &frame); - - if (frame.fcf.ack_required == 0 || - !linkaddr_cmp((linkaddr_t *)&frame.dest_addr, - &linkaddr_node_addr)) { - return false; - } - - ack_buf = l2_buf_get_reserve(0); - if (!ack_buf) { - *status = MAC_TX_ERR; - return false; - } - - uip_pkt_packetbuf(ack_buf)[0] = FRAME802154_ACKFRAME; - uip_pkt_packetbuf(ack_buf)[1] = 0; - uip_pkt_packetbuf(ack_buf)[2] = frame.seq; - - *status = NETSTACK_RADIO.send(ack_buf, NULL, ACK_LEN); - - l2_buf_unref(ack_buf); - - PRINTF("simplerdc: Send ACK to packet %u\n", - packetbuf_attr(buf, PACKETBUF_ATTR_MAC_SEQNO)); - - return true; -} -#else -#define send_ack_packet(...) (false) -#endif - -static inline bool prepare_for_ack(struct net_buf *buf) -{ - if (packetbuf_attr(buf, PACKETBUF_ATTR_MAC_ACK) != 0) { - PRINTF("simplerdc: ACK requested\n"); - - nano_sem_init(&ack_lock); - ack_received = false; - - return true; - } - - return false; -} - -static inline uint8_t wait_for_ack(bool broadcast, bool ack_required) -{ - if (broadcast || !ack_required) { - return MAC_TX_OK; - } - - if (nano_sem_take(&ack_lock, MSEC(10)) == 0) { - nano_sem_init(&ack_lock); - } - - if (!ack_received) { - return MAC_TX_NOACK; - } - - return MAC_TX_OK; -} - -static inline uint8_t prepare_packet(struct net_buf *buf) -{ - uint8_t retries; - - retries = packetbuf_attr(buf, PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS); - if (retries <= 0) { - retries = SIMPLERDC_MAX_RETRANSMISSIONS + 1; - } - - packetbuf_set_addr(buf, PACKETBUF_ADDR_SENDER, &linkaddr_node_addr); - - if (NETSTACK_FRAMER.create_and_secure(buf) < 0) { - return 0; - } - - return retries; -} - -static void init(void) -{ - NETSTACK_RADIO.on(); -} - -static uint8_t send_packet(struct net_buf *buf, - mac_callback_t sent_callback, void *ptr) -{ - int ret = MAC_TX_OK; - bool is_broadcast, ack_required; - uint8_t attempts; - uint8_t retries; - -#ifdef SIMPLERDC_802154_ACK_REQ - packetbuf_set_attr(buf, PACKETBUF_ATTR_MAC_ACK, 1); -#endif - - retries = prepare_packet(buf); - if (!retries) { - return MAC_TX_ERR_FATAL; - } - - ack_required = prepare_for_ack(buf); - is_broadcast = !!packetbuf_holds_broadcast(buf); - attempts = 0; - - while (retries) { - attempts++; - retries--; - - ret = NETSTACK_RADIO.transmit(buf, packetbuf_totlen(buf)); - if (ret == RADIO_TX_COLLISION) { - continue; - } - - ret = wait_for_ack(is_broadcast, ack_required); - if (ret == MAC_TX_OK) { - break; - } - } - - mac_call_sent_callback(buf, sent_callback, ptr, ret, attempts); - - if (ret == MAC_TX_OK) { - return 1; - } - - return 0; -} - -static uint8_t send_packet_list(struct net_buf *buf, - mac_callback_t sent_callback, - void *ptr, struct rdc_buf_list *list) -{ - while (list) { - struct rdc_buf_list *next = list->next; - int last_sent_ok; - - queuebuf_to_packetbuf(buf, list->buf); - - last_sent_ok = send_packet(buf, sent_callback, ptr); - if (!last_sent_ok) { - return 0; - } - - list = next; - } - - return 1; -} - -static uint8_t input_packet(struct net_buf *buf) -{ - uint8_t ret = 0; - bool duplicate; - - if (handle_ack_packet(buf)) { - return 0; - } - - if (NETSTACK_FRAMER.parse(buf) < 0) { - PRINTF("simpledc: parsing failed msg len %u\n", - packetbuf_datalen(buf)); - return 0; - } - - duplicate = check_duplicate(buf); - - if (send_ack_packet(buf, &ret)) { - return ret; - } - - if (duplicate) { - return 0; - } - - return NETSTACK_MAC.input(buf); -} - -static int on(void) -{ - return NETSTACK_RADIO.on(); -} - -static int off(int keep_radio_on) -{ - return NETSTACK_RADIO.off(); -} - -static unsigned short channel_check_interval(void) -{ - return 0; -} - -const struct rdc_driver simplerdc_driver = { - "simplerdc", - init, - send_packet, - send_packet_list, - input_packet, - on, - off, - channel_check_interval, -}; diff --git a/net/ip/contiki/nbr-table.c b/net/ip/contiki/nbr-table.c deleted file mode 100644 index e8ae66a1aa18e4aeea8776fd7ef9b55231a5b932..0000000000000000000000000000000000000000 --- a/net/ip/contiki/nbr-table.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (c) 2013, Swedish Institute of Computer Science - * Copyright (c) 2010, Vrije Universiteit Brussel - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * - * Authors: Simon Duquennoy - * Joris Borms - */ - -#include "contiki.h" - -#include -#include -#include "lib/memb.h" -#include "lib/list.h" -#include "contiki/nbr-table.h" - -/* List of link-layer addresses of the neighbors, used as key in the tables */ -typedef struct nbr_table_key { - struct nbr_table_key *next; - linkaddr_t lladdr; -} nbr_table_key_t; - -/* For each neighbor, a map of the tables that use the neighbor. - * As we are using uint8_t, we have a maximum of 8 tables in the system */ -static uint8_t used_map[NBR_TABLE_MAX_NEIGHBORS]; -/* For each neighbor, a map of the tables that lock the neighbor */ -static uint8_t locked_map[NBR_TABLE_MAX_NEIGHBORS]; -/* The maximum number of tables */ -#define MAX_NUM_TABLES 8 -/* A list of pointers to tables in use */ -static struct nbr_table *all_tables[MAX_NUM_TABLES]; -/* The current number of tables */ -static unsigned num_tables; - -/* The neighbor address table */ -MEMB(neighbor_addr_mem, nbr_table_key_t, NBR_TABLE_MAX_NEIGHBORS); -LIST(nbr_table_keys); - -/*---------------------------------------------------------------------------*/ -/* Get a key from a neighbor index */ -static nbr_table_key_t * -key_from_index(int index) -{ - return index != -1 ? &((nbr_table_key_t *)neighbor_addr_mem.mem)[index] : NULL; -} -/*---------------------------------------------------------------------------*/ -/* Get an item from its neighbor index */ -static nbr_table_item_t * -item_from_index(nbr_table_t *table, int index) -{ - return table != NULL && index != -1 ? (char *)table->data + index * table->item_size : NULL; -} -/*---------------------------------------------------------------------------*/ -/* Get the neighbor index of an item */ -static int -index_from_key(nbr_table_key_t *key) -{ - return key != NULL ? key - (nbr_table_key_t *)neighbor_addr_mem.mem : -1; -} -/*---------------------------------------------------------------------------*/ -/* Get the neighbor index of an item */ -static int -index_from_item(nbr_table_t *table, const nbr_table_item_t *item) -{ - return table != NULL && item != NULL ? ((int)((char *)item - (char *)table->data)) / table->item_size : -1; -} -/*---------------------------------------------------------------------------*/ -/* Get an item from its key */ -static nbr_table_item_t * -item_from_key(nbr_table_t *table, nbr_table_key_t *key) -{ - return item_from_index(table, index_from_key(key)); -} -/*---------------------------------------------------------------------------*/ -/* Get the key af an item */ -static nbr_table_key_t * -key_from_item(nbr_table_t *table, const nbr_table_item_t *item) -{ - return key_from_index(index_from_item(table, item)); -} -/*---------------------------------------------------------------------------*/ -/* Get the index of a neighbor from its link-layer address */ -static int -index_from_lladdr(const linkaddr_t *lladdr) -{ - nbr_table_key_t *key; - /* Allow lladdr-free insertion, useful e.g. for IPv6 ND. - * Only one such entry is possible at a time, indexed by linkaddr_null. */ - if(lladdr == NULL) { - lladdr = &linkaddr_null; - } - key = list_head(nbr_table_keys); - while(key != NULL) { - if(lladdr && linkaddr_cmp(lladdr, &key->lladdr)) { - return index_from_key(key); - } - key = list_item_next(key); - } - return -1; -} -/*---------------------------------------------------------------------------*/ -/* Get bit from "used" or "locked" bitmap */ -static int -nbr_get_bit(uint8_t *bitmap, nbr_table_t *table, nbr_table_item_t *item) -{ - int item_index = index_from_item(table, item); - if(table != NULL && item_index != -1) { - return (bitmap[item_index] & (1 << table->index)) != 0; - } else { - return 0; - } - return 0; -} -/*---------------------------------------------------------------------------*/ -/* Set bit in "used" or "locked" bitmap */ -static int -nbr_set_bit(uint8_t *bitmap, nbr_table_t *table, nbr_table_item_t *item, int value) -{ - int item_index = index_from_item(table, item); - if(table != NULL && item_index != -1) { - if(value) { - bitmap[item_index] |= 1 << table->index; - } else { - bitmap[item_index] &= ~(1 << table->index); - } - return 1; - } else { - return 0; - } - return 0; -} -/*---------------------------------------------------------------------------*/ -static nbr_table_key_t * -nbr_table_allocate(void) -{ - nbr_table_key_t *key; - int least_used_count = 0; - nbr_table_key_t *least_used_key = NULL; - - key = memb_alloc(&neighbor_addr_mem); - if(key != NULL) { - return key; - } else { /* No more space, try to free a neighbor. - * The replacement policy is the following: remove neighbor that is: - * (1) not locked - * (2) used by fewest tables - * (3) oldest (the list is ordered by insertion time) - * */ - /* Get item from first key */ - key = list_head(nbr_table_keys); - while(key != NULL) { - int item_index = index_from_key(key); - int locked = locked_map[item_index]; - /* Never delete a locked item */ - if(!locked) { - int used = used_map[item_index]; - int used_count = 0; - /* Count how many tables are using this item */ - while(used != 0) { - if((used & 1) == 1) { - used_count++; - } - used >>= 1; - } - /* Find least used item */ - if(least_used_key == NULL || used_count < least_used_count) { - least_used_key = key; - least_used_count = used_count; - if(used_count == 0) { /* We won't find any least used item */ - break; - } - } - } - key = list_item_next(key); - } - if(least_used_key == NULL) { - /* We haven't found any unlocked item, allocation fails */ - return NULL; - } else { - /* Reuse least used item */ - int i; - for(i = 0; icallback != NULL) { - /* Call table callback for each table that uses this item */ - nbr_table_item_t *removed_item = item_from_key(all_tables[i], least_used_key); - if(nbr_get_bit(used_map, all_tables[i], removed_item) == 1) { - all_tables[i]->callback(removed_item); - } - } - } - /* Empty used map */ - used_map[index_from_key(least_used_key)] = 0; - /* Remove neighbor from list */ - list_remove(nbr_table_keys, least_used_key); - /* Return associated key */ - return least_used_key; - } - } -} -/*---------------------------------------------------------------------------*/ -/* Register a new neighbor table. To be used at initialization by modules - * using a neighbor table */ -int -nbr_table_register(nbr_table_t *table, nbr_table_callback *callback) -{ - if(num_tables < MAX_NUM_TABLES) { - table->index = num_tables++; - table->callback = callback; - all_tables[table->index] = table; - return 1; - } else { - /* Maximum number of tables exceeded */ - return 0; - } -} -/*---------------------------------------------------------------------------*/ -/* Returns the first item of the current table */ -nbr_table_item_t * -nbr_table_head(nbr_table_t *table) -{ - /* Get item from first key */ - nbr_table_item_t *item = item_from_key(table, list_head(nbr_table_keys)); - /* Item is the first neighbor, now check is it is in the current table */ - if(nbr_get_bit(used_map, table, item)) { - return item; - } else { - return nbr_table_next(table, item); - } -} -/*---------------------------------------------------------------------------*/ -/* Iterates over the current table */ -nbr_table_item_t * -nbr_table_next(nbr_table_t *table, nbr_table_item_t *item) -{ - do { - void *key = key_from_item(table, item); - key = list_item_next(key); - /* Loop until the next item is in the current table */ - item = item_from_key(table, key); - } while(item && !nbr_get_bit(used_map, table, item)); - return item; -} -/*---------------------------------------------------------------------------*/ -/* Add a neighbor indexed with its link-layer address */ -nbr_table_item_t * -nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr) -{ - int index; - nbr_table_item_t *item; - nbr_table_key_t *key; - - /* Allow lladdr-free insertion, useful e.g. for IPv6 ND. - * Only one such entry is possible at a time, indexed by linkaddr_null. */ - if(lladdr == NULL) { - lladdr = &linkaddr_null; - } - - if((index = index_from_lladdr(lladdr)) == -1) { - /* Neighbor not yet in table, let's try to allocate one */ - key = nbr_table_allocate(); - - /* No space available for new entry */ - if(key == NULL) { - return NULL; - } - - /* Add neighbor to list */ - list_add(nbr_table_keys, key); - - /* Get index from newly allocated neighbor */ - index = index_from_key(key); - - /* Set link-layer address */ - linkaddr_copy(&key->lladdr, lladdr); - } - - /* Get item in the current table */ - item = item_from_index(table, index); - - /* Initialize item data and set "used" bit */ - memset(item, 0, table->item_size); - nbr_set_bit(used_map, table, item, 1); - - return item; -} -/*---------------------------------------------------------------------------*/ -/* Get an item from its link-layer address */ -void * -nbr_table_get_from_lladdr(nbr_table_t *table, const linkaddr_t *lladdr) -{ - void *item = item_from_index(table, index_from_lladdr(lladdr)); - return nbr_get_bit(used_map, table, item) ? item : NULL; -} -/*---------------------------------------------------------------------------*/ -/* Removes a neighbor from the current table (unset "used" bit) */ -int -nbr_table_remove(nbr_table_t *table, void *item) -{ - int ret = nbr_set_bit(used_map, table, item, 0); - nbr_set_bit(locked_map, table, item, 0); - return ret; -} -/*---------------------------------------------------------------------------*/ -/* Lock a neighbor for the current table (set "locked" bit) */ -int -nbr_table_lock(nbr_table_t *table, void *item) -{ - return nbr_set_bit(locked_map, table, item, 1); -} -/*---------------------------------------------------------------------------*/ -/* Release the lock on a neighbor for the current table (unset "locked" bit) */ -int -nbr_table_unlock(nbr_table_t *table, void *item) -{ - return nbr_set_bit(locked_map, table, item, 0); -} -/*---------------------------------------------------------------------------*/ -/* Get link-layer address of an item */ -linkaddr_t * -nbr_table_get_lladdr(nbr_table_t *table, const void *item) -{ - nbr_table_key_t *key = key_from_item(table, item); - return key != NULL ? &key->lladdr : NULL; -} diff --git a/net/ip/contiki/nbr-table.h b/net/ip/contiki/nbr-table.h deleted file mode 100644 index 89643b1b1707df77d57fb0c205af0d6bd6937ad8..0000000000000000000000000000000000000000 --- a/net/ip/contiki/nbr-table.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2013, Swedish Institute of Computer Science - * Copyright (c) 2010, Vrije Universiteit Brussel - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * - * Authors: Simon Duquennoy - * Joris Borms - */ - -#ifndef NBR_TABLE_H_ -#define NBR_TABLE_H_ - -#include "contiki.h" -#include "contiki/linkaddr.h" -#include "contiki/netstack.h" - -/* Neighbor table size */ -#ifdef NBR_TABLE_CONF_MAX_NEIGHBORS -#define NBR_TABLE_MAX_NEIGHBORS NBR_TABLE_CONF_MAX_NEIGHBORS -#else /* NBR_TABLE_CONF_MAX_NEIGHBORS */ -#define NBR_TABLE_MAX_NEIGHBORS 8 -#endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */ - -/* An item in a neighbor table */ -typedef void nbr_table_item_t; - -/* Callback function, called when removing an item from a table */ -typedef void(nbr_table_callback)(nbr_table_item_t *item); - -/* A neighbor table */ -typedef struct nbr_table { - int index; - int item_size; - nbr_table_callback *callback; - nbr_table_item_t *data; -} nbr_table_t; - -/** \brief A static neighbor table. To be initialized through nbr_table_register(name) */ -#define NBR_TABLE(type, name) \ - static type _##name##_mem[NBR_TABLE_MAX_NEIGHBORS]; \ - static nbr_table_t name##_struct = { 0, sizeof(type), NULL, (nbr_table_item_t *)_##name##_mem }; \ - static nbr_table_t *name = &name##_struct \ - -/** \brief A non-static neighbor table. To be initialized through nbr_table_register(name) */ -#define NBR_TABLE_GLOBAL(type, name) \ - static type _##name##_mem[NBR_TABLE_MAX_NEIGHBORS]; \ - static nbr_table_t name##_struct = { 0, sizeof(type), NULL, (nbr_table_item_t *)_##name##_mem }; \ - nbr_table_t *name = &name##_struct \ - -/** \brief Declaration of non-static neighbor tables */ -#define NBR_TABLE_DECLARE(name) extern nbr_table_t *name - -/** \name Neighbor tables: register and loop through table elements */ -/** @{ */ -int nbr_table_register(nbr_table_t *table, nbr_table_callback *callback); -nbr_table_item_t *nbr_table_head(nbr_table_t *table); -nbr_table_item_t *nbr_table_next(nbr_table_t *table, nbr_table_item_t *item); -/** @} */ - -/** \name Neighbor tables: add and get data */ -/** @{ */ -nbr_table_item_t *nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr); -nbr_table_item_t *nbr_table_get_from_lladdr(nbr_table_t *table, const linkaddr_t *lladdr); -/** @} */ - -/** \name Neighbor tables: set flags (unused, locked, unlocked) */ -/** @{ */ -int nbr_table_remove(nbr_table_t *table, nbr_table_item_t *item); -int nbr_table_lock(nbr_table_t *table, nbr_table_item_t *item); -int nbr_table_unlock(nbr_table_t *table, nbr_table_item_t *item); -/** @} */ - -/** \name Neighbor tables: address manipulation */ -/** @{ */ -linkaddr_t *nbr_table_get_lladdr(nbr_table_t *table, const nbr_table_item_t *item); -/** @} */ - -#endif /* NBR_TABLE_H_ */ diff --git a/net/ip/contiki/netstack.c b/net/ip/contiki/netstack.c deleted file mode 100644 index 0ca14abbc7da729fe311fe574ee73c3857f3ff0a..0000000000000000000000000000000000000000 --- a/net/ip/contiki/netstack.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Initialiation file for the Contiki low-layer network stack (NETSTACK) - * \author - * Adam Dunkels - */ - -#include "contiki/netstack.h" -/*---------------------------------------------------------------------------*/ -void -netstack_init(void) -{ - NETSTACK_RADIO.init(); - NETSTACK_RDC.init(); - NETSTACK_MAC.init(); - NETSTACK_COMPRESS.init(); -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/netstack.h b/net/ip/contiki/netstack.h deleted file mode 100644 index 89df8a96a82874d1c012c81737c56c83a5af4a7b..0000000000000000000000000000000000000000 --- a/net/ip/contiki/netstack.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * $Id: netstack.h,v 1.6 2010/10/03 20:37:32 adamdunkels Exp $ - */ - -/** - * \file - * Include file for the Contiki low-layer network stack (NETSTACK) - * \author - * Adam Dunkels - */ - -#ifndef NETSTACK_H -#define NETSTACK_H - -#include - -#include "contiki-conf.h" - -#ifndef NETSTACK_LLSEC -#ifdef NETSTACK_CONF_LLSEC -#define NETSTACK_LLSEC NETSTACK_CONF_LLSEC -#else /* NETSTACK_CONF_LLSEC */ -#define NETSTACK_LLSEC nullsec_driver -#endif /* NETSTACK_CONF_LLSEC */ -#endif /* NETSTACK_LLSEC */ - -#ifndef NETSTACK_MAC -#ifdef NETSTACK_CONF_MAC -#define NETSTACK_MAC NETSTACK_CONF_MAC -#else /* NETSTACK_CONF_MAC */ -#define NETSTACK_MAC nullmac_driver -#endif /* NETSTACK_CONF_MAC */ -#endif /* NETSTACK_MAC */ - -#ifndef NETSTACK_RDC -#ifdef NETSTACK_CONF_RDC -#define NETSTACK_RDC NETSTACK_CONF_RDC -#else /* NETSTACK_CONF_RDC */ -#define NETSTACK_RDC simplerdc_driver -#endif /* NETSTACK_CONF_RDC */ -#endif /* NETSTACK_RDC */ - -#ifndef NETSTACK_RDC_CHANNEL_CHECK_RATE -#ifdef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE -#define NETSTACK_RDC_CHANNEL_CHECK_RATE NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE -#else /* NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE */ -#define NETSTACK_RDC_CHANNEL_CHECK_RATE 8 -#endif /* NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE */ -#endif /* NETSTACK_RDC_CHANNEL_CHECK_RATE */ - -#if (NETSTACK_RDC_CHANNEL_CHECK_RATE & (NETSTACK_RDC_CHANNEL_CHECK_RATE - 1)) != 0 -#error NETSTACK_RDC_CONF_CHANNEL_CHECK_RATE must be a power of two (i.e., 1, 2, 4, 8, 16, 32, 64, ...). -#error Change NETSTACK_RDC_CONF_CHANNEL_CHECK_RATE in contiki-conf.h, project-conf.h or in your Makefile. -#endif - - -#ifndef NETSTACK_RADIO -#ifdef NETSTACK_CONF_RADIO -#define NETSTACK_RADIO NETSTACK_CONF_RADIO -#else /* NETSTACK_CONF_RADIO */ -#define NETSTACK_RADIO nullradio_driver -#endif /* NETSTACK_CONF_RADIO */ -#endif /* NETSTACK_RADIO */ - -#ifndef NETSTACK_FRAMER -#ifdef NETSTACK_CONF_FRAMER -#define NETSTACK_FRAMER NETSTACK_CONF_FRAMER -#else /* NETSTACK_CONF_FRAMER */ -#define NETSTACK_FRAMER framer_nullmac -#endif /* NETSTACK_CONF_FRAMER */ -#endif /* NETSTACK_FRAMER */ - -#ifndef NETSTACK_COMPRESS -#ifdef NETSTACK_CONF_COMPRESS -#define NETSTACK_COMPRESS NETSTACK_CONF_COMPRESS -#else /* NETSTACK_CONF_COMPRESS */ -#define NETSTACK_COMPRESS null_compression -#endif /* NETSTACK_CONF_COMPRESS */ -#endif /* NETSTACK_COMPRESS */ - -#ifndef NETSTACK_FRAGMENT -#ifdef NETSTACK_CONF_FRAGMENT -#define NETSTACK_FRAGMENT NETSTACK_CONF_FRAGMENT -#else /* NETSTACK_CONF_FRAGMENT */ -#define NETSTACK_FRAGMENT null_fragmentation -#endif /* NETSTACK_CONF_FRAGMENT */ -#endif /* NETSTACK_FRAGEMENT */ - -#include "contiki/llsec/llsec.h" -#include "contiki/mac/mac.h" -#include "contiki/mac/rdc.h" -#include "contiki/mac/framer.h" -#include "contiki/os/dev/radio.h" -#include "contiki/sicslowpan/compression.h" -#include "contiki/sicslowpan/fragmentation.h" - -/** - * The structure of a network driver in Contiki. - */ -struct network_driver { - char *name; - - /** Initialize the network driver */ - void (* init)(void); - - /** Callback for getting notified of incoming packet. */ - uint8_t (* input)(struct net_buf *buf); -}; - -extern const struct llsec_driver NETSTACK_LLSEC; -extern const struct rdc_driver NETSTACK_RDC; -extern const struct mac_driver NETSTACK_MAC; -extern const struct radio_driver NETSTACK_RADIO; -extern const struct framer NETSTACK_FRAMER; -extern const struct compression NETSTACK_COMPRESS; -extern const struct fragmentation NETSTACK_FRAGMENT; - -void netstack_init(void); - -#endif /* NETSTACK_H */ diff --git a/net/ip/contiki/os/dev/nullradio.c b/net/ip/contiki/os/dev/nullradio.c deleted file mode 100644 index b4386e437a953031acb6f78000655dc18d2dd22e..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/dev/nullradio.c +++ /dev/null @@ -1,109 +0,0 @@ -#include - -#include "dev/nullradio.h" - - -/*---------------------------------------------------------------------------*/ -static int -init(void) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -prepare(const void *payload, unsigned short payload_len) -{ - return 1; -} -/*---------------------------------------------------------------------------*/ -static int -transmit(struct net_buf *buf, unsigned short transmit_len) -{ - return RADIO_TX_OK; -} -/*---------------------------------------------------------------------------*/ -static int -send(struct net_buf *buf, const void *payload, unsigned short payload_len) -{ - prepare(payload, payload_len); - return transmit(buf, payload_len); -} -/*---------------------------------------------------------------------------*/ -static int -radio_read(void *buf, unsigned short buf_len) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -channel_clear(void) -{ - return 1; -} -/*---------------------------------------------------------------------------*/ -static int -receiving_packet(void) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -pending_packet(void) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -on(void) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -off(void) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -static radio_result_t -get_value(radio_param_t param, radio_value_t *value) -{ - return RADIO_RESULT_NOT_SUPPORTED; -} -/*---------------------------------------------------------------------------*/ -static radio_result_t -set_value(radio_param_t param, radio_value_t value) -{ - return RADIO_RESULT_NOT_SUPPORTED; -} -/*---------------------------------------------------------------------------*/ -static radio_result_t -get_object(radio_param_t param, void *dest, size_t size) -{ - return RADIO_RESULT_NOT_SUPPORTED; -} -/*---------------------------------------------------------------------------*/ -static radio_result_t -set_object(radio_param_t param, const void *src, size_t size) -{ - return RADIO_RESULT_NOT_SUPPORTED; -} -/*---------------------------------------------------------------------------*/ -const struct radio_driver nullradio_driver = - { - init, - prepare, - transmit, - send, - radio_read, - channel_clear, - receiving_packet, - pending_packet, - on, - off, - get_value, - set_value, - get_object, - set_object - }; -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/os/dev/nullradio.h b/net/ip/contiki/os/dev/nullradio.h deleted file mode 100644 index 87acb3450a55839fa784dc091eec58f74570f4d1..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/dev/nullradio.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef NULLRADIO_H -#define NULLRADIO_H - -#include "dev/radio.h" - -extern const struct radio_driver nullradio_driver; - -#endif /* NULLRADIO_H */ diff --git a/net/ip/contiki/os/dev/radio.h b/net/ip/contiki/os/dev/radio.h deleted file mode 100644 index efd0d1dbbc3c364ebfeeb37c93b01f624d293dd9..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/dev/radio.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header file for the radio API - * \author - * Adam Dunkels - * Joakim Eriksson - * Niclas Finne - * Nicolas Tsiftes - */ - -/** - * \addtogroup dev - * @{ - */ - -/** - * \defgroup radio Radio API - * - * The radio API module defines a set of functions that a radio device - * driver must implement. - * - * @{ - */ - -#ifndef RADIO_H_ -#define RADIO_H_ - -#include - -#include - -/** - * Each radio has a set of parameters that designate the current - * configuration and state of the radio. Parameters can either have - * values of type radio_value_t, or, when this type is insufficient, a - * generic object that is specified by a memory pointer and the size - * of the object. - * - * The radio_value_t type is set to an integer type that can hold most - * values used to configure the radio, and is therefore the most - * common type used for a parameter. Certain parameters require - * objects of a considerably larger size than radio_value_t, however, - * and in these cases the documentation below for the parameter will - * indicate this. - * - * All radio parameters that can vary during runtime are prefixed by - * "RADIO_PARAM", whereas those "parameters" that are guaranteed to - * remain immutable are prefixed by "RADIO_CONST". Each mutable - * parameter has a set of valid parameter values. When attempting to - * set a parameter to an invalid value, the radio will return - * RADIO_RESULT_INVALID_VALUE. - * - * Some radios support only a subset of the defined radio parameters. - * When trying to set or get such an unsupported parameter, the radio - * will return RADIO_RESULT_NOT_SUPPORTED. - */ - -typedef int radio_value_t; -typedef unsigned radio_param_t; - -enum { - - /* Radio power mode determines if the radio is on - (RADIO_POWER_MODE_ON) or off (RADIO_POWER_MODE_OFF). */ - RADIO_PARAM_POWER_MODE, - - /* - * Channel used for radio communication. The channel depends on the - * communication standard used by the radio. The values can range - * from RADIO_CONST_CHANNEL_MIN to RADIO_CONST_CHANNEL_MAX. - */ - RADIO_PARAM_CHANNEL, - - /* Personal area network identifier, which is used by the address filter. */ - RADIO_PARAM_PAN_ID, - - /* Short address (16 bits) for the radio, which is used by the address - filter. */ - RADIO_PARAM_16BIT_ADDR, - - /* - * Radio receiver mode determines if the radio has address filter - * (RADIO_RX_MODE_ADDRESS_FILTER) and auto-ACK (RADIO_RX_MODE_AUTOACK) - * enabled. This parameter is set as a bit mask. - */ - RADIO_PARAM_RX_MODE, - - /* - * Radio transmission mode determines if the radio has send on CCA - * (RADIO_TX_MODE_SEND_ON_CCA) enabled or not. This parameter is set - * as a bit mask. - */ - RADIO_PARAM_TX_MODE, - - /* - * Transmission power in dBm. The values can range from - * RADIO_CONST_TXPOWER_MIN to RADIO_CONST_TXPOWER_MAX. - * - * Some radios restrict the available values to a subset of this - * range. If an unavailable TXPOWER value is requested to be set, - * the radio may select another TXPOWER close to the requested - * one. When getting the value of this parameter, the actual value - * used by the radio will be returned. - */ - RADIO_PARAM_TXPOWER, - - /* - * Clear channel assessment threshold in dBm. This threshold - * determines the minimum RSSI level at which the radio will assume - * that there is a packet in the air. - * - * The CCA threshold must be set to a level above the noise floor of - * the deployment. Otherwise mechanisms such as send-on-CCA and - * low-power-listening duty cycling protocols may not work - * correctly. Hence, the default value of the system may not be - * optimal for any given deployment. - */ - RADIO_PARAM_CCA_THRESHOLD, - - /* Received signal strength indicator in dBm. */ - RADIO_PARAM_RSSI, - - /* - * Long (64 bits) address for the radio, which is used by the address filter. - * The address is specified in network byte order. - * - * Because this parameter value is larger than what fits in radio_value_t, - * it needs to be used with radio.get_object()/set_object(). - */ - RADIO_PARAM_64BIT_ADDR, - - /* Constants (read only) */ - - /* The lowest radio channel. */ - RADIO_CONST_CHANNEL_MIN, - /* The highest radio channel. */ - RADIO_CONST_CHANNEL_MAX, - - /* The minimum transmission power in dBm. */ - RADIO_CONST_TXPOWER_MIN, - /* The maximum transmission power in dBm. */ - RADIO_CONST_TXPOWER_MAX -}; - -/* Radio power modes */ -enum { - RADIO_POWER_MODE_OFF, - RADIO_POWER_MODE_ON -}; - -/** - * The radio reception mode controls address filtering and automatic - * transmission of acknowledgements in the radio (if such operations - * are supported by the radio). A single parameter is used to allow - * setting these features simultaneously as an atomic operation. - * - * To enable both address filter and transmissions of automatic - * acknowledgments: - * - * NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE, - * RADIO_RX_MODE_ADDRESS_FILTER | RADIO_RX_MODE_AUTOACK); - */ -#define RADIO_RX_MODE_ADDRESS_FILTER (1 << 0) -#define RADIO_RX_MODE_AUTOACK (1 << 1) - -/** - * The radio transmission mode controls whether transmissions should - * be done using clear channel assessment (if supported by the - * radio). If send-on-CCA is enabled, the radio's send function will - * wait for a radio-specific time window for the channel to become - * clear. If this does not happen, the send function will return - * RADIO_TX_COLLISION. - */ -#define RADIO_TX_MODE_SEND_ON_CCA (1 << 0) - -/* Radio return values when setting or getting radio parameters. */ -typedef enum { - RADIO_RESULT_OK, - RADIO_RESULT_NOT_SUPPORTED, - RADIO_RESULT_INVALID_VALUE, - RADIO_RESULT_ERROR -} radio_result_t; - -/* Radio return values for transmissions. */ -enum { - RADIO_TX_OK, - RADIO_TX_ERR, - RADIO_TX_COLLISION, - RADIO_TX_NOACK, -}; - -/** - * The structure of a device driver for a radio in Contiki. - */ -struct radio_driver { - - int (* init)(void); - - /** Prepare the radio with a packet to be sent. */ - int (* prepare)(const void *payload, unsigned short payload_len); - - /** Send the packet that has previously been prepared. */ - int (* transmit)(struct net_buf *buf, unsigned short transmit_len); - - /** Prepare & transmit a packet. */ - int (* send)(struct net_buf *buf, const void *payload, unsigned short payload_len); - - /** Read a received packet into a buffer. */ - int (* read)(void *buf, unsigned short buf_len); - - /** Perform a Clear-Channel Assessment (CCA) to find out if there is - a packet in the air or not. */ - int (* channel_clear)(void); - - /** Check if the radio driver is currently receiving a packet */ - int (* receiving_packet)(void); - - /** Check if the radio driver has just received a packet */ - int (* pending_packet)(void); - - /** Turn the radio on. */ - int (* on)(void); - - /** Turn the radio off. */ - int (* off)(void); - - /** Get a radio parameter value. */ - radio_result_t (* get_value)(radio_param_t param, radio_value_t *value); - - /** Set a radio parameter value. */ - radio_result_t (* set_value)(radio_param_t param, radio_value_t value); - - /** - * Get a radio parameter object. The argument 'dest' must point to a - * memory area of at least 'size' bytes, and this memory area will - * contain the parameter object if the function succeeds. - */ - radio_result_t (* get_object)(radio_param_t param, void *dest, size_t size); - - /** - * Set a radio parameter object. The memory area referred to by the - * argument 'src' will not be accessed after the function returns. - */ - radio_result_t (* set_object)(radio_param_t param, const void *src, - size_t size); - -}; - -#endif /* RADIO_H_ */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/os/dev/slip-arch.c b/net/ip/contiki/os/dev/slip-arch.c deleted file mode 100644 index 05417aa13648e3c4e78949cd481f85dc7748b2f9..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/dev/slip-arch.c +++ /dev/null @@ -1,34 +0,0 @@ -/* uart.c - UART based network driver */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include - -#include "dev/slip.h" - -void slip_arch_writeb(unsigned char c) -{ - uint8_t buf[1] = { c }; - - uart_pipe_send(&buf[0], 1); -} - -void slip_arch_init(unsigned long ubr) -{ -} diff --git a/net/ip/contiki/os/dev/slip.c b/net/ip/contiki/os/dev/slip.c deleted file mode 100644 index ce0be81f43125eeab228f7f4caea65f48b559e06..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/dev/slip.c +++ /dev/null @@ -1,474 +0,0 @@ -/* -*- C -*- */ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#if defined(CONFIG_NETWORKING_UART) - -#include -#include -#include - -#include -#include - -#include - -#include "contiki.h" - -#include "contiki/ip/uip.h" - -#if !defined(CONFIG_NETWORKING_DEBUG_UART) -#undef NET_DBG -#define NET_DBG(fmt, ...) -#endif - -#define BUF(buf) ((struct uip_tcpip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) - -#include "dev/slip.h" - -#define SLIP_END 0300 -#define SLIP_ESC 0333 -#define SLIP_ESC_END 0334 -#define SLIP_ESC_ESC 0335 - -PROCESS(slip_process, "SLIP driver"); - -uint8_t slip_active; - -#if 1 -#define SLIP_STATISTICS(statement) -#else -uint16_t slip_rubbish, slip_twopackets, slip_overflow, slip_ip_drop; -#define SLIP_STATISTICS(statement) statement -#endif - -/* Must be at least one byte larger than UIP_BUFSIZE! */ -#define RX_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN + 16) - -enum { - STATE_TWOPACKETS = 0, /* We have 2 packets and drop incoming data. */ - STATE_OK = 1, - STATE_ESC = 2, - STATE_RUBBISH = 3, -}; - -/* - * Variables begin and end manage the buffer space in a cyclic - * fashion. The first used byte is at begin and end is one byte past - * the last. I.e. [begin, end) is the actively used space. - * - * If begin != pkt_end we have a packet at [begin, pkt_end), - * furthermore, if state == STATE_TWOPACKETS we have one more packet at - * [pkt_end, end). If more bytes arrive in state STATE_TWOPACKETS - * they are discarded. - */ - -static uint8_t state = STATE_TWOPACKETS; -static uint16_t begin, end; -static uint8_t rxbuf[RX_BUFSIZE]; -static uint16_t pkt_end; /* SLIP_END tracker. */ - -static void (* input_callback)(void) = NULL; -/*---------------------------------------------------------------------------*/ -void -slip_set_input_callback(void (*c)(void)) -{ - input_callback = c; -} -/*---------------------------------------------------------------------------*/ -/* slip_send: forward (IPv4) packets with {UIP_FW_NETIF(..., slip_send)} - * was used in slip-bridge.c - */ -uint8_t -slip_send(struct net_buf *buf) -{ - uint16_t i; - uint8_t *ptr; - uint8_t c; - - slip_arch_writeb(SLIP_END); - - ptr = &uip_buf(buf)[UIP_LLH_LEN]; - for(i = 0; i < uip_len(buf); ++i) { - if(i == UIP_TCPIP_HLEN) { - ptr = (uint8_t *)uip_appdata(buf); - } - c = *ptr++; - if(c == SLIP_END) { - slip_arch_writeb(SLIP_ESC); - c = SLIP_ESC_END; - } else if(c == SLIP_ESC) { - slip_arch_writeb(SLIP_ESC); - c = SLIP_ESC_ESC; - } - slip_arch_writeb(c); - } - slip_arch_writeb(SLIP_END); - - return 0; /* UIP_FW_OK */ -} -/*---------------------------------------------------------------------------*/ -uint8_t -slip_write(const void *_ptr, int len) -{ - const uint8_t *ptr = _ptr; - uint16_t i; - uint8_t c; - - slip_arch_writeb(SLIP_END); - - for(i = 0; i < len; ++i) { - c = *ptr++; - if(c == SLIP_END) { - slip_arch_writeb(SLIP_ESC); - c = SLIP_ESC_END; - } else if(c == SLIP_ESC) { - slip_arch_writeb(SLIP_ESC); - c = SLIP_ESC_ESC; - } - slip_arch_writeb(c); - } - slip_arch_writeb(SLIP_END); - - return len; -} -/*---------------------------------------------------------------------------*/ -static void -rxbuf_init(void) -{ - begin = end = pkt_end = 0; - state = STATE_OK; -} -/*---------------------------------------------------------------------------*/ -/* Upper half does the polling. */ -static uint16_t -slip_poll_handler(uint8_t *outbuf, uint16_t blen) -{ - /* This is a hack and won't work across buffer edge! */ - if(rxbuf[begin] == 'C') { - int i; - if(begin < end && (end - begin) >= 6 - && memcmp(&rxbuf[begin], "CLIENT", 6) == 0) { - state = STATE_TWOPACKETS; /* Interrupts do nothing. */ - memset(&rxbuf[begin], 0x0, 6); - - rxbuf_init(); - - for(i = 0; i < 13; i++) { - slip_arch_writeb("CLIENTSERVER\300"[i]); - } - return 0; - } - } -#ifdef SLIP_CONF_ANSWER_MAC_REQUEST - else if(rxbuf[begin] == '?') { - /* Used by tapslip6 to request mac for auto configure */ - int j, addr_len; - linkaddr_t *addr; - char* hexchar = "0123456789abcdef"; - if(begin < end && (end - begin) >= 2 - && rxbuf[begin + 1] == 'M') { - state = STATE_TWOPACKETS; /* Interrupts do nothing. */ - rxbuf[begin] = 0; - rxbuf[begin + 1] = 0; - - rxbuf_init(); - - addr = linkaddr_get_node_addr(&addr_len); - /* this is just a test so far... just to see if it works */ - slip_arch_writeb('!'); - slip_arch_writeb('M'); - for(j = 0; j < addr_len; j++) { - slip_arch_writeb(hexchar[addr->u8[j] >> 4]); - slip_arch_writeb(hexchar[addr->u8[j] & 15]); - } - slip_arch_writeb(SLIP_END); - return 0; - } - } -#endif /* SLIP_CONF_ANSWER_MAC_REQUEST */ - - /* - * Interrupt can not change begin but may change pkt_end. - * If pkt_end != begin it will not change again. - */ - if(begin != pkt_end) { - uint16_t len; - - if(begin < pkt_end) { - len = pkt_end - begin; - if(len > blen) { - len = 0; - } else { - memcpy(outbuf, &rxbuf[begin], len); - } - } else { - len = (RX_BUFSIZE - begin) + (pkt_end - 0); - if(len > blen) { - len = 0; - } else { - unsigned i; - for(i = begin; i < RX_BUFSIZE; i++) { - *outbuf++ = rxbuf[i]; - } - for(i = 0; i < pkt_end; i++) { - *outbuf++ = rxbuf[i]; - } - } - } - - /* Remove data from buffer together with the copied packet. */ - begin = pkt_end; - if(state == STATE_TWOPACKETS) { - pkt_end = end; - state = STATE_OK; /* Assume no bytes where lost! */ - - /* One more packet is buffered, need to be polled again! */ - process_poll(&slip_process); - } - return len; - } - - return 0; -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(slip_process, ev, data, not_used, user_data) -{ - struct net_buf *buf; - - PROCESS_BEGIN(); - - rxbuf_init(); - - while(1) { - PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); - - slip_active = 1; - - buf = ip_buf_get_reserve_rx(0); - if (!buf) { - NET_ERR("No RX buffers left, slip msg discarded\n"); - rxbuf_init(); - continue; - } - - /* Move packet from rxbuf to buffer provided by uIP. */ - uip_len(buf) = slip_poll_handler(&uip_buf(buf)[UIP_LLH_LEN], - UIP_BUFSIZE - UIP_LLH_LEN); -#if !NETSTACK_CONF_WITH_IPV6 - if(uip_len(buf) == 4 && strncmp((char*)&uip_buf(buf)[UIP_LLH_LEN], "?IPA", 4) == 0) { - char sbuf[8]; - memcpy(&sbuf[0], "=IPA", 4); - memcpy(&sbuf[4], &uip_hostaddr, 4); - if(input_callback) { - input_callback(); - } - slip_write(sbuf, 8); - /* If the packet is being discarded in uip.c:uip_input(), then the - * uip_len(buf) is set to 0. If that is done, then do not release - * the buffer here as that would cause double free. - */ - if (uip_len(buf) != 0) { - ip_buf_unref(buf); - } - } else if(uip_len(buf) > 0 - && uip_len(buf) == (((uint16_t)(BUF(buf)->len[0]) << 8) + BUF(buf)->len[1]) - && uip_ipchksum(buf) == 0xffff) { -#define IP_DF 0x40 - if(BUF(buf)->ipid[0] == 0 && BUF(buf)->ipid[1] == 0 && BUF(buf)->ipoffset[0] & IP_DF) { - static uint16_t ip_id; - uint16_t nid = ip_id++; - BUF(buf)->ipid[0] = nid >> 8; - BUF(buf)->ipid[1] = nid; - nid = uip_htons(nid); - nid = ~nid; /* negate */ - BUF(buf)->ipchksum += nid; /* add */ - if(BUF(buf)->ipchksum < nid) { /* 1-complement overflow? */ - BUF(buf)->ipchksum++; - } - } - - net_buf_add(buf, uip_len(buf)); - -#ifdef SLIP_CONF_TCPIP_INPUT - if (SLIP_CONF_TCPIP_INPUT(buf) < 0) { - ip_buf_unref(buf); - } -#else - tcpip_input(buf); -#endif - } else { - NET_DBG("Dropping slip message buf %p\n", buf); - uip_len(buf) = 0; - ip_buf_unref(buf); - SLIP_STATISTICS(slip_ip_drop++); - } -#else /* NETSTACK_CONF_WITH_IPV6 */ - if(uip_len(buf) > 0) { - net_buf_add(buf, uip_len(buf)); - - if(input_callback) { - input_callback(); - } -#ifdef SLIP_CONF_TCPIP_INPUT - if (SLIP_CONF_TCPIP_INPUT(buf) < 0) { - ip_buf_unref(buf); - } -#else - tcpip_input(buf); -#endif - } -#endif /* NETSTACK_CONF_WITH_IPV6 */ - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ -int -slip_input_byte(unsigned char c) -{ - switch(state) { - case STATE_RUBBISH: - if(c == SLIP_END) { - state = STATE_OK; - } - return 0; - - case STATE_TWOPACKETS: /* Two packets are already buffered! */ - return 0; - - case STATE_ESC: - if(c == SLIP_ESC_END) { - c = SLIP_END; - } else if(c == SLIP_ESC_ESC) { - c = SLIP_ESC; - } else { - state = STATE_RUBBISH; - SLIP_STATISTICS(slip_rubbish++); - end = pkt_end; /* remove rubbish */ - return 0; - } - state = STATE_OK; - break; - - case STATE_OK: - if(c == SLIP_ESC) { - state = STATE_ESC; - return 0; - } else if(c == SLIP_END) { - /* - * We have a new packet, possibly of zero length. - * - * There may already be one packet buffered. - */ - if(end != pkt_end) { /* Non zero length. */ - if(begin == pkt_end) { /* None buffered. */ - pkt_end = end; - } else { - state = STATE_TWOPACKETS; - SLIP_STATISTICS(slip_twopackets++); - } - process_poll(&slip_process); - return 1; - } - return 0; - } - break; - } - - /* add_char: */ - { - unsigned next; - next = end + 1; - if(next == RX_BUFSIZE) { - next = 0; - } - if(next == begin) { /* rxbuf is full */ - state = STATE_RUBBISH; - SLIP_STATISTICS(slip_overflow++); - end = pkt_end; /* remove rubbish */ - return 0; - } - rxbuf[end] = c; - end = next; - } - - /* There could be a separate poll routine for this. */ - if(c == 'T' && rxbuf[begin] == 'C') { - process_poll(&slip_process); - return 1; - } - - return 0; -} -/*---------------------------------------------------------------------------*/ - -void slip_recv(void) -{ - process_post_synch(&slip_process, PROCESS_EVENT_POLL, NULL, NULL); -} - -/*---------------------------------------------------------------------------*/ -static uint8_t *recv_cb(uint8_t *buf, size_t *off) -{ - int i; - - for (i = 0; i < *off; i++) { - if (slip_input_byte(buf[i])) { - /* - * The magic happens in slip.c:PROCESS_THREAD() - * It will copy the slip.c internal buffer into - * net_buf and call IP stack input function. The input - * function is set to net_recv() which will then - * feed the buffer into rx fiber. - */ - slip_recv(); - break; - } - } - - *off = 0; - return buf; -} - -/*---------------------------------------------------------------------------*/ -void slip_start(void) -{ - /* Use small temp buffer for receiving data */ - static uint8_t buf[32]; - - uart_pipe_register(buf, sizeof(buf), recv_cb); - - process_start(&slip_process, NULL, NULL); -} - -#endif /* defined(CONFIG_NETWORKING_UART) */ diff --git a/net/ip/contiki/os/dev/slip.h b/net/ip/contiki/os/dev/slip.h deleted file mode 100644 index bca0c1a0dc06f369f92ccb7ee22fbb1a7ae6174f..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/dev/slip.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- C -*- */ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#ifndef SLIP_H_ -#define SLIP_H_ - -#if defined(CONFIG_NETWORKING_UART) - -#include - -#include "contiki.h" - -PROCESS_NAME(slip_process); - -/** - * Send an IP packet from the uIP buffer with SLIP. - */ -uint8_t slip_send(struct net_buf *buf); - -/** - * Input a SLIP byte. - * - * This function is called by the RS232/SIO device driver to pass - * incoming bytes to the SLIP driver. The function can be called from - * an interrupt context. - * - * For systems using low-power CPU modes, the return value of the - * function can be used to determine if the CPU should be woken up or - * not. If the function returns non-zero, the CPU should be powered - * up. If the function returns zero, the CPU can continue to be - * powered down. - * - * \param c The data that is to be passed to the SLIP driver - * - * \return Non-zero if the CPU should be powered up, zero otherwise. - */ -int slip_input_byte(unsigned char c); - -uint8_t slip_write(const void *ptr, int len); - -/* Did we receive any bytes lately? */ -extern uint8_t slip_active; - -/* Statistics. */ -extern uint16_t slip_rubbish, slip_twopackets, slip_overflow, slip_ip_drop; - -/** - * Set a function to be called when there is activity on the SLIP - * interface; used for detecting if a node is a gateway node. - */ -void slip_set_input_callback(void (*callback)(void)); - -/* - * These machine dependent functions and an interrupt service routine - * must be provided externally (slip_arch.c). - */ -void slip_arch_init(unsigned long ubr); -void slip_arch_writeb(unsigned char c); - -void slip_start(void); - -void slip_recv(void); - -/* We do not want the packet to directly go to tcpip_input() because - * the packet is received in interrupt context. We instead use the - * net_recv() to place the packet into rx fiber which then calls - * the tcpip_input() - */ -#define SLIP_CONF_TCPIP_INPUT(buf) net_recv(buf) - -#else /* defined(CONFIG_NETWORKING_UART) */ - -#define slip_start(...) -#define slip_recv(...) - -#endif /* defined(CONFIG_NETWORKING_UART) */ - -#endif /* SLIP_H_ */ diff --git a/net/ip/contiki/os/dev/watchdog.h b/net/ip/contiki/os/dev/watchdog.h deleted file mode 100644 index d480d0f61a68bc20d22285e4b34bbe113ce9615e..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/dev/watchdog.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ -#ifndef WATCHDOG_H_ -#define WATCHDOG_H_ - -void watchdog_init(void); -void watchdog_start(void); -static inline void watchdog_periodic(void) { } /* FIXME - code needed here */ -void watchdog_stop(void); - -void watchdog_reboot(void); - -#endif /* WATCHDOG_H_ */ diff --git a/net/ip/contiki/os/lib/aes-128.c b/net/ip/contiki/os/lib/aes-128.c deleted file mode 100644 index 473adf6fc7286671ad258e3a548cdbfe2debcfe4..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/lib/aes-128.c +++ /dev/null @@ -1,198 +0,0 @@ -/* --COPYRIGHT--,BSD - * Copyright (c) 2011, Texas Instruments Incorporated - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * --/COPYRIGHT--*/ -/* - * TI_aes_128_encr_only.c - * - * Created on: Nov 3, 2011 - * Author: Eric Peeters - */ - -/** - * \file - * Wrapped AES-128 implementation from Texas Instruments. - * \author - * Konrad Krentz - */ - -#include "lib/aes-128.h" -#include - -static const uint8_t sbox[256] = { -0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, -0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, -0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, -0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, -0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, -0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, -0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, -0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, -0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, -0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, -0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, -0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, -0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, -0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, -0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, -0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; - -static uint8_t round_keys[11][AES_128_KEY_LENGTH]; - -/*---------------------------------------------------------------------------*/ -/* multiplies by 2 in GF(2) */ -static uint8_t -galois_mul2(uint8_t value) -{ - if(value >> 7) { - value = value << 1; - return value ^ 0x1b; - } else { - return value << 1; - } -} -/*---------------------------------------------------------------------------*/ -static void -set_key(uint8_t *key) -{ - uint8_t i; - uint8_t j; - uint8_t rcon; - - rcon = 0x01; - memcpy(round_keys[0], key, AES_128_KEY_LENGTH); - for(i = 1; i <= 10; i++) { - round_keys[i][0] = sbox[round_keys[i - 1][13]] ^ round_keys[i - 1][0] ^ rcon; - round_keys[i][1] = sbox[round_keys[i - 1][14]] ^ round_keys[i - 1][1]; - round_keys[i][2] = sbox[round_keys[i - 1][15]] ^ round_keys[i - 1][2]; - round_keys[i][3] = sbox[round_keys[i - 1][12]] ^ round_keys[i - 1][3]; - for(j = 4; j < AES_128_BLOCK_SIZE; j++) { - round_keys[i][j] = round_keys[i - 1][j] ^ round_keys[i][j - 4]; - } - rcon = galois_mul2(rcon); - } -} -/*---------------------------------------------------------------------------*/ -static void -encrypt(uint8_t *state) -{ - uint8_t buf1, buf2, buf3, buf4, round, i; - - /* round 0 */ - /* AddRoundKey */ - for(i = 0; i < AES_128_BLOCK_SIZE; i++) { - state[i] = state[i] ^ round_keys[0][i]; - } - - for(round = 1; round <= 10; round++) { - /* ByteSub */ - for(i = 0; i < AES_128_BLOCK_SIZE; i++) { - state[i] = sbox[state[i]]; - } - - /* ShiftRow */ - buf1 = state[1]; - state[1] = state[5]; - state[5] = state[9]; - state[9] = state[13]; - state[13] = buf1; - - buf1 = state[2]; - buf2 = state[6]; - state[2] = state[10]; - state[6] = state[14]; - state[10] = buf1; - state[14] = buf2; - - buf1 = state[15]; - state[15] = state[11]; - state[11] = state[7]; - state[7] = state[3]; - state[3] = buf1; - - /* last round skips MixColumn */ - if(round < 10) { - /* MixColumn */ - for(i = 0; i < 4; i++) { - buf4 = (i << 2); - buf1 = state[buf4] ^ state[buf4 + 1] ^ state[buf4 + 2] ^ state[buf4 + 3]; - buf2 = state[buf4]; - buf3 = state[buf4] ^ state[buf4 + 1]; - buf3 = galois_mul2(buf3); - - state[buf4] = state[buf4] ^ buf3 ^ buf1; - - buf3 = state[buf4 + 1] ^ state[buf4 + 2]; - buf3 = galois_mul2(buf3); - state[buf4 + 1] = state[buf4 + 1] ^ buf3 ^ buf1; - - buf3 = state[buf4 + 2] ^ state[buf4 + 3]; - buf3 = galois_mul2(buf3); - state[buf4 + 2] = state[buf4 + 2] ^ buf3 ^ buf1; - - buf3 = state[buf4 + 3] ^ buf2; - buf3 = galois_mul2(buf3); - state[buf4 + 3] = state[buf4 + 3] ^ buf3 ^ buf1; - } - } - - /* AddRoundKey */ - for(i = 0; i < AES_128_BLOCK_SIZE; i++) { - state[i] = state[i] ^ round_keys[round][i]; - } - } -} -/*---------------------------------------------------------------------------*/ -void -aes_128_padded_encrypt(uint8_t *plaintext_and_result, uint8_t plaintext_len) -{ - uint8_t block[AES_128_BLOCK_SIZE]; - - memset(block, 0, AES_128_BLOCK_SIZE); - memcpy(block, plaintext_and_result, plaintext_len); - AES_128.encrypt(block); - memcpy(plaintext_and_result, block, plaintext_len); -} -/*---------------------------------------------------------------------------*/ -void -aes_128_set_padded_key(uint8_t *key, uint8_t key_len) -{ - uint8_t block[AES_128_BLOCK_SIZE]; - - memset(block, 0, AES_128_BLOCK_SIZE); - memcpy(block, key, key_len); - AES_128.set_key(block); -} -/*---------------------------------------------------------------------------*/ -const struct aes_128_driver aes_128_driver = { - set_key, - encrypt -}; -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/contiki/os/lib/aes-128.h b/net/ip/contiki/os/lib/aes-128.h deleted file mode 100644 index a16155b4fb10964d63349e6440297abc87465b89..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/lib/aes-128.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2013, Hasso-Plattner-Institut. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * AES-128. - * \author - * Konrad Krentz - */ - -#ifndef AES_H_ -#define AES_H_ - -#include "contiki.h" - -#define AES_128_BLOCK_SIZE 16 -#define AES_128_KEY_LENGTH 16 - -#ifdef AES_128_CONF -#define AES_128 AES_128_CONF -#else /* AES_128_CONF */ -#define AES_128 aes_128_driver -#endif /* AES_128_CONF */ - -/** - * Structure of AES drivers. - */ -struct aes_128_driver { - - /** - * \brief Sets the current key. - */ - void (* set_key)(uint8_t *key); - - /** - * \brief Encrypts. - */ - void (* encrypt)(uint8_t *plaintext_and_result); -}; - -/** - * \brief Pads the plaintext with zeroes before calling AES_128.encrypt - */ -void aes_128_padded_encrypt(uint8_t *plaintext_and_result, uint8_t plaintext_len); - -/** - * \brief Pads the key with zeroes before calling AES_128.set_key - */ -void aes_128_set_padded_key(uint8_t *key, uint8_t key_len); - -extern const struct aes_128_driver AES_128; - -#endif /* AES_H_ */ diff --git a/net/ip/contiki/os/lib/list.c b/net/ip/contiki/os/lib/list.c deleted file mode 100644 index 401da617ea0181d20cc5c0673b4128353513cb08..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/lib/list.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ - -/** - * \file - * Linked list library implementation. - * - * \author Adam Dunkels - * - */ - -/** - * \addtogroup list - * @{ - */ - -#include "lib/list.h" - -#define NULL 0 - -struct list { - struct list *next; -}; - -/*---------------------------------------------------------------------------*/ -/** - * Initialize a list. - * - * This function initalizes a list. The list will be empty after this - * function has been called. - * - * \param list The list to be initialized. - */ -void -list_init(list_t list) -{ - *list = NULL; -} -/*---------------------------------------------------------------------------*/ -/** - * Get a pointer to the first element of a list. - * - * This function returns a pointer to the first element of the - * list. The element will \b not be removed from the list. - * - * \param list The list. - * \return A pointer to the first element on the list. - * - * \sa list_tail() - */ -void * -list_head(list_t list) -{ - return *list; -} -/*---------------------------------------------------------------------------*/ -/** - * Duplicate a list. - * - * This function duplicates a list by copying the list reference, but - * not the elements. - * - * \note This function does \b not copy the elements of the list, but - * merely duplicates the pointer to the first element of the list. - * - * \param dest The destination list. - * \param src The source list. - */ -void -list_copy(list_t dest, list_t src) -{ - *dest = *src; -} -/*---------------------------------------------------------------------------*/ -/** - * Get the tail of a list. - * - * This function returns a pointer to the elements following the first - * element of a list. No elements are removed by this function. - * - * \param list The list - * \return A pointer to the element after the first element on the list. - * - * \sa list_head() - */ -void * -list_tail(list_t list) -{ - struct list *l; - - if(*list == NULL) { - return NULL; - } - - for(l = *list; l->next != NULL; l = l->next); - - return l; -} -/*---------------------------------------------------------------------------*/ -/** - * Add an item at the end of a list. - * - * This function adds an item to the end of the list. - * - * \param list The list. - * \param item A pointer to the item to be added. - * - * \sa list_push() - * - */ -void -list_add(list_t list, void *item) -{ - struct list *l; - - /* Make sure not to add the same element twice */ - list_remove(list, item); - - ((struct list *)item)->next = NULL; - - l = list_tail(list); - - if(l == NULL) { - *list = item; - } else { - l->next = item; - } -} -/*---------------------------------------------------------------------------*/ -/** - * Add an item to the start of the list. - */ -void -list_push(list_t list, void *item) -{ - /* struct list *l;*/ - - /* Make sure not to add the same element twice */ - list_remove(list, item); - - ((struct list *)item)->next = *list; - *list = item; -} -/*---------------------------------------------------------------------------*/ -/** - * Remove the last object on the list. - * - * This function removes the last object on the list and returns it. - * - * \param list The list - * \return The removed object - * - */ -void * -list_chop(list_t list) -{ - struct list *l, *r; - - if(*list == NULL) { - return NULL; - } - if(((struct list *)*list)->next == NULL) { - l = *list; - *list = NULL; - return l; - } - - for(l = *list; l->next->next != NULL; l = l->next); - - r = l->next; - l->next = NULL; - - return r; -} -/*---------------------------------------------------------------------------*/ -/** - * Remove the first object on a list. - * - * This function removes the first object on the list and returns a - * pointer to it. - * - * \param list The list. - * \return Pointer to the removed element of list. - */ -/*---------------------------------------------------------------------------*/ -void * -list_pop(list_t list) -{ - struct list *l; - l = *list; - if(*list != NULL) { - *list = ((struct list *)*list)->next; - } - - return l; -} -/*---------------------------------------------------------------------------*/ -/** - * Remove a specific element from a list. - * - * This function removes a specified element from the list. - * - * \param list The list. - * \param item The item that is to be removed from the list. - * - */ -/*---------------------------------------------------------------------------*/ -void -list_remove(list_t list, void *item) -{ - struct list *l, *r; - - if(*list == NULL) { - return; - } - - r = NULL; - for(l = *list; l != NULL; l = l->next) { - if(l == item) { - if(r == NULL) { - /* First on list */ - *list = l->next; - } else { - /* Not first on list */ - r->next = l->next; - } - l->next = NULL; - return; - } - r = l; - } -} -/*---------------------------------------------------------------------------*/ -/** - * Get the length of a list. - * - * This function counts the number of elements on a specified list. - * - * \param list The list. - * \return The length of the list. - */ -/*---------------------------------------------------------------------------*/ -int -list_length(list_t list) -{ - struct list *l; - int n = 0; - - for(l = *list; l != NULL; l = l->next) { - ++n; - } - - return n; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Insert an item after a specified item on the list - * \param list The list - * \param previtem The item after which the new item should be inserted - * \param newitem The new item that is to be inserted - * \author Adam Dunkels - * - * This function inserts an item right after a specified - * item on the list. This function is useful when using - * the list module to ordered lists. - * - * If previtem is NULL, the new item is placed at the - * start of the list. - * - */ -void -list_insert(list_t list, void *previtem, void *newitem) -{ - if(previtem == NULL) { - list_push(list, newitem); - } else { - - ((struct list *)newitem)->next = ((struct list *)previtem)->next; - ((struct list *)previtem)->next = newitem; - } -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Get the next item following this item - * \param item A list item - * \returns A next item on the list - * - * This function takes a list item and returns the next - * item on the list, or NULL if there are no more items on - * the list. This function is used when iterating through - * lists. - */ -void * -list_item_next(void *item) -{ - return item == NULL? NULL: ((struct list *)item)->next; -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/os/lib/list.h b/net/ip/contiki/os/lib/list.h deleted file mode 100644 index 0624682a28c20c282797ee5df7c2cc7b49bd228e..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/lib/list.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ - -/** - * \file - * Linked list manipulation routines. - * \author Adam Dunkels - * - */ - -/** \addtogroup lib - @{ */ -/** - * \defgroup list Linked list library - * - * The linked list library provides a set of functions for - * manipulating linked lists. - * - * A linked list is made up of elements where the first element \b - * must be a pointer. This pointer is used by the linked list library - * to form lists of the elements. - * - * Lists are declared with the LIST() macro. The declaration specifies - * the name of the list that later is used with all list functions. - * - * Lists can be manipulated by inserting or removing elements from - * either sides of the list (list_push(), list_add(), list_pop(), - * list_chop()). A specified element can also be removed from inside a - * list with list_remove(). The head and tail of a list can be - * extracted using list_head() and list_tail(), respectively. - * - * @{ - */ - -#ifndef LIST_H_ -#define LIST_H_ - -#define LIST_CONCAT2(s1, s2) s1##s2 -#define LIST_CONCAT(s1, s2) LIST_CONCAT2(s1, s2) - -/** - * Declare a linked list. - * - * This macro declares a linked list with the specified \c type. The - * type \b must be a structure (\c struct) with its first element - * being a pointer. This pointer is used by the linked list library to - * form the linked lists. - * - * The list variable is declared as static to make it easy to use in a - * single C module without unnecessarily exporting the name to other - * modules. - * - * \param name The name of the list. - */ -#define LIST(name) \ - static void *LIST_CONCAT(name,_list) = NULL; \ - static list_t name = (list_t)&LIST_CONCAT(name,_list) - -/** - * Declare a linked list inside a structure declaraction. - * - * This macro declares a linked list with the specified \c type. The - * type \b must be a structure (\c struct) with its first element - * being a pointer. This pointer is used by the linked list library to - * form the linked lists. - * - * Internally, the list is defined as two items: the list itself and a - * pointer to the list. The pointer has the name of the parameter to - * the macro and the name of the list is a concatenation of the name - * and the suffix "_list". The pointer must point to the list for the - * list to work. Thus the list must be initialized before using. - * - * The list is initialized with the LIST_STRUCT_INIT() macro. - * - * \param name The name of the list. - */ -#define LIST_STRUCT(name) \ - void *LIST_CONCAT(name,_list); \ - list_t name - -/** - * Initialize a linked list that is part of a structure. - * - * This macro sets up the internal pointers in a list that has been - * defined as part of a struct. This macro must be called before using - * the list. - * - * \param struct_ptr A pointer to the struct - * \param name The name of the list. - */ -#define LIST_STRUCT_INIT(struct_ptr, name) \ - do { \ - (struct_ptr)->name = &((struct_ptr)->LIST_CONCAT(name,_list)); \ - (struct_ptr)->LIST_CONCAT(name,_list) = NULL; \ - list_init((struct_ptr)->name); \ - } while(0) - -/** - * The linked list type. - * - */ -typedef void ** list_t; - -void list_init(list_t list); -void * list_head(list_t list); -void * list_tail(list_t list); -void * list_pop (list_t list); -void list_push(list_t list, void *item); - -void * list_chop(list_t list); - -void list_add(list_t list, void *item); -void list_remove(list_t list, void *item); - -int list_length(list_t list); - -void list_copy(list_t dest, list_t src); - -void list_insert(list_t list, void *previtem, void *newitem); - -void * list_item_next(void *item); - -#endif /* LIST_H_ */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/os/lib/memb.c b/net/ip/contiki/os/lib/memb.c deleted file mode 100644 index b4056dd9faa3fadb205712070adc903b77662d4e..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/lib/memb.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ - -/** - * \addtogroup memb - * @{ - */ - - /** - * \file - * Memory block allocation routines. - * \author Adam Dunkels - */ -#include - -#include "contiki.h" -#include "lib/memb.h" - -/*---------------------------------------------------------------------------*/ -void -memb_init(struct memb *m) -{ - memset(m->count, 0, m->num); - memset(m->mem, 0, m->size * m->num); -} -/*---------------------------------------------------------------------------*/ -void * -memb_alloc(struct memb *m) -{ - int i; - - for(i = 0; i < m->num; ++i) { - if(m->count[i] == 0) { - /* If this block was unused, we increase the reference count to - indicate that it now is used and return a pointer to the - memory block. */ - ++(m->count[i]); - return (void *)((char *)m->mem + (i * m->size)); - } - } - - /* No free block was found, so we return NULL to indicate failure to - allocate block. */ - return NULL; -} -/*---------------------------------------------------------------------------*/ -char -memb_free(struct memb *m, void *ptr) -{ - int i; - char *ptr2; - - /* Walk through the list of blocks and try to find the block to - which the pointer "ptr" points to. */ - ptr2 = (char *)m->mem; - for(i = 0; i < m->num; ++i) { - - if(ptr2 == (char *)ptr) { - /* We've found to block to which "ptr" points so we decrease the - reference count and return the new value of it. */ - if(m->count[i] > 0) { - /* Make sure that we don't deallocate free memory. */ - --(m->count[i]); - } - return m->count[i]; - } - ptr2 += m->size; - } - return -1; -} -/*---------------------------------------------------------------------------*/ -int -memb_inmemb(struct memb *m, void *ptr) -{ - return (char *)ptr >= (char *)m->mem && - (char *)ptr < (char *)m->mem + (m->num * m->size); -} -/*---------------------------------------------------------------------------*/ -int -memb_numfree(struct memb *m) -{ - int i; - int num_free = 0; - - for(i = 0; i < m->num; ++i) { - if(m->count[i] == 0) { - ++num_free; - } - } - - return num_free; -} -/** @} */ diff --git a/net/ip/contiki/os/lib/memb.h b/net/ip/contiki/os/lib/memb.h deleted file mode 100644 index d66e5a419e076be614d1e4c081776c41ccd91c7e..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/lib/memb.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ - -/** - * \addtogroup mem - * @{ - */ - - -/** - * \defgroup memb Memory block management functions - * - * The memory block allocation routines provide a simple yet powerful - * set of functions for managing a set of memory blocks of fixed - * size. A set of memory blocks is statically declared with the - * MEMB() macro. Memory blocks are allocated from the declared - * memory by the memb_alloc() function, and are deallocated with the - * memb_free() function. - * - * @{ - */ - - -/** - * \file - * Memory block allocation routines. - * \author - * Adam Dunkels - * - */ - -#ifndef MEMB_H_ -#define MEMB_H_ - -#include "sys/cc.h" - -/** - * Declare a memory block. - * - * This macro is used to statically declare a block of memory that can - * be used by the block allocation functions. The macro statically - * declares a C array with a size that matches the specified number of - * blocks and their individual sizes. - * - * Example: - \code -MEMB(connections, struct connection, 16); - \endcode - * - * \param name The name of the memory block (later used with - * memb_init(), memb_alloc() and memb_free()). - * - * \param structure The name of the struct that the memory block holds - * - * \param num The total number of memory chunks in the block. - * - */ -#define MEMB(name, structure, num) \ - static char CC_CONCAT(name,_memb_count)[num]; \ - static structure CC_CONCAT(name,_memb_mem)[num]; \ - static struct memb name = {sizeof(structure), num, \ - CC_CONCAT(name,_memb_count), \ - (void *)CC_CONCAT(name,_memb_mem)} - -struct memb { - unsigned short size; - unsigned short num; - char *count; - void *mem; -}; - -/** - * Initialize a memory block that was declared with MEMB(). - * - * \param m A memory block previously declared with MEMB(). - */ -void memb_init(struct memb *m); - -/** - * Allocate a memory block from a block of memory declared with MEMB(). - * - * \param m A memory block previously declared with MEMB(). - */ -void *memb_alloc(struct memb *m); - -/** - * Deallocate a memory block from a memory block previously declared - * with MEMB(). - * - * \param m m A memory block previously declared with MEMB(). - * - * \param ptr A pointer to the memory block that is to be deallocated. - * - * \return The new reference count for the memory block (should be 0 - * if successfully deallocated) or -1 if the pointer "ptr" did not - * point to a legal memory block. - */ -char memb_free(struct memb *m, void *ptr); - -int memb_inmemb(struct memb *m, void *ptr); - -int memb_numfree(struct memb *m); - -/** @} */ -/** @} */ - -#endif /* MEMB_H_ */ diff --git a/net/ip/contiki/os/lib/mmem.c b/net/ip/contiki/os/lib/mmem.c deleted file mode 100644 index 20c7390fd5e4ecc5c564af23db19a95dfdbcdade..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/lib/mmem.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \addtogroup mmem - * @{ - */ - -/** - * \file - * Implementation of the managed memory allocator - * \author - * Adam Dunkels - * - */ - - -#include "mmem.h" -#include "list.h" -#include "contiki-conf.h" -#include - -#ifdef MMEM_CONF_SIZE -#define MMEM_SIZE MMEM_CONF_SIZE -#else -#define MMEM_SIZE 4096 -#endif - -LIST(mmemlist); -unsigned int avail_memory; -static char memory[MMEM_SIZE]; - -/*---------------------------------------------------------------------------*/ -/** - * \brief Allocate a managed memory block - * \param m A pointer to a struct mmem. - * \param size The size of the requested memory block - * \return Non-zero if the memory could be allocated, zero if memory - * was not available. - * \author Adam Dunkels - * - * This function allocates a chunk of managed memory. The - * memory allocated with this function must be deallocated - * using the mmem_free() function. - * - * \note This function does NOT return a pointer to the - * allocated memory, but a pointer to a structure that - * contains information about the managed memory. The - * macro MMEM_PTR() is used to get a pointer to the - * allocated memory. - * - */ -int -mmem_alloc(struct mmem *m, unsigned int size) -{ - /* Check if we have enough memory left for this allocation. */ - if(avail_memory < size) { - return 0; - } - - /* We had enough memory so we add this memory block to the end of - the list of allocated memory blocks. */ - list_add(mmemlist, m); - - /* Set up the pointer so that it points to the first available byte - in the memory block. */ - m->ptr = &memory[MMEM_SIZE - avail_memory]; - - /* Remember the size of this memory block. */ - m->size = size; - - /* Decrease the amount of available memory. */ - avail_memory -= size; - - /* Return non-zero to indicate that we were able to allocate - memory. */ - return 1; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Deallocate a managed memory block - * \param m A pointer to the managed memory block - * \author Adam Dunkels - * - * This function deallocates a managed memory block that - * previously has been allocated with mmem_alloc(). - * - */ -void -mmem_free(struct mmem *m) -{ - struct mmem *n; - - if(m->next != NULL) { - /* Compact the memory after the allocation that is to be removed - by moving it downwards. */ - memmove(m->ptr, m->next->ptr, - &memory[MMEM_SIZE - avail_memory] - (char *)m->next->ptr); - - /* Update all the memory pointers that points to memory that is - after the allocation that is to be removed. */ - for(n = m->next; n != NULL; n = n->next) { - n->ptr = (void *)((char *)n->ptr - m->size); - } - } - - avail_memory += m->size; - - /* Remove the memory block from the list. */ - list_remove(mmemlist, m); -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Initialize the managed memory module - * \author Adam Dunkels - * - * This function initializes the managed memory module and - * should be called before any other function from the - * module. - * - */ -void -mmem_init(void) -{ - static int inited = 0; - if(inited) { - return; - } - list_init(mmemlist); - avail_memory = MMEM_SIZE; - inited = 1; -} -/*---------------------------------------------------------------------------*/ - -/** @} */ diff --git a/net/ip/contiki/os/lib/mmem.h b/net/ip/contiki/os/lib/mmem.h deleted file mode 100644 index e075f585bc72562e3de5fbdfb0d5e3ef527ea957..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/lib/mmem.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ -/** - * \addtogroup mem - * @{ - */ - -/** - * \defgroup mmem Managed memory allocator - * - * The managed memory allocator is a fragmentation-free memory - * manager. It keeps the allocated memory free from fragmentation by - * compacting the memory when blocks are freed. A program that uses - * the managed memory module cannot be sure that allocated memory - * stays in place. Therefore, a level of indirection is used: access - * to allocated memory must always be done using a special macro. - * - * \note This module has not been heavily tested. - * @{ - */ - -/** - * \file - * Header file for the managed memory allocator - * \author - * Adam Dunkels - * - */ - -#ifndef MMEM_H_ -#define MMEM_H_ - -/*---------------------------------------------------------------------------*/ -/** - * \brief Get a pointer to the managed memory - * \param m A pointer to the struct mmem - * \return A pointer to the memory block, or NULL if memory could - * not be allocated. - * \author Adam Dunkels - * - * This macro is used to get a pointer to a memory block - * allocated with mmem_alloc(). - * - * \hideinitializer - */ -#define MMEM_PTR(m) (struct mmem *)(m)->ptr - -struct mmem { - struct mmem *next; - unsigned int size; - void *ptr; -}; - -/* XXX: tagga minne med "interrupt usage", vilke gör att man är - speciellt varsam under free(). */ - -int mmem_alloc(struct mmem *m, unsigned int size); -void mmem_free(struct mmem *); -void mmem_init(void); - -#endif /* MMEM_H_ */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/os/lib/random.c b/net/ip/contiki/os/lib/random.c deleted file mode 100644 index f62d4fdf26e559b33ebf6d030a8adffb928ad61a..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/lib/random.c +++ /dev/null @@ -1,36 +0,0 @@ -/* random.c - Random number API */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include "lib/random.h" - -void random_init(unsigned short seed) -{ - -} - -unsigned short random_rand(void) -{ - /* FIXME: At the moment there is no random number generator - * implemented so fix this func when random numbers - * are available. - */ - return (unsigned short)sys_cycle_get_32(); -} diff --git a/net/ip/contiki/os/lib/random.h b/net/ip/contiki/os/lib/random.h deleted file mode 100644 index cb206e23b63265ad409e53e6cf1268088a69f38e..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/lib/random.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ -#ifndef RANDOM_H_ -#define RANDOM_H_ - -/* - * Initialize the pseudo-random generator. - * - */ -void random_init(unsigned short seed); - -/* - * Calculate a pseudo random number between 0 and 65535. - * - * \return A pseudo-random number between 0 and 65535. - */ -unsigned short random_rand(void); - -/* In gcc int rand() uses RAND_MAX and long random() uses RANDOM_MAX */ -/* Since random_rand casts to unsigned short, we'll use this maxmimum */ -#define RANDOM_RAND_MAX 65535U - -#endif /* RANDOM_H_ */ diff --git a/net/ip/contiki/os/rtimer-arch.h b/net/ip/contiki/os/rtimer-arch.h deleted file mode 100644 index 33a7c9a83eb4aa93050f957ff5f6a8974f7d189c..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/rtimer-arch.h +++ /dev/null @@ -1,33 +0,0 @@ -/* FIXME - dummy file to be replaced/removed at some point */ - -/* - * Copyright (c) 2016 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __RTIMER_ARCH_H__ -#define __RTIMER_ARCH_H__ - -#include "contiki-conf.h" -#include "sys/clock.h" - -#define RTIMER_ARCH_SECOND CLOCK_CONF_SECOND - -static inline rtimer_clock_t rtimer_arch_now(void) { return clock_time(); } -int rtimer_arch_check(void); -int rtimer_arch_pending(void); -rtimer_clock_t rtimer_arch_next(void); -static inline void rtimer_arch_init(void) {} - -#endif /* __RTIMER_ARCH_H__ */ diff --git a/net/ip/contiki/os/sys/arg.c b/net/ip/contiki/os/sys/arg.c deleted file mode 100644 index 090034380726d516e8ee36bf19dfeb4a79be8f48..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/arg.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the Contiki desktop OS - * - * - */ - -/** - * \file - * Argument buffer for passing arguments when starting processes - * \author Adam Dunkels - */ - -/** - * \addtogroup sys - * @{ - */ - -/** - * \defgroup arg Argument buffer - * @{ - * - * The argument buffer can be used when passing an argument from an - * exiting process to a process that has not been created yet. Since - * the exiting process will have exited when the new process is - * started, the argument cannot be passed in any of the processes' - * addres spaces. In such situations, the argument buffer can be used. - * - * The argument buffer is statically allocated in memory and is - * globally accessible to all processes. - * - * An argument buffer is allocated with the arg_alloc() function and - * deallocated with the arg_free() function. The arg_free() function - * is designed so that it can take any pointer, not just an argument - * buffer pointer. If the pointer to arg_free() is not an argument - * buffer, the function does nothing. - */ - -#include "contiki.h" -#include "sys/arg.h" - -/** - * \internal Structure used for holding an argument buffer. - */ -struct argbuf { - char buf[128]; - char used; -}; - -static struct argbuf bufs[1]; - -/*-----------------------------------------------------------------------------------*/ -/** - * \internal Initalizer, called by the dispatcher module. - */ -/*-----------------------------------------------------------------------------------*/ -void -arg_init(void) -{ - bufs[0].used = 0; -} -/*-----------------------------------------------------------------------------------*/ -/** - * Allocates an argument buffer. - * - * \param size The requested size of the buffer, in bytes. - * - * \return Pointer to allocated buffer, or NULL if no buffer could be - * allocated. - * - * \note It currently is not possible to allocate argument buffers of - * any other size than 128 bytes. - * - */ -/*-----------------------------------------------------------------------------------*/ -char * -arg_alloc(char size) -{ - if(bufs[0].used == 0) { - bufs[0].used = 1; - return bufs[0].buf; - } - return 0; -} -/*-----------------------------------------------------------------------------------*/ -/** - * Deallocates an argument buffer. - * - * This function deallocates the argument buffer pointed to by the - * parameter, but only if the buffer actually is an argument buffer - * and is allocated. It is perfectly safe to call this function with - * any pointer. - * - * \param arg A pointer. - */ -/*-----------------------------------------------------------------------------------*/ -void -arg_free(char *arg) -{ - if(arg == bufs[0].buf) { - bufs[0].used = 0; - } -} -/*-----------------------------------------------------------------------------------*/ -/** @} */ -/** @} */ diff --git a/net/ip/contiki/os/sys/arg.h b/net/ip/contiki/os/sys/arg.h deleted file mode 100644 index 6c2d0eb19788c0bbb474174e2a02c7db42af243b..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/arg.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the Contiki desktop OS - * - * - */ -#ifndef ARG_H_ -#define ARG_H_ - -void arg_init(void); - -char *arg_alloc(char size); -void arg_free(char *arg); - -#endif /* ARG_H_ */ diff --git a/net/ip/contiki/os/sys/autostart.h b/net/ip/contiki/os/sys/autostart.h deleted file mode 100644 index a88dbd6b631206d6b43fc35b77507a0456f239d4..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/autostart.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header file for module for automatically starting and exiting a list of processes. - * \author - * Adam Dunkels - */ - -#ifndef AUTOSTART_H_ -#define AUTOSTART_H_ - -#include "sys/process.h" - -#if ! CC_NO_VA_ARGS -#if AUTOSTART_ENABLE -#define AUTOSTART_PROCESSES(...) \ -struct process * const autostart_processes[] = {__VA_ARGS__, NULL} -#else /* AUTOSTART_ENABLE */ -#define AUTOSTART_PROCESSES(...) \ -extern int _dummy -#endif /* AUTOSTART_ENABLE */ -#else -#error "C compiler must support __VA_ARGS__ macro" -#endif - -CLIF extern struct process * const autostart_processes[]; - -void autostart_start(struct process * const processes[]); -void autostart_exit(struct process * const processes[]); - -#endif /* AUTOSTART_H_ */ diff --git a/net/ip/contiki/os/sys/cc.h b/net/ip/contiki/os/sys/cc.h deleted file mode 100644 index 90ef3e710d9a1593d34534a0df02f1d072517625..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/cc.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the Contiki desktop OS - * - * - */ - -/** - * \file - * Default definitions of C compiler quirk work-arounds. - * \author Adam Dunkels - * - * This file is used for making use of extra functionality of some C - * compilers used for Contiki, and defining work-arounds for various - * quirks and problems with some other C compilers. - */ - -#ifndef CC_H_ -#define CC_H_ - -#include "contiki-conf.h" - -/** - * Configure if the C compiler supports the "register" keyword for - * function arguments. - */ -#if CC_CONF_REGISTER_ARGS -#define CC_REGISTER_ARG register -#else /* CC_CONF_REGISTER_ARGS */ -#define CC_REGISTER_ARG -#endif /* CC_CONF_REGISTER_ARGS */ - -/** - * Configure if the C compiler supports the arguments for function - * pointers. - */ -#if CC_CONF_FUNCTION_POINTER_ARGS -#define CC_FUNCTION_POINTER_ARGS 1 -#else /* CC_CONF_FUNCTION_POINTER_ARGS */ -#define CC_FUNCTION_POINTER_ARGS 0 -#endif /* CC_CONF_FUNCTION_POINTER_ARGS */ - -/** - * Configure if the C compiler supports fastcall function - * declarations. - */ -#ifdef CC_CONF_FASTCALL -#define CC_FASTCALL CC_CONF_FASTCALL -#else /* CC_CONF_FASTCALL */ -#define CC_FASTCALL -#endif /* CC_CONF_FASTCALL */ - -/** - * Configure if the C compiler have problems with const function pointers - */ -#ifdef CC_CONF_CONST_FUNCTION_BUG -#define CC_CONST_FUNCTION -#else /* CC_CONF_FASTCALL */ -#define CC_CONST_FUNCTION const -#endif /* CC_CONF_FASTCALL */ - -/** - * Configure work-around for unsigned char bugs with sdcc. - */ -#if CC_CONF_UNSIGNED_CHAR_BUGS -#define CC_UNSIGNED_CHAR_BUGS 1 -#else /* CC_CONF_UNSIGNED_CHAR_BUGS */ -#define CC_UNSIGNED_CHAR_BUGS 0 -#endif /* CC_CONF_UNSIGNED_CHAR_BUGS */ - -/** - * Configure if C compiler supports double hash marks in C macros. - */ -#if CC_CONF_DOUBLE_HASH -#define CC_DOUBLE_HASH 1 -#else /* CC_CONF_DOUBLE_HASH */ -#define CC_DOUBLE_HASH 0 -#endif /* CC_CONF_DOUBLE_HASH */ - -#ifdef CC_CONF_INLINE -#define CC_INLINE CC_CONF_INLINE -#else /* CC_CONF_INLINE */ -#define CC_INLINE -#endif /* CC_CONF_INLINE */ - -/** - * Configure if the C compiler supports the assignment of struct value. - */ -#ifdef CC_CONF_ASSIGN_AGGREGATE -#define CC_ASSIGN_AGGREGATE(dest, src) CC_CONF_ASSIGN_AGGREGATE(dest, src) -#else /* CC_CONF_ASSIGN_AGGREGATE */ -#define CC_ASSIGN_AGGREGATE(dest, src) *dest = *src -#endif /* CC_CONF_ASSIGN_AGGREGATE */ - -#if CC_CONF_NO_VA_ARGS -#define CC_NO_VA_ARGS CC_CONF_VA_ARGS -#endif - -#ifndef NULL -#define NULL 0 -#endif /* NULL */ - -#define CC_CONCAT2(s1, s2) s1##s2 -/** - * A C preprocessing macro for concatenating to - * strings. - * - * We need use two macros (CC_CONCAT and CC_CONCAT2) in order to allow - * concatenation of two \#defined macros. - */ -#define CC_CONCAT(s1, s2) CC_CONCAT2(s1, s2) - -#endif /* CC_H_ */ diff --git a/net/ip/contiki/os/sys/clock.c b/net/ip/contiki/os/sys/clock.c deleted file mode 100644 index 153beb6306f18627ae6d6b8f32138ff283960dc9..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/clock.c +++ /dev/null @@ -1,76 +0,0 @@ -/* clock.c - System specific clock routines */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "sys/clock.h" -#include - -#define DEBUG 0 -#include "contiki/ip/uip-debug.h" - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif - -static int64_t start_time; - -void clock_init(void) -{ - sys_tick_delta(&start_time); -} - -clock_time_t clock_time(void) -{ - return sys_tick_get_32(); -} - -unsigned long clock_seconds(void) -{ - return clock_time() / sys_clock_ticks_per_sec; -} - -void clock_delay(unsigned int d) -{ - switch (sys_execution_context_type_get()) { - case NANO_CTX_FIBER: - fiber_sleep(d); - break; -#ifdef CONFIG_MICROKERNEL - case NANO_CTX_TASK: - task_sleep(d); - break; -#endif - default: - return; - } -} - -/* Note that this function busy waits until the delay has passed. */ -void clock_delay_usec_busywait(uint32_t dt) -{ -#define USEC_TO_CYCLES(usec) ((usec) * sys_clock_hw_cycles_per_sec / USEC_PER_SEC) - - uint32_t usec = USEC_TO_CYCLES(dt); - uint32_t start = sys_cycle_get_32(); - - while ((start + usec) > sys_cycle_get_32()) { - } -} diff --git a/net/ip/contiki/os/sys/clock.h b/net/ip/contiki/os/sys/clock.h deleted file mode 100644 index 1c4830632a36322cf7b21782644bcc21a8666e36..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/clock.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ - -/** \addtogroup sys - * @{ - */ - -/** - * \defgroup clock Clock library - * - * The clock library is the interface between Contiki and the platform - * specific clock functionality. The clock library defines a macro, - * CLOCK_SECOND, to convert seconds into the tick resolution of the platform. - * Typically this is 1-10 milliseconds, e.g. 4*CLOCK_SECOND could be 512. - * A 16 bit counter would thus overflow every 1-10 minutes. - * Platforms use the tick interrupt to maintain a long term count - * of seconds since startup. - * - * Platforms may also implement rtimers for greater time resolution - * and for real-time interrupts, These use a corresponding RTIMER_SECOND. - * - * \note These timers do not necessarily have a common divisor or are phase locked. - * One may be crystal controlled and the other may not. Low power operation - * or sleep will often use one for wake and disable the other, then give - * it a tick correction after wakeup. - * - * \note The clock library need in many cases not be used - * directly. Rather, the \ref timer "timer library", \ref etimer - * "event timers", or \ref rtimer "rtimer library" should be used. - * - * \sa \ref timer "Timer library" - * \sa \ref etimer "Event timers" - * \sa \ref rtimer "Realtime library" - * - * @{ - */ - -#ifndef CLOCK_H_ -#define CLOCK_H_ - -#include "contiki-conf.h" - -#ifdef CONFIG_MICROKERNEL -#include -#else -#include -#endif - -/** - * A second, measured in system clock time. - * - * \hideinitializer - */ -#ifdef CLOCK_CONF_SECOND -#define CLOCK_SECOND CLOCK_CONF_SECOND -#else -#define CLOCK_SECOND (clock_time_t)32 -#endif - -/** - * Initialize the clock library. - * - * This function initializes the clock library and should be called - * from the main() function of the system. - * - */ -void clock_init(void); - -/** - * Get the current clock time. - * - * This function returns the current system clock time. - * - * \return The current clock time, measured in system ticks. - */ -CCIF clock_time_t clock_time(void); - -/** - * Get the current value of the platform seconds. - * - * This could be the number of seconds since startup, or - * since a standard epoch. - * - * \return The value. - */ -CCIF unsigned long clock_seconds(void); - -/** - * Set the value of the platform seconds. - * \param sec The value to set. - * - */ -void clock_set_seconds(unsigned long sec); - -/** - * Wait for a given number of ticks. - * \param t How many ticks. - * - */ -void clock_wait(clock_time_t t); - -/** - * Delay a given number of microseconds. - * \param dt How many microseconds to delay. - * - * \note Interrupts could increase the delay by a variable amount. - */ -void clock_delay_usec(uint16_t dt); - -void clock_delay_usec_busywait(uint32_t delay); - -#define CLOCK_CYCLE_LT(a,b) ((signed)((a)-(b)) < 0) -#define CLOCK_MSEC_TO_CYCLES(msec) (MSEC(msec) * sys_clock_us_per_tick) - -static inline uint32_t clock_get_cycle(void) -{ - return sys_cycle_get_32(); -} - -/** - * Deprecated platform-specific routines. - * - */ -int clock_fine_max(void); -unsigned short clock_fine(void); -void clock_delay(unsigned int delay); - -#endif /* CLOCK_H_ */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/os/sys/ctimer.c b/net/ip/contiki/os/sys/ctimer.c deleted file mode 100644 index 6012f994e947dc9080df13750a11919bdbbe997d..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/ctimer.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Callback timer implementation - * \author - * Adam Dunkels - */ - -/** - * \addtogroup ctimer - * @{ - */ - -#include - -#include "sys/ctimer.h" -#include "contiki.h" -#include "lib/list.h" - -LIST(ctimer_list); - -static char initialized; - -#define DEBUG DEBUG_NONE -#include "contiki/ip/uip-debug.h" - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif - -/*---------------------------------------------------------------------------*/ -PROCESS(ctimer_process, "Ctimer process"); -PROCESS_THREAD(ctimer_process, ev, data, buf, user_data) -{ - struct ctimer *c; - PROCESS_BEGIN(); - - for(c = list_head(ctimer_list); c != NULL; c = c->next) { - etimer_set(&c->etimer, c->etimer.timer.interval, &ctimer_process); - } - initialized = 1; - - while(1) { - PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_TIMER); - for(c = list_head(ctimer_list); c != NULL; c = c->next) { - if(&c->etimer == data) { - list_remove(ctimer_list, c); - PROCESS_CONTEXT_BEGIN(c->p); - if(c->f != NULL) { - c->f(c->buf, c->ptr); - } - PROCESS_CONTEXT_END(c->p); - break; - } - } - } - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ -void -ctimer_init(void) -{ - initialized = 0; - list_init(ctimer_list); - process_start(&ctimer_process, NULL, NULL); -} -/*---------------------------------------------------------------------------*/ -void -ctimer_set(struct net_buf *buf, struct ctimer *c, clock_time_t t, - void (*f)(struct net_buf *, void *), void *ptr) -{ - c->p = &ctimer_process; - c->f = f; - c->ptr = ptr; - c->buf = buf; - PRINTF("ctimer_set %p t %u process %p buf %p etimer %p\n", - c, (unsigned)t, c->p, buf, &c->etimer); - if(initialized) { - PROCESS_CONTEXT_BEGIN(&ctimer_process); - etimer_set(&c->etimer, t, &ctimer_process); - PROCESS_CONTEXT_END(&ctimer_process); - } else { - c->etimer.timer.interval = t; - } - - list_add(ctimer_list, c); -} -/*---------------------------------------------------------------------------*/ -void -ctimer_reset(struct ctimer *c) -{ - if(initialized) { - PROCESS_CONTEXT_BEGIN(&ctimer_process); - etimer_reset(&c->etimer); - PROCESS_CONTEXT_END(&ctimer_process); - } - - list_add(ctimer_list, c); -} -/*---------------------------------------------------------------------------*/ -void -ctimer_restart(struct ctimer *c) -{ - if(initialized) { - PROCESS_CONTEXT_BEGIN(&ctimer_process); - etimer_restart(&c->etimer); - PROCESS_CONTEXT_END(&ctimer_process); - } - - list_add(ctimer_list, c); -} -/*---------------------------------------------------------------------------*/ -void -ctimer_stop(struct ctimer *c) -{ - if(initialized) { - etimer_stop(&c->etimer); - } else { - c->etimer.next = NULL; - //c->etimer.p = PROCESS_NONE; - } - list_remove(ctimer_list, c); -} -/*---------------------------------------------------------------------------*/ -int -ctimer_expired(struct ctimer *c) -{ - struct ctimer *t; - if(initialized) { - return etimer_expired(&c->etimer); - } - for(t = list_head(ctimer_list); t != NULL; t = t->next) { - if(t == c) { - return 0; - } - } - return 1; -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/os/sys/ctimer.h b/net/ip/contiki/os/sys/ctimer.h deleted file mode 100644 index daad87735a03bcd267911d387586c4b7748f8f3f..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/ctimer.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header file for the callback timer - * \author - * Adam Dunkels - */ - -/** - * \addtogroup sys - * @{ - */ - -/** - * \defgroup ctimer Callback timer - * @{ - * - * The ctimer module provides a timer mechanism that calls a specified - * C function when a ctimer expires. - * - */ - -#include - -#ifndef CTIMER_H_ -#define CTIMER_H_ - -#include "sys/etimer.h" - -struct ctimer { - struct ctimer *next; - struct etimer etimer; - struct process *p; - void (*f)(struct net_buf *, void *); - void *ptr; - struct net_buf *buf; -}; - -/** - * \brief Reset a callback timer with the same interval as was - * previously set. - * \param c A pointer to the callback timer. - * - * This function resets the callback timer with the same - * interval that was given to the callback timer with the - * ctimer_set() function. The start point of the interval - * is the exact time that the callback timer last - * expired. Therefore, this function will cause the timer - * to be stable over time, unlike the ctimer_restart() - * function. - * - * \sa ctimer_restart() - */ -void ctimer_reset(struct ctimer *c); - -/** - * \brief Restart a callback timer from the current point in time - * \param c A pointer to the callback timer. - * - * This function restarts the callback timer with the same - * interval that was given to the ctimer_set() - * function. The callback timer will start at the current - * time. - * - * \note A periodic timer will drift if this function is - * used to reset it. For periodic timers, use the - * ctimer_reset() function instead. - * - * \sa ctimer_reset() - */ -void ctimer_restart(struct ctimer *c); - -/** - * \brief Set a callback timer. - * \param c A pointer to the callback timer. - * \param t The interval before the timer expires. - * \param f A function to be called when the timer expires. - * \param ptr An opaque pointer that will be supplied as an argument to the callback function. - * - * This function is used to set a callback timer for a time - * sometime in the future. When the callback timer expires, - * the callback function f will be called with ptr as argument. - * - */ -void ctimer_set(struct net_buf *buf, struct ctimer *c, clock_time_t t, - void (*f)(struct net_buf *, void *), void *ptr); - -/** - * \brief Stop a pending callback timer. - * \param c A pointer to the pending callback timer. - * - * This function stops a callback timer that has previously - * been set with ctimer_set(), ctimer_reset(), or ctimer_restart(). - * After this function has been called, the callback timer will be - * expired and will not call the callback function. - * - */ -void ctimer_stop(struct ctimer *c); - -/** - * \brief Check if a callback timer has expired. - * \param c A pointer to the callback timer - * \return Non-zero if the timer has expired, zero otherwise. - * - * This function tests if a callback timer has expired and - * returns true or false depending on its status. - */ -int ctimer_expired(struct ctimer *c); - -/** - * \brief Initialize the callback timer library. - * - * This function initializes the callback timer library and - * should be called from the system boot up code. - */ -void ctimer_init(void); - -PROCESS_NAME(ctimer_process); -#endif /* CTIMER_H_ */ -/** @} */ -/** @} */ diff --git a/net/ip/contiki/os/sys/energest.h b/net/ip/contiki/os/sys/energest.h deleted file mode 100644 index 6d43aaa11889cbb805cf6afaeae858f7ddbc31c7..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/energest.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header file for the energy estimation mechanism - * \author - * Adam Dunkels - */ - -#ifndef ENERGEST_H_ -#define ENERGEST_H_ - -#include "sys/rtimer.h" - -typedef struct { - /* unsigned long cumulative[2];*/ - unsigned long current; -} energest_t; - -enum energest_type { - ENERGEST_TYPE_CPU, - ENERGEST_TYPE_LPM, - ENERGEST_TYPE_IRQ, - ENERGEST_TYPE_LED_GREEN, - ENERGEST_TYPE_LED_YELLOW, - ENERGEST_TYPE_LED_RED, - ENERGEST_TYPE_TRANSMIT, - ENERGEST_TYPE_LISTEN, - - ENERGEST_TYPE_FLASH_READ, - ENERGEST_TYPE_FLASH_WRITE, - - ENERGEST_TYPE_SENSORS, - - ENERGEST_TYPE_SERIAL, - - ENERGEST_TYPE_MAX -}; - -void energest_init(void); -unsigned long energest_type_time(int type); -#ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS -unsigned long energest_leveldevice_leveltime(int powerlevel); -#endif -void energest_type_set(int type, unsigned long value); -void energest_flush(void); - -#if ENERGEST_CONF_ON -/*extern int energest_total_count;*/ -extern energest_t energest_total_time[ENERGEST_TYPE_MAX]; -extern rtimer_clock_t energest_current_time[ENERGEST_TYPE_MAX]; -extern unsigned char energest_current_mode[ENERGEST_TYPE_MAX]; - -#ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS -extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVICE_LEVELS]; -#endif - -#define ENERGEST_ON(type) do { \ - /*++energest_total_count;*/ \ - energest_current_time[type] = RTIMER_NOW(); \ - energest_current_mode[type] = 1; \ - } while(0) -#ifdef __AVR__ -/* Handle 16 bit rtimer wraparound */ -#define ENERGEST_OFF(type) if(energest_current_mode[type] != 0) do { \ - if (RTIMER_NOW() < energest_current_time[type]) energest_total_time[type].current += RTIMER_ARCH_SECOND; \ - energest_total_time[type].current += (rtimer_clock_t)(RTIMER_NOW() - \ - energest_current_time[type]); \ - energest_current_mode[type] = 0; \ - } while(0) - -#define ENERGEST_OFF_LEVEL(type,level) do { \ - if (RTIMER_NOW() < energest_current_time[type]) energest_total_time[type].current += RTIMER_ARCH_SECOND; \ - energest_leveldevice_current_leveltime[level].current += (rtimer_clock_t)(RTIMER_NOW() - \ - energest_current_time[type]); \ - energest_current_mode[type] = 0; \ - } while(0) -#else -#define ENERGEST_OFF(type) if(energest_current_mode[type] != 0) do { \ - energest_total_time[type].current += (rtimer_clock_t)(RTIMER_NOW() - \ - energest_current_time[type]); \ - energest_current_mode[type] = 0; \ - } while(0) - -#define ENERGEST_OFF_LEVEL(type,level) do { \ - energest_leveldevice_current_leveltime[level].current += (rtimer_clock_t)(RTIMER_NOW() - \ - energest_current_time[type]); \ - energest_current_mode[type] = 0; \ - } while(0) -#endif - - -#else /* ENERGEST_CONF_ON */ -#define ENERGEST_ON(type) do { } while(0) -#define ENERGEST_OFF(type) do { } while(0) -#define ENERGEST_OFF_LEVEL(type,level) do { } while(0) -#endif /* ENERGEST_CONF_ON */ - -#endif /* ENERGEST_H_ */ diff --git a/net/ip/contiki/os/sys/etimer.c b/net/ip/contiki/os/sys/etimer.c deleted file mode 100644 index 92a1155bf9d39b2fbb0b43102d1bedbead86826c..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/etimer.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ - -/** - * \addtogroup etimer - * @{ - */ - -/** - * \file - * Event timer library implementation. - * \author - * Adam Dunkels - */ - -#include "contiki-conf.h" - -#define DEBUG DEBUG_NONE -#include "contiki/ip/uip-debug.h" - -#include "sys/etimer.h" -#include "sys/process.h" - -extern void net_timer_check(void); - -static struct etimer *timerlist; -static clock_time_t next_expiration; - -PROCESS(etimer_process, "Event timer"); -/*---------------------------------------------------------------------------*/ -static void -update_time(void) -{ - struct etimer *t; - clock_time_t remaining; - - if (timerlist == NULL) { - next_expiration = 0; - } else { - clock_time_t shortest = 0; - for(t = timerlist; t != NULL; t = t->next) { - remaining = timer_remaining(&t->timer); - PRINTF("%s():%d etimer %p left %d shortest %d triggered %d\n", - __FUNCTION__, __LINE__, - t, remaining, shortest, etimer_is_triggered(t)); - if((shortest > remaining || shortest == 0) && remaining != 0) { - shortest = remaining; - } - } - next_expiration = shortest; - PRINTF("%s():%d next expiration %d\n", __FUNCTION__, __LINE__, - next_expiration); - } - - net_timer_check(); -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(etimer_process, ev, data, buf, user_data) -{ - struct etimer *t; - - PROCESS_BEGIN(); - - while(1) { - PROCESS_YIELD(); - - PRINTF("%s():%d timerlist %p\n", __FUNCTION__, __LINE__, timerlist); - for(t = timerlist; t != NULL; t = t->next) { - PRINTF("%s():%d timer %p remaining %d triggered %d\n", - __FUNCTION__, __LINE__, - t, timer_remaining(&t->timer), etimer_is_triggered(t)); - if(etimer_expired(t) && !etimer_is_triggered(t)) { - PRINTF("%s():%d timer %p expired, process %p\n", - __FUNCTION__, __LINE__, t, t->p); - - if (t->p == NULL) { - PRINTF("calling tcpip_process\n"); - process_post_synch(&tcpip_process, PROCESS_EVENT_TIMER, t, NULL); - } else { - process_post_synch(t->p, PROCESS_EVENT_TIMER, t, NULL); - } - } - } - update_time(); - - } - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ -clock_time_t -etimer_request_poll(void) -{ - process_post_synch(&etimer_process, PROCESS_EVENT_POLL, - NULL, NULL); - return next_expiration; -} -/*---------------------------------------------------------------------------*/ -static void -add_timer(struct etimer *timer) -{ - struct etimer *t; - - for(t = timerlist; t != NULL; t = t->next) { - if(t == timer) { - /* Timer already on list, bail out. */ - update_time(); - return; - } - } - - /* Timer not on list. */ - timer->next = timerlist; - timerlist = timer; - - update_time(); -} -/*---------------------------------------------------------------------------*/ -void -etimer_set(struct etimer *et, clock_time_t interval, struct process *p) -{ - et->p = p; - timer_set(&et->timer, interval); - add_timer(et); -} -/*---------------------------------------------------------------------------*/ -void -etimer_reset(struct etimer *et) -{ - timer_reset(&et->timer); - add_timer(et); -} -/*---------------------------------------------------------------------------*/ -void -etimer_restart(struct etimer *et) -{ - timer_restart(&et->timer); - add_timer(et); -} -/*---------------------------------------------------------------------------*/ -#if 1 -void -etimer_adjust(struct etimer *et, int timediff) -{ - et->timer.start += timediff; - update_time(); -} -#endif -/*---------------------------------------------------------------------------*/ -int -etimer_expired(struct etimer *et) -{ - return timer_expired(&et->timer); -} -/*---------------------------------------------------------------------------*/ -clock_time_t -etimer_expiration_time(struct etimer *et) -{ - return et->timer.start + et->timer.interval; -} -/*---------------------------------------------------------------------------*/ -clock_time_t -etimer_start_time(struct etimer *et) -{ - return et->timer.start; -} -/*---------------------------------------------------------------------------*/ -int -etimer_pending(void) -{ - return timerlist != NULL; -} -/*---------------------------------------------------------------------------*/ -clock_time_t -etimer_next_expiration_time(void) -{ - return etimer_pending() ? next_expiration : 0; -} -/*---------------------------------------------------------------------------*/ -void -etimer_stop(struct etimer *et) -{ - struct etimer *t; - - timer_stop(&et->timer); - - /* First check if et is the first event timer on the list. */ - if(et == timerlist) { - timerlist = timerlist->next; - update_time(); - } else { - /* Else walk through the list and try to find the item before the - et timer. */ - for(t = timerlist; t != NULL && t->next != et; t = t->next); - - if(t != NULL) { - /* We've found the item before the event timer that we are about - to remove. We point the items next pointer to the event after - the removed item. */ - t->next = et->next; - - update_time(); - } - } - - /* Remove the next pointer from the item to be removed. */ - et->next = NULL; - - PRINTF("%s():%d timer %p removed\n", __FUNCTION__, __LINE__); -} -/*---------------------------------------------------------------------------*/ -bool etimer_is_triggered(struct etimer *t) -{ - return timer_is_triggered(&t->timer); -} -void etimer_set_triggered(struct etimer *t) -{ - timer_set_triggered(&t->timer); -} -/** @} */ diff --git a/net/ip/contiki/os/sys/etimer.h b/net/ip/contiki/os/sys/etimer.h deleted file mode 100644 index 848ae7b0e43fff68211365e7db91ef03df31f7bb..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/etimer.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ - -/** - * \file - * Event timer header file. - * \author - * Adam Dunkels - */ - -/** \addtogroup sys - * @{ */ - -/** - * \defgroup etimer Event timers - * - * Event timers provides a way to generate timed events. An event - * timer will post an event to the process that set the timer when the - * event timer expires. - * - * An event timer is declared as a \c struct \c etimer and all access - * to the event timer is made by a pointer to the declared event - * timer. - * - * \sa \ref timer "Simple timer library" - * \sa \ref clock "Clock library" (used by the timer library) - * - * @{ - */ - -#ifndef ETIMER_H_ -#define ETIMER_H_ - -#include "sys/timer.h" -#include "sys/process.h" - -/** - * A timer. - * - * This structure is used for declaring a timer. The timer must be set - * with etimer_set() before it can be used. - * - * \hideinitializer - */ -struct etimer { - struct timer timer; - struct etimer *next; - struct process *p; -}; - -/** - * \name Functions called from application programs - * @{ - */ - -/** - * \brief Set an event timer. - * \param et A pointer to the event timer - * \param interval The interval before the timer expires. - * - * This function is used to set an event timer for a time - * sometime in the future. When the event timer expires, - * the event PROCESS_EVENT_TIMER will be posted to the - * process that called the etimer_set() function. - * - */ -CCIF void etimer_set(struct etimer *et, clock_time_t interval, - struct process *p); - -/** - * \brief Reset an event timer with the same interval as was - * previously set. - * \param et A pointer to the event timer. - * - * This function resets the event timer with the same - * interval that was given to the event timer with the - * etimer_set() function. The start point of the interval - * is the exact time that the event timer last - * expired. Therefore, this function will cause the timer - * to be stable over time, unlike the etimer_restart() - * function. - * - * \sa etimer_restart() - */ -CCIF void etimer_reset(struct etimer *et); - -/** - * \brief Restart an event timer from the current point in time - * \param et A pointer to the event timer. - * - * This function restarts the event timer with the same - * interval that was given to the etimer_set() - * function. The event timer will start at the current - * time. - * - * \note A periodic timer will drift if this function is - * used to reset it. For periodic timers, use the - * etimer_reset() function instead. - * - * \sa etimer_reset() - */ -void etimer_restart(struct etimer *et); - -/** - * \brief Adjust the expiration time for an event timer - * \param et A pointer to the event timer. - * \param td The time difference to adjust the expiration time with. - * - * This function is used to adjust the time the event - * timer will expire. It can be used to synchronize - * periodic timers without the need to restart the timer - * or change the timer interval. - * - * \note This function should only be used for small - * adjustments. For large adjustments use etimer_set() - * instead. - * - * \note A periodic timer will drift unless the - * etimer_reset() function is used. - * - * \sa etimer_set() - * \sa etimer_reset() - */ -void etimer_adjust(struct etimer *et, int td); - -/** - * \brief Get the expiration time for the event timer. - * \param et A pointer to the event timer - * \return The expiration time for the event timer. - * - * This function returns the expiration time for an event timer. - */ -clock_time_t etimer_expiration_time(struct etimer *et); - -/** - * \brief Get the start time for the event timer. - * \param et A pointer to the event timer - * \return The start time for the event timer. - * - * This function returns the start time (when the timer - * was last set) for an event timer. - */ -clock_time_t etimer_start_time(struct etimer *et); - -/** - * \brief Check if an event timer has expired. - * \param et A pointer to the event timer - * \return Non-zero if the timer has expired, zero otherwise. - * - * This function tests if an event timer has expired and - * returns true or false depending on its status. - */ -CCIF int etimer_expired(struct etimer *et); - -/** - * \brief Stop a pending event timer. - * \param et A pointer to the pending event timer. - * - * This function stops an event timer that has previously - * been set with etimer_set() or etimer_reset(). After - * this function has been called, the event timer will not - * emit any event when it expires. - * - */ -void etimer_stop(struct etimer *et); - -/** @} */ - -/** - * \name Functions called from timer interrupts, by the system - * @{ - */ - -/** - * \brief Make the event timer aware that the clock has changed - * - * This function is used to inform the event timer module - * that the system clock has been updated. Typically, this - * function would be called from the timer interrupt - * handler when the clock has ticked. - */ -clock_time_t etimer_request_poll(void); - -/** - * \brief Check if there are any non-expired event timers. - * \return True if there are active event timers, false if there are - * no active timers. - * - * This function checks if there are any active event - * timers that have not expired. - */ -int etimer_pending(void); - -/** - * \brief Get next event timer expiration time. - * \return Next expiration time of all pending event timers. - * If there are no pending event timers this function - * returns 0. - * - * This functions returns next expiration time of all - * pending event timers. - */ -clock_time_t etimer_next_expiration_time(void); - -bool etimer_is_triggered(struct etimer *t); -void etimer_set_triggered(struct etimer *t); - - -/** @} */ - -PROCESS_NAME(etimer_process); -#endif /* ETIMER_H_ */ -/** @} */ -/** @} */ diff --git a/net/ip/contiki/os/sys/inttypes.h b/net/ip/contiki/os/sys/inttypes.h deleted file mode 100644 index 9a6118bd8590ca341a8a0addbd21d74e51e51a28..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/inttypes.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/net/ip/contiki/os/sys/lc-switch.h b/net/ip/contiki/os/sys/lc-switch.h deleted file mode 100644 index 8fcef34497516a2991abb92fa6f9f1271fb7fd59..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/lc-switch.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2004-2005, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ - -/** - * \addtogroup lc - * @{ - */ - -/** - * \file - * Implementation of local continuations based on switch() statement - * \author Adam Dunkels - * - * This implementation of local continuations uses the C switch() - * statement to resume execution of a function somewhere inside the - * function's body. The implementation is based on the fact that - * switch() statements are able to jump directly into the bodies of - * control structures such as if() or while() statements. - * - * This implementation borrows heavily from Simon Tatham's coroutines - * implementation in C: - * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html - */ - -#ifndef LC_SWITCH_H_ -#define LC_SWITCH_H_ - -/* WARNING! lc implementation using switch() does not work if an - LC_SET() is done within another switch() statement! */ - -/** \hideinitializer */ -typedef unsigned short lc_t; - -#define LC_INIT(s) s = 0; - -#define LC_RESUME(s) switch(s) { case 0: - -#define LC_SET(s) s = __LINE__; case __LINE__: - -#define LC_END(s) } - -#endif /* LC_SWITCH_H_ */ - -/** @} */ diff --git a/net/ip/contiki/os/sys/lc.h b/net/ip/contiki/os/sys/lc.h deleted file mode 100644 index 6062a21e2c22bab390b7cb67e8b17f91aee12a86..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/lc.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2004-2005, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ - -/** - * \addtogroup pt - * @{ - */ - -/** - * \defgroup lc Local continuations - * @{ - * - * Local continuations form the basis for implementing protothreads. A - * local continuation can be set in a specific function to - * capture the state of the function. After a local continuation has - * been set can be resumed in order to restore the state of the - * function at the point where the local continuation was set. - * - * - */ - -/** - * \file core/sys/lc.h - * Local continuations - * \author - * Adam Dunkels - * - */ - -#ifdef DOXYGEN -/** - * Initialize a local continuation. - * - * This operation initializes the local continuation, thereby - * unsetting any previously set continuation state. - * - * \hideinitializer - */ -#define LC_INIT(lc) - -/** - * Set a local continuation. - * - * The set operation saves the state of the function at the point - * where the operation is executed. As far as the set operation is - * concerned, the state of the function does not include the - * call-stack or local (automatic) variables, but only the program - * counter and such CPU registers that needs to be saved. - * - * \hideinitializer - */ -#define LC_SET(lc) - -/** - * Resume a local continuation. - * - * The resume operation resumes a previously set local continuation, thus - * restoring the state in which the function was when the local - * continuation was set. If the local continuation has not been - * previously set, the resume operation does nothing. - * - * \hideinitializer - */ -#define LC_RESUME(lc) - -/** - * Mark the end of local continuation usage. - * - * The end operation signifies that local continuations should not be - * used any more in the function. This operation is not needed for - * most implementations of local continuation, but is required by a - * few implementations. - * - * \hideinitializer - */ -#define LC_END(lc) - -/** - * \var typedef lc_t; - * - * The local continuation type. - * - * \hideinitializer - */ -#endif /* DOXYGEN */ - -#ifndef LC_H_ -#define LC_H_ - -#ifdef LC_CONF_INCLUDE -#include LC_CONF_INCLUDE -#else /* LC_CONF_INCLUDE */ -#include "sys/lc-switch.h" -#endif /* LC_CONF_INCLUDE */ - -#endif /* LC_H_ */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/os/sys/loader.h b/net/ip/contiki/os/sys/loader.h deleted file mode 100644 index 7d2e264c6c364cdf4b77d1535d0b922b873de8d5..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/loader.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the Contiki desktop OS - * - * - */ - -/** - * \file - * Default definitions and error values for the Contiki program loader. - * \author Adam Dunkels - * - */ - -/** \addtogroup sys - * @{ - */ - -/** - * \defgroup loader The Contiki program loader - * - * The Contiki program loader is an abstract interface for loading and - * starting programs. - * - * @{ - */ - -#ifndef LOADER_H_ -#define LOADER_H_ - -/* Errors that the LOADER_LOAD() function may return: */ - -#define LOADER_OK 0 /**< No error. */ -#define LOADER_ERR_READ 1 /**< Read error. */ -#define LOADER_ERR_HDR 2 /**< Header error. */ -#define LOADER_ERR_OS 3 /**< Wrong OS. */ -#define LOADER_ERR_FMT 4 /**< Data format error. */ -#define LOADER_ERR_MEM 5 /**< Not enough memory. */ -#define LOADER_ERR_OPEN 6 /**< Could not open file. */ -#define LOADER_ERR_ARCH 7 /**< Wrong architecture. */ -#define LOADER_ERR_VERSION 8 /**< Wrong OS version. */ -#define LOADER_ERR_NOLOADER 9 /**< Program loading not supported. */ - -#ifdef LOADER_CONF_ARCH -#include LOADER_CONF_ARCH -#endif /* LOADER_CONF_ARCH */ - -/** - * Load and execute a program. - * - * This macro is used for loading and executing a program, and - * requires support from the architecture dependent code. The actual - * program loading is made by architecture specific functions. - * - * \note A program loaded with LOADER_LOAD() must call the - * LOADER_UNLOAD() function to unload itself. - * - * \param name The name of the program to be loaded. - * - * \param arg A pointer argument that is passed to the program. - * - * \return A loader error, or LOADER_OK if loading was successful. - */ -#ifndef LOADER_LOAD -#define LOADER_LOAD(name, arg) LOADER_ERR_NOLOADER -#endif /* LOADER_LOAD */ - -/** - * Unload a program from memory. - * - * This macro is used for unloading a program and deallocating any - * memory that was allocated during the loading of the program. This - * function must be called by the program itself. - * - */ -#ifndef LOADER_UNLOAD -#define LOADER_UNLOAD() -#endif /* LOADER_UNLOAD */ - -/** - * Load a DSC (program description). - * - * Loads a DSC (program description) into memory and returns a pointer - * to the dsc. - * - * \return A pointer to the DSC or NULL if it could not be loaded. - */ -#ifndef LOADER_LOAD_DSC -#define LOADER_LOAD_DSC(name) NULL -#endif /* LOADER_LOAD_DSC */ - -/** - * Unload a DSC (program description). - * - * Unload a DSC from memory and deallocate any memory that was - * allocated when it was loaded. - */ -#ifndef LOADER_UNLOAD_DSC -#define LOADER_UNLOAD_DSC(dsc) -#endif /* LOADER_UNLOAD */ - -#endif /* LOADER_H_ */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/os/sys/log.h b/net/ip/contiki/os/sys/log.h deleted file mode 100644 index c6bc24737a9e5a639670ba6b4948bbf0c23a56c1..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/log.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ -#ifndef LOG_H_ -#define LOG_H_ - -#include "contiki-conf.h" - -#if LOG_CONF_ENABLED -void log_message(const char *part1, const char *part2); -#else /* LOG_CONF_ENABLED */ -#define log_message(p1, p2) -#endif /* LOG_CONF_ENABLED */ - -#endif /* LOG_H_ */ diff --git a/net/ip/contiki/os/sys/process.c b/net/ip/contiki/os/sys/process.c deleted file mode 100644 index 88eda8c0a0e071ae12a9079273ede8e1f4756b74..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/process.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \addtogroup process - * @{ - */ - -/** - * \file - * Implementation of the Contiki process kernel. - * \author - * Adam Dunkels - * - */ - -#include - -#include -#include - -#include "sys/process.h" -#include "sys/arg.h" - -/* - * Pointer to the currently running process structure. - */ -struct process *process_list = NULL; -struct process *process_current = NULL; - -static process_event_t lastevent; - -/* - * Structure used for keeping the queue of active events. - */ -struct event_data { - process_event_t ev; - process_data_t data; - struct process *p; -}; - -static process_num_events_t nevents, fevent; -static struct event_data events[PROCESS_CONF_NUMEVENTS]; - -#if PROCESS_CONF_STATS -process_num_events_t process_maxevents; -#endif - -static volatile unsigned char poll_requested; - -#define PROCESS_STATE_NONE 0 -#define PROCESS_STATE_RUNNING 1 -#define PROCESS_STATE_CALLED 2 - -static void call_process(struct process *p, process_event_t ev, process_data_t data, struct net_buf *buf); - -#define DEBUG 0 -#include "contiki/ip/uip-debug.h" - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif - -/*---------------------------------------------------------------------------*/ -process_event_t -process_alloc_event(void) -{ - return lastevent++; -} -/*---------------------------------------------------------------------------*/ -void -process_start(struct process *p, process_data_t data, void *user_data) -{ - struct process *q; - - /* First make sure that we don't try to start a process that is - already running. */ - for(q = process_list; q != p && q != NULL; q = q->next); - - /* If we found the process on the process list, we bail out. */ - if(q == p) { - return; - } - /* Put on the procs list.*/ - p->next = process_list; - process_list = p; - p->state = PROCESS_STATE_RUNNING; - p->user_data = user_data; - PT_INIT(&p->pt); - - PRINTF("process: starting '%s'\n", PROCESS_NAME_STRING(p)); - - /* Post a synchronous initialization event to the process. */ - process_post_synch(p, PROCESS_EVENT_INIT, data, NULL); -} -/*---------------------------------------------------------------------------*/ -static void -exit_process(struct process *p, struct process *fromprocess, struct net_buf *buf) -{ - register struct process *q; - struct process *old_current = process_current; - - PRINTF("process: exit_process '%s'\n", PROCESS_NAME_STRING(p)); - - /* Make sure the process is in the process list before we try to - exit it. */ - for(q = process_list; q != p && q != NULL; q = q->next); - if(q == NULL) { - return; - } - - if(process_is_running(p)) { - /* Process was running */ - p->state = PROCESS_STATE_NONE; - - /* - * Post a synchronous event to all processes to inform them that - * this process is about to exit. This will allow services to - * deallocate state associated with this process. - */ - for(q = process_list; q != NULL; q = q->next) { - if(p != q) { - call_process(q, PROCESS_EVENT_EXITED, (process_data_t)p, NULL); - } - } - - if(p->thread != NULL && p != fromprocess) { - /* Post the exit event to the process that is about to exit. */ - process_current = p; - p->thread(&p->pt, PROCESS_EVENT_EXIT, NULL, buf, p->user_data); - } - } - - if(p == process_list) { - process_list = process_list->next; - } else { - for(q = process_list; q != NULL; q = q->next) { - if(q->next == p) { - q->next = p->next; - break; - } - } - } - - process_current = old_current; -} -/*---------------------------------------------------------------------------*/ -static void -call_process(struct process *p, process_event_t ev, process_data_t data, - struct net_buf *buf) -{ - int ret; - -#if DEBUG - if(p->state == PROCESS_STATE_CALLED) { - printf("process: process '%s' called again with event %d buf %p\n", - PROCESS_NAME_STRING(p), ev, buf); - } -#endif /* DEBUG */ - - if((p->state & PROCESS_STATE_RUNNING) && - p->thread != NULL) { - PRINTF("process: calling process '%s' with event %d buf %p\n", PROCESS_NAME_STRING(p), ev, buf); - process_current = p; - p->state = PROCESS_STATE_CALLED; - ret = p->thread(&p->pt, ev, data, buf, p->user_data); - if(ret == PT_EXITED || - ret == PT_ENDED || - ev == PROCESS_EVENT_EXIT) { - exit_process(p, p, buf); - } else { - p->state = PROCESS_STATE_RUNNING; - } - } -} -/*---------------------------------------------------------------------------*/ -void -process_exit(struct process *p) -{ - exit_process(p, PROCESS_CURRENT(), NULL); -} -/*---------------------------------------------------------------------------*/ -void -process_init(void) -{ - lastevent = PROCESS_EVENT_MAX; - - nevents = fevent = 0; -#if PROCESS_CONF_STATS - process_maxevents = 0; -#endif /* PROCESS_CONF_STATS */ - - process_current = process_list = NULL; -} -/*---------------------------------------------------------------------------*/ -/* - * Call each process' poll handler. - */ -/*---------------------------------------------------------------------------*/ -static void -do_poll(struct net_buf *buf) -{ - struct process *p; - - poll_requested = 0; - /* Call the processes that needs to be polled. */ - for(p = process_list; p != NULL; p = p->next) { - if(p->needspoll) { - p->state = PROCESS_STATE_RUNNING; - p->needspoll = 0; - call_process(p, PROCESS_EVENT_POLL, NULL, buf); - } - } -} -/*---------------------------------------------------------------------------*/ -/* - * Process the next event in the event queue and deliver it to - * listening processes. - */ -/*---------------------------------------------------------------------------*/ -static void -do_event(struct net_buf *buf) -{ - static process_event_t ev; - static process_data_t data; - static struct process *receiver; - static struct process *p; - - /* - * If there are any events in the queue, take the first one and walk - * through the list of processes to see if the event should be - * delivered to any of them. If so, we call the event handler - * function for the process. We only process one event at a time and - * call the poll handlers inbetween. - */ - - if(nevents > 0) { - - /* There are events that we should deliver. */ - ev = events[fevent].ev; - - data = events[fevent].data; - receiver = events[fevent].p; - - /* Since we have seen the new event, we move pointer upwards - and decrease the number of events. */ - fevent = (fevent + 1) % PROCESS_CONF_NUMEVENTS; - --nevents; - - /* If this is a broadcast event, we deliver it to all events, in - order of their priority. */ - if(receiver == PROCESS_BROADCAST) { - for(p = process_list; p != NULL; p = p->next) { - - /* If we have been requested to poll a process, we do this in - between processing the broadcast event. */ - if(poll_requested) { - do_poll(buf); - } - call_process(p, ev, data, buf); - } - } else { - /* This is not a broadcast event, so we deliver it to the - specified process. */ - /* If the event was an INIT event, we should also update the - state of the process. */ - if(ev == PROCESS_EVENT_INIT) { - receiver->state = PROCESS_STATE_RUNNING; - } - - /* Make sure that the process actually is running. */ - call_process(receiver, ev, data, buf); - } - } -} -/*---------------------------------------------------------------------------*/ -int -process_run(struct net_buf *buf) -{ - /* Process poll events. */ - if(poll_requested) { - do_poll(buf); - } - - /* Process one event from the queue */ - do_event(buf); - - return nevents + poll_requested; -} -/*---------------------------------------------------------------------------*/ -int -process_nevents(void) -{ - return nevents + poll_requested; -} -/*---------------------------------------------------------------------------*/ -int -process_post(struct process *p, process_event_t ev, process_data_t data) -{ - static process_num_events_t snum; - - if(PROCESS_CURRENT() == NULL) { - PRINTF("process_post: NULL process posts event %d to process '%s', nevents %d\n", - ev,PROCESS_NAME_STRING(p), nevents); - } else { - PRINTF("process_post: Process '%s' posts event %d to process '%s', nevents %d\n", - PROCESS_NAME_STRING(PROCESS_CURRENT()), ev, - p == PROCESS_BROADCAST? "": PROCESS_NAME_STRING(p), nevents); - } - - if(nevents == PROCESS_CONF_NUMEVENTS) { -#if DEBUG - if(p == PROCESS_BROADCAST) { - printf("soft panic: event queue is full when broadcast event %d was posted from %s\n", ev, PROCESS_NAME_STRING(process_current)); - } else { - printf("soft panic: event queue is full when event %d was posted to %s from %s\n", ev, PROCESS_NAME_STRING(p), PROCESS_NAME_STRING(process_current)); - } -#endif /* DEBUG */ - return PROCESS_ERR_FULL; - } - - snum = (process_num_events_t)(fevent + nevents) % PROCESS_CONF_NUMEVENTS; - events[snum].ev = ev; - events[snum].data = data; - events[snum].p = p; - ++nevents; - -#if PROCESS_CONF_STATS - if(nevents > process_maxevents) { - process_maxevents = nevents; - } -#endif /* PROCESS_CONF_STATS */ - - return PROCESS_ERR_OK; -} -/*---------------------------------------------------------------------------*/ -void -process_post_synch(struct process *p, process_event_t ev, process_data_t data, - struct net_buf *buf) -{ - struct process *caller = process_current; - - call_process(p, ev, data, buf); - process_current = caller; -} -/*---------------------------------------------------------------------------*/ -void -process_poll(struct process *p) -{ - if(p != NULL) { - if(p->state == PROCESS_STATE_RUNNING || - p->state == PROCESS_STATE_CALLED) { - p->needspoll = 1; - poll_requested = 1; - } - } -} -/*---------------------------------------------------------------------------*/ -int -process_is_running(struct process *p) -{ - return p->state != PROCESS_STATE_NONE; -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/os/sys/process.h b/net/ip/contiki/os/sys/process.h deleted file mode 100644 index a025fe5503315181840508c9281384a68b35e35a..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/process.h +++ /dev/null @@ -1,539 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \addtogroup sys - * @{ - */ - -/** - * \defgroup process Contiki processes - * - * A process in Contiki consists of a single \ref pt "protothread". - * - * @{ - */ - -/** - * \file - * Header file for the Contiki process interface. - * \author - * Adam Dunkels - * - */ - -#ifndef PROCESS_H_ -#define PROCESS_H_ - -#include "sys/pt.h" -#include "sys/cc.h" - -struct net_buf; - -typedef unsigned char process_event_t; -typedef void * process_data_t; -typedef unsigned char process_num_events_t; - -/** - * \name Return values - * @{ - */ - -/** - * \brief Return value indicating that an operation was successful. - * - * This value is returned to indicate that an operation - * was successful. - */ -#define PROCESS_ERR_OK 0 -/** - * \brief Return value indicating that the event queue was full. - * - * This value is returned from process_post() to indicate - * that the event queue was full and that an event could - * not be posted. - */ -#define PROCESS_ERR_FULL 1 -/* @} */ - -#define PROCESS_NONE NULL - -#ifndef PROCESS_CONF_NUMEVENTS -#define PROCESS_CONF_NUMEVENTS 32 -#endif /* PROCESS_CONF_NUMEVENTS */ - -#define PROCESS_EVENT_NONE 0x80 -#define PROCESS_EVENT_INIT 0x81 -#define PROCESS_EVENT_POLL 0x82 -#define PROCESS_EVENT_EXIT 0x83 -#define PROCESS_EVENT_SERVICE_REMOVED 0x84 -#define PROCESS_EVENT_CONTINUE 0x85 -#define PROCESS_EVENT_MSG 0x86 -#define PROCESS_EVENT_EXITED 0x87 -#define PROCESS_EVENT_TIMER 0x88 -#define PROCESS_EVENT_COM 0x89 -#define PROCESS_EVENT_MAX 0x8a - -#define PROCESS_BROADCAST NULL -#define PROCESS_ZOMBIE ((struct process *)0x1) - -/** - * \name Process protothread functions - * @{ - */ - -/** - * Define the beginning of a process. - * - * This macro defines the beginning of a process, and must always - * appear in a PROCESS_THREAD() definition. The PROCESS_END() macro - * must come at the end of the process. - * - * \hideinitializer - */ -#define PROCESS_BEGIN() PT_BEGIN(process_pt) - -/** - * Define the end of a process. - * - * This macro defines the end of a process. It must appear in a - * PROCESS_THREAD() definition and must always be included. The - * process exits when the PROCESS_END() macro is reached. - * - * \hideinitializer - */ -#define PROCESS_END() PT_END(process_pt) - -/** - * Wait for an event to be posted to the process. - * - * This macro blocks the currently running process until the process - * receives an event. - * - * \hideinitializer - */ -#define PROCESS_WAIT_EVENT() PROCESS_YIELD() - -/** - * Wait for an event to be posted to the process, with an extra - * condition. - * - * This macro is similar to PROCESS_WAIT_EVENT() in that it blocks the - * currently running process until the process receives an event. But - * PROCESS_WAIT_EVENT_UNTIL() takes an extra condition which must be - * true for the process to continue. - * - * \param c The condition that must be true for the process to continue. - * \sa PT_WAIT_UNTIL() - * - * \hideinitializer - */ -#define PROCESS_WAIT_EVENT_UNTIL(c) PROCESS_YIELD_UNTIL(c) - -/** - * Yield the currently running process. - * - * \hideinitializer - */ -#define PROCESS_YIELD() PT_YIELD(process_pt) - -/** - * Yield the currently running process until a condition occurs. - * - * This macro is different from PROCESS_WAIT_UNTIL() in that - * PROCESS_YIELD_UNTIL() is guaranteed to always yield at least - * once. This ensures that the process does not end up in an infinite - * loop and monopolizing the CPU. - * - * \param c The condition to wait for. - * - * \hideinitializer - */ -#define PROCESS_YIELD_UNTIL(c) PT_YIELD_UNTIL(process_pt, c) - -/** - * Wait for a condition to occur. - * - * This macro does not guarantee that the process yields, and should - * therefore be used with care. In most cases, PROCESS_WAIT_EVENT(), - * PROCESS_WAIT_EVENT_UNTIL(), PROCESS_YIELD() or - * PROCESS_YIELD_UNTIL() should be used instead. - * - * \param c The condition to wait for. - * - * \hideinitializer - */ -#define PROCESS_WAIT_UNTIL(c) PT_WAIT_UNTIL(process_pt, c) -#define PROCESS_WAIT_WHILE(c) PT_WAIT_WHILE(process_pt, c) - -/** - * Exit the currently running process. - * - * \hideinitializer - */ -#define PROCESS_EXIT() PT_EXIT(process_pt) - -/** - * Spawn a protothread from the process. - * - * \param pt The protothread state (struct pt) for the new protothread - * \param thread The call to the protothread function. - * \sa PT_SPAWN() - * - * \hideinitializer - */ -#define PROCESS_PT_SPAWN(pt, thread) PT_SPAWN(process_pt, pt, thread) - -/** - * Yield the process for a short while. - * - * This macro yields the currently running process for a short while, - * thus letting other processes run before the process continues. - * - * \hideinitializer - */ -#define PROCESS_PAUSE() do { \ - process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL); \ - PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_CONTINUE); \ -} while(0) - -/** @} end of protothread functions */ - -/** - * \name Poll and exit handlers - * @{ - */ -/** - * Specify an action when a process is polled. - * - * \note This declaration must come immediately before the - * PROCESS_BEGIN() macro. - * - * \param handler The action to be performed. - * - * \hideinitializer - */ -#define PROCESS_POLLHANDLER(handler) if(ev == PROCESS_EVENT_POLL) { handler; } - -/** - * Specify an action when a process exits. - * - * \note This declaration must come immediately before the - * PROCESS_BEGIN() macro. - * - * \param handler The action to be performed. - * - * \hideinitializer - */ -#define PROCESS_EXITHANDLER(handler) if(ev == PROCESS_EVENT_EXIT) { handler; } - -/** @} */ - -/** - * \name Process declaration and definition - * @{ - */ - -/** - * Define the body of a process. - * - * This macro is used to define the body (protothread) of a - * process. The process is called whenever an event occurs in the - * system, A process always start with the PROCESS_BEGIN() macro and - * end with the PROCESS_END() macro. - * - * \hideinitializer - */ -#define PROCESS_THREAD(name, ev, data, buf, user_data) \ -static PT_THREAD(process_thread_##name(struct pt *process_pt, \ - process_event_t ev, \ - process_data_t data, \ - struct net_buf *buf, \ - void *user_data)) - -/** - * Declare the name of a process. - * - * This macro is typically used in header files to declare the name of - * a process that is implemented in the C file. - * - * \hideinitializer - */ -#define PROCESS_NAME(name) extern struct process name - -/** - * Declare a process. - * - * This macro declares a process. The process has two names: the - * variable of the process structure, which is used by the C program, - * and a human readable string name, which is used when debugging. - * A configuration option allows removal of the readable name to save RAM. - * - * \param name The variable name of the process structure. - * \param strname The string representation of the process' name. - * - * \hideinitializer - */ -#if PROCESS_CONF_NO_PROCESS_NAMES -#define PROCESS(name, strname) \ - PROCESS_THREAD(name, ev, data); \ - struct process name = { NULL, \ - process_thread_##name } -#else -#define PROCESS(name, strname) \ - PROCESS_THREAD(name, ev, data, buf, user_data); \ - struct process name = { NULL, strname, \ - process_thread_##name } -#endif - -/** @} */ - -struct process { - struct process *next; -#if PROCESS_CONF_NO_PROCESS_NAMES -#define PROCESS_NAME_STRING(process) "" -#else - const char *name; -#define PROCESS_NAME_STRING(process) (process)->name -#endif - PT_THREAD((* thread)(struct pt *, process_event_t, process_data_t, - struct net_buf *, void *user_data)); - struct pt pt; - unsigned char state, needspoll; - void *user_data; -}; - -/** - * \name Functions called from application programs - * @{ - */ - -/** - * Start a process. - * - * \param p A pointer to a process structure. - * - * \param data An argument pointer that can be passed to the new - * process - * - */ -CCIF void process_start(struct process *p, process_data_t data, void *user_data); - -/** - * Post an asynchronous event. - * - * This function posts an asynchronous event to one or more - * processes. The handing of the event is deferred until the target - * process is scheduled by the kernel. An event can be broadcast to - * all processes, in which case all processes in the system will be - * scheduled to handle the event. - * - * \param ev The event to be posted. - * - * \param data The auxiliary data to be sent with the event - * - * \param p The process to which the event should be posted, or - * PROCESS_BROADCAST if the event should be posted to all processes. - * - * \retval PROCESS_ERR_OK The event could be posted. - * - * \retval PROCESS_ERR_FULL The event queue was full and the event could - * not be posted. - */ -CCIF int process_post(struct process *p, process_event_t ev, process_data_t data); - -/** - * Post a synchronous event to a process. - * - * \param p A pointer to the process' process structure. - * - * \param ev The event to be posted. - * - * \param data A pointer to additional data that is posted together - * with the event. - */ -CCIF void process_post_synch(struct process *p, - process_event_t ev, process_data_t data, - struct net_buf *buf); - -/** - * \brief Cause a process to exit - * \param p The process that is to be exited - * - * This function causes a process to exit. The process can - * either be the currently executing process, or another - * process that is currently running. - * - * \sa PROCESS_CURRENT() - */ -CCIF void process_exit(struct process *p); - - -/** - * Get a pointer to the currently running process. - * - * This macro get a pointer to the currently running - * process. Typically, this macro is used to post an event to the - * current process with process_post(). - * - * \hideinitializer - */ -#define PROCESS_CURRENT() process_current -CCIF extern struct process *process_current; - -/** - * Switch context to another process - * - * This function switch context to the specified process and executes - * the code as if run by that process. Typical use of this function is - * to switch context in services, called by other processes. Each - * PROCESS_CONTEXT_BEGIN() must be followed by the - * PROCESS_CONTEXT_END() macro to end the context switch. - * - * Example: - \code - PROCESS_CONTEXT_BEGIN(&test_process); - etimer_set(&timer, CLOCK_SECOND); - PROCESS_CONTEXT_END(&test_process); - \endcode - * - * \param p The process to use as context - * - * \sa PROCESS_CONTEXT_END() - * \sa PROCESS_CURRENT() - */ -#define PROCESS_CONTEXT_BEGIN(p) {\ -struct process *tmp_current = PROCESS_CURRENT();\ -process_current = p - -/** - * End a context switch - * - * This function ends a context switch and changes back to the - * previous process. - * - * \param p The process used in the context switch - * - * \sa PROCESS_CONTEXT_START() - */ -#define PROCESS_CONTEXT_END(p) process_current = tmp_current; } - -/** - * \brief Allocate a global event number. - * \return The allocated event number - * - * In Contiki, event numbers above 128 are global and may - * be posted from one process to another. This function - * allocates one such event number. - * - * \note There currently is no way to deallocate an allocated event - * number. - */ -CCIF process_event_t process_alloc_event(void); - -/** @} */ - -/** - * \name Functions called from device drivers - * @{ - */ - -/** - * Request a process to be polled. - * - * This function typically is called from an interrupt handler to - * cause a process to be polled. - * - * \param p A pointer to the process' process structure. - */ -CCIF void process_poll(struct process *p); - -/** @} */ - -/** - * \name Functions called by the system and boot-up code - * @{ - */ - -/** - * \brief Initialize the process module. - * - * This function initializes the process module and should - * be called by the system boot-up code. - */ -void process_init(void); - -/** - * Run the system once - call poll handlers and process one event. - * - * This function should be called repeatedly from the main() program - * to actually run the Contiki system. It calls the necessary poll - * handlers, and processes one event. The function returns the number - * of events that are waiting in the event queue so that the caller - * may choose to put the CPU to sleep when there are no pending - * events. - * - * \return The number of events that are currently waiting in the - * event queue. - */ -int process_run(struct net_buf *buf); - - -/** - * Check if a process is running. - * - * This function checks if a specific process is running. - * - * \param p The process. - * \retval Non-zero if the process is running. - * \retval Zero if the process is not running. - */ -CCIF int process_is_running(struct process *p); - -/** - * Number of events waiting to be processed. - * - * \return The number of events that are currently waiting to be - * processed. - */ -int process_nevents(void); - -/** @} */ - -CCIF extern struct process *process_list; - -#define PROCESS_LIST() process_list - -#endif /* PROCESS_H_ */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/os/sys/procinit.h b/net/ip/contiki/os/sys/procinit.h deleted file mode 100644 index 5e65a6de6e5efbe3ca5ae78ab54a66c2f79f9f03..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/procinit.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ -#ifndef PROCINIT_H_ -#define PROCINIT_H_ - -#include "sys/process.h" - -#if ! CC_NO_VA_ARGS -#define PROCINIT(...) \ -const struct process *procinit[] = {__VA_ARGS__, NULL} -#endif - -void procinit_init(void); - -#endif /* PROCINIT_H_ */ diff --git a/net/ip/contiki/os/sys/pt.h b/net/ip/contiki/os/sys/pt.h deleted file mode 100644 index c9549119ee0d04f6751f37231e0be684c3c17211..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/pt.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (c) 2004-2005, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ - -/** - * \addtogroup pt - * @{ - */ - -/** - * \file - * Protothreads implementation. - * \author - * Adam Dunkels - * - */ - -#ifndef PT_H_ -#define PT_H_ - -#include "sys/lc.h" - -struct pt { - lc_t lc; -}; - -#define PT_WAITING 0 -#define PT_YIELDED 1 -#define PT_EXITED 2 -#define PT_ENDED 3 - -/** - * \name Initialization - * @{ - */ - -/** - * Initialize a protothread. - * - * Initializes a protothread. Initialization must be done prior to - * starting to execute the protothread. - * - * \param pt A pointer to the protothread control structure. - * - * \sa PT_SPAWN() - * - * \hideinitializer - */ -#define PT_INIT(pt) LC_INIT((pt)->lc) - -/** @} */ - -/** - * \name Declaration and definition - * @{ - */ - -/** - * Declaration of a protothread. - * - * This macro is used to declare a protothread. All protothreads must - * be declared with this macro. - * - * \param name_args The name and arguments of the C function - * implementing the protothread. - * - * \hideinitializer - */ -#define PT_THREAD(name_args) char name_args - -/** - * Declare the start of a protothread inside the C function - * implementing the protothread. - * - * This macro is used to declare the starting point of a - * protothread. It should be placed at the start of the function in - * which the protothread runs. All C statements above the PT_BEGIN() - * invokation will be executed each time the protothread is scheduled. - * - * \param pt A pointer to the protothread control structure. - * - * \hideinitializer - */ -#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; if (PT_YIELD_FLAG) {;} LC_RESUME((pt)->lc) - -/** - * Declare the end of a protothread. - * - * This macro is used for declaring that a protothread ends. It must - * always be used together with a matching PT_BEGIN() macro. - * - * \param pt A pointer to the protothread control structure. - * - * \hideinitializer - */ -#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \ - PT_INIT(pt); return PT_ENDED; } - -/** @} */ - -/** - * \name Blocked wait - * @{ - */ - -/** - * Block and wait until condition is true. - * - * This macro blocks the protothread until the specified condition is - * true. - * - * \param pt A pointer to the protothread control structure. - * \param condition The condition. - * - * \hideinitializer - */ -#define PT_WAIT_UNTIL(pt, condition) \ - do { \ - LC_SET((pt)->lc); \ - if(!(condition)) { \ - return PT_WAITING; \ - } \ - } while(0) - -/** - * Block and wait while condition is true. - * - * This function blocks and waits while condition is true. See - * PT_WAIT_UNTIL(). - * - * \param pt A pointer to the protothread control structure. - * \param cond The condition. - * - * \hideinitializer - */ -#define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond)) - -/** @} */ - -/** - * \name Hierarchical protothreads - * @{ - */ - -/** - * Block and wait until a child protothread completes. - * - * This macro schedules a child protothread. The current protothread - * will block until the child protothread completes. - * - * \note The child protothread must be manually initialized with the - * PT_INIT() function before this function is used. - * - * \param pt A pointer to the protothread control structure. - * \param thread The child protothread with arguments - * - * \sa PT_SPAWN() - * - * \hideinitializer - */ -#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread)) - -/** - * Spawn a child protothread and wait until it exits. - * - * This macro spawns a child protothread and waits until it exits. The - * macro can only be used within a protothread. - * - * \param pt A pointer to the protothread control structure. - * \param child A pointer to the child protothread's control structure. - * \param thread The child protothread with arguments - * - * \hideinitializer - */ -#define PT_SPAWN(pt, child, thread) \ - do { \ - PT_INIT((child)); \ - PT_WAIT_THREAD((pt), (thread)); \ - } while(0) - -/** @} */ - -/** - * \name Exiting and restarting - * @{ - */ - -/** - * Restart the protothread. - * - * This macro will block and cause the running protothread to restart - * its execution at the place of the PT_BEGIN() call. - * - * \param pt A pointer to the protothread control structure. - * - * \hideinitializer - */ -#define PT_RESTART(pt) \ - do { \ - PT_INIT(pt); \ - return PT_WAITING; \ - } while(0) - -/** - * Exit the protothread. - * - * This macro causes the protothread to exit. If the protothread was - * spawned by another protothread, the parent protothread will become - * unblocked and can continue to run. - * - * \param pt A pointer to the protothread control structure. - * - * \hideinitializer - */ -#define PT_EXIT(pt) \ - do { \ - PT_INIT(pt); \ - return PT_EXITED; \ - } while(0) - -/** @} */ - -/** - * \name Calling a protothread - * @{ - */ - -/** - * Schedule a protothread. - * - * This function schedules a protothread. The return value of the - * function is non-zero if the protothread is running or zero if the - * protothread has exited. - * - * \param f The call to the C function implementing the protothread to - * be scheduled - * - * \hideinitializer - */ -#define PT_SCHEDULE(f) ((f) < PT_EXITED) - -/** @} */ - -/** - * \name Yielding from a protothread - * @{ - */ - -/** - * Yield from the current protothread. - * - * This function will yield the protothread, thereby allowing other - * processing to take place in the system. - * - * \param pt A pointer to the protothread control structure. - * - * \hideinitializer - */ -#define PT_YIELD(pt) \ - do { \ - PT_YIELD_FLAG = 0; \ - LC_SET((pt)->lc); \ - if(PT_YIELD_FLAG == 0) { \ - return PT_YIELDED; \ - } \ - } while(0) - -/** - * \brief Yield from the protothread until a condition occurs. - * \param pt A pointer to the protothread control structure. - * \param cond The condition. - * - * This function will yield the protothread, until the - * specified condition evaluates to true. - * - * - * \hideinitializer - */ -#define PT_YIELD_UNTIL(pt, cond) \ - do { \ - PT_YIELD_FLAG = 0; \ - LC_SET((pt)->lc); \ - if((PT_YIELD_FLAG == 0) || !(cond)) { \ - return PT_YIELDED; \ - } \ - } while(0) - -/** @} */ - -#endif /* PT_H_ */ - -/** @} */ diff --git a/net/ip/contiki/os/sys/rtimer.c b/net/ip/contiki/os/sys/rtimer.c deleted file mode 100644 index cf96a17bf47b806397b02675d4357cbefb786ec7..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/rtimer.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Implementation of the architecture-agnostic parts of the real-time timer module. - * \author - * Adam Dunkels - * - */ - -/** - * \addtogroup rt - * @{ - */ - -#include "sys/rtimer.h" -#include "contiki.h" - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif - -static struct rtimer *next_rtimer; - -/*---------------------------------------------------------------------------*/ -void -rtimer_init(void) -{ - rtimer_arch_init(); -} -/*---------------------------------------------------------------------------*/ -int -rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, - rtimer_clock_t duration, - rtimer_callback_t func, void *ptr) -{ - int first = 0; - - PRINTF("rtimer_set time %d\n", time); - - if(next_rtimer == NULL) { - first = 1; - } - - rtimer->func = func; - rtimer->ptr = ptr; - - rtimer->time = time; - next_rtimer = rtimer; - - if(first == 1) { - rtimer_arch_schedule(time); - } - return RTIMER_OK; -} -/*---------------------------------------------------------------------------*/ -void -rtimer_run_next(void) -{ - struct rtimer *t; - if(next_rtimer == NULL) { - return; - } - t = next_rtimer; - next_rtimer = NULL; - t->func(t, t->ptr); - if(next_rtimer != NULL) { - rtimer_arch_schedule(next_rtimer->time); - } - return; -} -/*---------------------------------------------------------------------------*/ - -/** @}*/ diff --git a/net/ip/contiki/os/sys/rtimer.h b/net/ip/contiki/os/sys/rtimer.h deleted file mode 100644 index 11dde5fa1fe673a9c838ffb94022ff67e055d15a..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/rtimer.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header file for the real-time timer module. - * \author - * Adam Dunkels - * - */ - -/** \addtogroup sys - * @{ */ - -/** - * \defgroup rt Real-time task scheduling - * - * The real-time module handles the scheduling and execution of - * real-time tasks (with predictable execution times). - * - * @{ - */ - -#ifndef RTIMER_H_ -#define RTIMER_H_ - -#include "contiki-conf.h" - -#ifndef RTIMER_CLOCK_LT -typedef unsigned short rtimer_clock_t; -#define RTIMER_CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) -#endif /* RTIMER_CLOCK_LT */ - -#include "rtimer-arch.h" - -/** - * \brief Initialize the real-time scheduler. - * - * This function initializes the real-time scheduler and - * must be called at boot-up, before any other functions - * from the real-time scheduler is called. - */ -void rtimer_init(void); - -struct rtimer; -typedef void (* rtimer_callback_t)(struct rtimer *t, void *ptr); - -/** - * \brief Representation of a real-time task - * - * This structure represents a real-time task and is used - * by the real-time module and the architecture specific - * support module for the real-time module. - */ -struct rtimer { - rtimer_clock_t time; - rtimer_callback_t func; - void *ptr; -}; - -enum { - RTIMER_OK, - RTIMER_ERR_FULL, - RTIMER_ERR_TIME, - RTIMER_ERR_ALREADY_SCHEDULED, -}; - -/** - * \brief Post a real-time task. - * \param task A pointer to the task variable previously declared with RTIMER_TASK(). - * \param time The time when the task is to be executed. - * \param duration Unused argument. - * \param func A function to be called when the task is executed. - * \param ptr An opaque pointer that will be supplied as an argument to the callback function. - * \return Non-zero (true) if the task could be scheduled, zero - * (false) if the task could not be scheduled. - * - * This function schedules a real-time task at a specified - * time in the future. - * - */ -int rtimer_set(struct rtimer *task, rtimer_clock_t time, - rtimer_clock_t duration, rtimer_callback_t func, void *ptr); - -/** - * \brief Execute the next real-time task and schedule the next task, if any - * - * This function is called by the architecture dependent - * code to execute and schedule the next real-time task. - * - */ -void rtimer_run_next(void); - -/** - * \brief Get the current clock time - * \return The current time - * - * This function returns what the real-time module thinks - * is the current time. The current time is used to set - * the timeouts for real-time tasks. - * - * \hideinitializer - */ -#define RTIMER_NOW() rtimer_arch_now() - -/** - * \brief Get the time that a task last was executed - * \param task The task - * \return The time that a task last was executed - * - * This function returns the time that the task was last - * executed. This typically is used to get a periodic - * execution of a task without clock drift. - * - * \hideinitializer - */ -#define RTIMER_TIME(task) ((task)->time) - -void rtimer_arch_init(void); -void rtimer_arch_schedule(rtimer_clock_t t); -/*rtimer_clock_t rtimer_arch_now(void);*/ - -#define RTIMER_SECOND RTIMER_ARCH_SECOND - -#endif /* RTIMER_H_ */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/os/sys/stimer.c b/net/ip/contiki/os/sys/stimer.c deleted file mode 100644 index 86545f59eed0c4938a78a7dea141e080cfbf96a7..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/stimer.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2004, 2008, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels , Nicolas Tsiftes - * - */ - -/** - * \file - * Timer of seconds library implementation. - * \author - * Adam Dunkels , Nicolas Tsiftes - */ - -/** - * \addtogroup stimer - * @{ - */ - -#include "contiki-conf.h" -#include "sys/clock.h" -#include "sys/stimer.h" - -#define SCLOCK_GEQ(a, b) ((unsigned long)((a) - (b)) < \ - ((unsigned long)(~((unsigned long)0)) >> 1)) - -/*---------------------------------------------------------------------------*/ -/** - * Set a timer. - * - * This function is used to set a timer for a time sometime in the - * future. The function stimer_expired() will evaluate to true after - * the timer has expired. - * - * \param t A pointer to the timer - * \param interval The interval before the timer expires. - * - */ -void -stimer_set(struct stimer *t, unsigned long interval) -{ - t->interval = interval; - t->start = clock_seconds(); -} -/*---------------------------------------------------------------------------*/ -/** - * Reset the timer with the same interval. - * - * This function resets the timer with the same interval that was - * given to the stimer_set() function. The start point of the interval - * is the exact time that the timer last expired. Therefore, this - * function will cause the timer to be stable over time, unlike the - * stimer_restart() function. - * - * \param t A pointer to the timer. - * - * \sa stimer_restart() - */ -void -stimer_reset(struct stimer *t) -{ - t->start += t->interval; -} -/*---------------------------------------------------------------------------*/ -/** - * Restart the timer from the current point in time - * - * This function restarts a timer with the same interval that was - * given to the stimer_set() function. The timer will start at the - * current time. - * - * \note A periodic timer will drift if this function is used to reset - * it. For preioric timers, use the stimer_reset() function instead. - * - * \param t A pointer to the timer. - * - * \sa stimer_reset() - */ -void -stimer_restart(struct stimer *t) -{ - t->start = clock_seconds(); -} -/*---------------------------------------------------------------------------*/ -/** - * Check if a timer has expired. - * - * This function tests if a timer has expired and returns true or - * false depending on its status. - * - * \param t A pointer to the timer - * - * \return Non-zero if the timer has expired, zero otherwise. - * - */ -int -stimer_expired(struct stimer *t) -{ - return SCLOCK_GEQ(clock_seconds(), t->start + t->interval); -} -/*---------------------------------------------------------------------------*/ -/** - * The time until the timer expires - * - * This function returns the time until the timer expires. - * - * \param t A pointer to the timer - * - * \return The time until the timer expires - * - */ -unsigned long -stimer_remaining(struct stimer *t) -{ - return t->start + t->interval - clock_seconds(); -} -/*---------------------------------------------------------------------------*/ -/** - * The time elapsed since the timer started - * - * This function returns the time elapsed. - * - * \param t A pointer to the timer - * - * \return The time elapsed since the last start of the timer - * - */ -unsigned long -stimer_elapsed(struct stimer *t) -{ - return clock_seconds() - t->start; -} - -/*---------------------------------------------------------------------------*/ - -/** @} */ diff --git a/net/ip/contiki/os/sys/stimer.h b/net/ip/contiki/os/sys/stimer.h deleted file mode 100644 index 6ef7db5de1abca83829ea4075c4c3da38cabc971..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/stimer.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2004, 2008, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels , Nicolas Tsiftes - * - */ - -/** - * \file - * Second timer library header file. - * \author - * Adam Dunkels , Nicolas Tsiftes - */ - -/** \addtogroup sys - * @{ */ - -/** - * \defgroup stimer Seconds timer library - * - * The stimer library provides functions for setting, resetting and - * restarting timers, and for checking if a timer has expired. An - * application must "manually" check if its timers have expired; this - * is not done automatically. - * - * A timer is declared as a \c struct \c stimer and all access to the - * timer is made by a pointer to the declared timer. - * - * \note The stimer library is not able to post events when a timer - * expires. The \ref etimer "Event timers" should be used for this - * purpose. - * - * \note The stimer library uses the \ref clock "Clock library" to - * measure time. Intervals should be specified in the seconds. - * - * \sa \ref etimer "Event timers" - * - * @{ - */ - -#ifndef STIMER_H_ -#define STIMER_H_ - -#include "sys/clock.h" - -/** - * A timer. - * - * This structure is used for declaring a timer. The timer must be set - * with stimer_set() before it can be used. - * - * \hideinitializer - */ -struct stimer { - unsigned long start; - unsigned long interval; -}; - -void stimer_set(struct stimer *t, unsigned long interval); -void stimer_reset(struct stimer *t); -void stimer_restart(struct stimer *t); -int stimer_expired(struct stimer *t); -unsigned long stimer_remaining(struct stimer *t); -unsigned long stimer_elapsed(struct stimer *t); - - -#endif /* STIMER_H_ */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/os/sys/time.h b/net/ip/contiki/os/sys/time.h deleted file mode 100644 index 977f499d87ee647a7ca7f79d2963252b51c4521c..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/time.h +++ /dev/null @@ -1 +0,0 @@ -/* Empty file to satisfy compiler */ diff --git a/net/ip/contiki/os/sys/timer.c b/net/ip/contiki/os/sys/timer.c deleted file mode 100644 index 04d720818ac7dd9a08d9ad7852151ad401a77a26..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/timer.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ - -/** - * \file - * Timer library implementation. - * \author - * Adam Dunkels - */ - -/** - * \addtogroup timer - * @{ - */ - -#include "contiki-conf.h" -#include "sys/clock.h" -#include "sys/timer.h" - -#define DEBUG DEBUG_NONE -#include "contiki/ip/uip-debug.h" - -/* - * Code indicates that the timer has expired. - * nano_timer_test(), called by timer_expired() returns it - * on timer expiration instead of NULL if timer is still running - */ -#define TIMER_EXPIRED_CODE ((void *)0xfede0123) - -static inline void do_init(struct timer *t) -{ - if (t && !t->init_done) { - nano_timer_init(&t->nano_timer, TIMER_EXPIRED_CODE); - t->init_done = true; - t->expired = false; - } -} - -/*---------------------------------------------------------------------------*/ -/** - * Set a timer. - * - * This function is used to set a timer for a time sometime in the - * future. The function timer_expired() will evaluate to true after - * the timer has expired. - * - * \param t A pointer to the timer - * \param interval The interval before the timer expires. - * - */ -void -timer_set(struct timer *t, clock_time_t interval) -{ - do_init(t); - - if (t->started) { - timer_stop(t); - } - - switch (sys_execution_context_type_get()) { - case NANO_CTX_FIBER: - nano_fiber_timer_start(&t->nano_timer, interval); - break; - case NANO_CTX_TASK: - nano_task_timer_start(&t->nano_timer, interval); - break; - default: - return; - } - - PRINTF("%s():%d timer %p started interval %d\n", __FUNCTION__, __LINE__, - t, interval); - t->started = true; - t->interval = interval; - t->start = clock_time(); - t->triggered = false; - t->expired = false; -} -/*---------------------------------------------------------------------------*/ -/** - * Reset the timer with the same interval. - * - * This function resets the timer with the same interval that was - * given to the timer_set() function. The start point of the interval - * is the exact time that the timer last expired. Therefore, this - * function will cause the timer to be stable over time, unlike the - * timer_restart() function. - * - * \note Must not be executed before timer expired - * - * \param t A pointer to the timer. - * \sa timer_restart() - */ -void -timer_reset(struct timer *t) -{ - timer_stop(t); - timer_set(t, t->interval); -} -/*---------------------------------------------------------------------------*/ -/** - * Restart the timer from the current point in time - * - * This function restarts a timer with the same interval that was - * given to the timer_set() function. The timer will start at the - * current time. - * - * \note A periodic timer will drift if this function is used to reset - * it. For preioric timers, use the timer_reset() function instead. - * - * \param t A pointer to the timer. - * - * \sa timer_reset() - */ -void -timer_restart(struct timer *t) -{ - do_init(t); - - if (t->started) { - timer_stop(t); - } - - switch (sys_execution_context_type_get()) { - case NANO_CTX_FIBER: - nano_fiber_timer_start(&t->nano_timer, t->interval); - break; - case NANO_CTX_TASK: - nano_task_timer_start(&t->nano_timer, t->interval); - break; - default: - return; - } - t->started = true; - t->start = clock_time(); - t->triggered = false; - t->expired = false; -} -/*---------------------------------------------------------------------------*/ -/** - * Check if a timer has expired. - * - * This function tests if a timer has expired and returns true or - * false depending on its status. - * - * \param t A pointer to the timer - * - * \return Non-zero if the timer has expired, zero otherwise. - * - */ -int -timer_expired(struct timer *t) -{ - void *user_data; - bool init_done = t->init_done; - - do_init(t); - - if (t->expired) { - return true; - } - - user_data = nano_timer_test(&t->nano_timer, TICKS_NONE); - - /* If user data is returned, then we are definitely expired. */ - if (user_data == TIMER_EXPIRED_CODE) { - t->expired = true; - return true; - } - - /* If TICKS_NONE is used, then the system returns NULL when the - * timer has not yet run. In this case we return true value so - * that the caller can schedule the timer again. - * - * Note that it is absolutely mandatory that timer struct is - * initialized before use. The init_done must reflect the real - * status of the timer. - */ - if (!init_done && user_data == NULL) { - t->expired = true; - return true; - } - - return false; -} -/*---------------------------------------------------------------------------*/ -bool timer_is_triggered(struct timer *t) -{ - return t->triggered; -} - -void timer_set_triggered(struct timer *t) -{ - t->triggered = true; -} -/*---------------------------------------------------------------------------*/ -/** - * The time until the timer expires - * - * This function returns the time until the timer expires. - * - * \param t A pointer to the timer - * - * \return The time until the timer expires - * - */ -clock_time_t -timer_remaining(struct timer *t) -{ - return nano_timer_ticks_remain(&t->nano_timer); -} -/*---------------------------------------------------------------------------*/ -bool timer_stop(struct timer *t) -{ - if (!t->started) { - return false; - } - - switch (sys_execution_context_type_get()) { - case NANO_CTX_FIBER: - nano_fiber_timer_stop(&t->nano_timer); - break; - case NANO_CTX_TASK: - nano_task_timer_stop(&t->nano_timer); - break; - default: - return false; - } - - PRINTF("%s():%d timer %p stopped\n", __FUNCTION__, __LINE__, t); - - t->started = false; - t->triggered = false; - return true; -} -/** @} */ diff --git a/net/ip/contiki/os/sys/timer.h b/net/ip/contiki/os/sys/timer.h deleted file mode 100644 index 1a6ffabeb8d96255e68c9d29da7fc68588e58eec..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/timer.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ - -/** - * \file - * Timer library header file. - * \author - * Adam Dunkels - */ - -/** \addtogroup sys - * @{ */ - -/** - * \defgroup timer Timer library - * - * The Contiki kernel does not provide support for timed - * events. Rather, an application that wants to use timers needs to - * explicitly use the timer library. - * - * The timer library provides functions for setting, resetting and - * restarting timers, and for checking if a timer has expired. An - * application must "manually" check if its timers have expired; this - * is not done automatically. - * - * A timer is declared as a \c struct \c timer and all access to the - * timer is made by a pointer to the declared timer. - * - * \note The timer library is not able to post events when a timer - * expires. The \ref etimer "Event timers" should be used for this - * purpose. - * - * \note The timer library uses the \ref clock "Clock library" to - * measure time. Intervals should be specified in the format used by - * the clock library. - * - * \sa \ref etimer "Event timers" - * - * @{ - */ - -#ifndef TIMER_H_ -#define TIMER_H_ - -#ifdef CONFIG_MICROKERNEL -#include -#else -#include -#endif - -#include - -#include "sys/clock.h" - -/** - * A timer. - * - * This structure is used for declaring a timer. The timer must be set - * with timer_set() before it can be used. - * - * \hideinitializer - */ -struct timer { - clock_time_t start; - clock_time_t interval; - struct nano_timer nano_timer; - int init_done; - int started; - int expired; - bool triggered; -}; - -CCIF void timer_set(struct timer *t, clock_time_t interval); -void timer_reset(struct timer *t); -void timer_restart(struct timer *t); -CCIF int timer_expired(struct timer *t); -clock_time_t timer_remaining(struct timer *t); -bool timer_stop(struct timer *t); -bool timer_is_triggered(struct timer *t); -void timer_set_triggered(struct timer *t); - -#endif /* TIMER_H_ */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/os/sys/types.h b/net/ip/contiki/os/sys/types.h deleted file mode 100644 index 977f499d87ee647a7ca7f79d2963252b51c4521c..0000000000000000000000000000000000000000 --- a/net/ip/contiki/os/sys/types.h +++ /dev/null @@ -1 +0,0 @@ -/* Empty file to satisfy compiler */ diff --git a/net/ip/contiki/packetbuf.c b/net/ip/contiki/packetbuf.c deleted file mode 100644 index 5fb61018e74aeca10740ebbd2ef4d49250a0f048..0000000000000000000000000000000000000000 --- a/net/ip/contiki/packetbuf.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Rime buffer (packetbuf) management - * \author - * Adam Dunkels - */ - -/** - * \addtogroup packetbuf - * @{ - */ - -#include - -#include - -#include "contiki-net.h" -#include "contiki/packetbuf.h" - -#if NETSTACK_CONF_WITH_RIME -#include "net/rime/rime.h" -#endif - -#if 0 -/* Moved to l2_buf.h */ -struct packetbuf_attr packetbuf_attrs[PACKETBUF_NUM_ATTRS]; -struct packetbuf_addr packetbuf_addrs[PACKETBUF_NUM_ADDRS]; - - -static uint16_t buflen, bufptr; -static uint8_t hdrptr; - -/* The declarations below ensure that the packet buffer is aligned on - an even 32-bit boundary. On some platforms (most notably the - msp430 or OpenRISC), having a potentially misaligned packet buffer may lead to - problems when accessing words. */ -static uint32_t packetbuf_aligned[(PACKETBUF_SIZE + PACKETBUF_HDR_SIZE + 3) / 4]; -static uint8_t *packetbuf = (uint8_t *)packetbuf_aligned; - -static uint8_t *packetbufptr; -#endif - -#define DEBUG 0 -#define DEBUG_LEVEL DEBUG -//#define DEBUG DEBUG_NONE -#include "contiki/ip/uip-debug.h" - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif - -/*---------------------------------------------------------------------------*/ -void -packetbuf_clear(struct net_buf *buf) -{ - uip_pkt_buflen(buf) = uip_pkt_bufptr(buf) = 0; - uip_pkt_hdrptr(buf) = PACKETBUF_HDR_SIZE; - - uip_pkt_packetbufptr(buf) = &uip_pkt_packetbuf(buf)[PACKETBUF_HDR_SIZE]; - packetbuf_attr_clear(buf); -} -/*---------------------------------------------------------------------------*/ -void -packetbuf_clear_hdr(struct net_buf *buf) -{ - uip_pkt_hdrptr(buf) = PACKETBUF_HDR_SIZE; -} -/*---------------------------------------------------------------------------*/ -int -packetbuf_copyfrom(struct net_buf *buf, const void *from, uint16_t len) -{ - uint16_t l; - - packetbuf_clear(buf); - l = len > PACKETBUF_SIZE? PACKETBUF_SIZE: len; - memcpy(uip_pkt_packetbufptr(buf), from, l); - uip_pkt_buflen(buf) = l; - return l; -} -/*---------------------------------------------------------------------------*/ -void -packetbuf_compact(struct net_buf *buf) -{ - int i, len; - - if(packetbuf_is_reference(buf)) { - memcpy(&uip_pkt_packetbuf(buf)[PACKETBUF_HDR_SIZE], packetbuf_reference_ptr(buf), - packetbuf_datalen(buf)); - } else if(uip_pkt_bufptr(buf) > 0) { - len = packetbuf_datalen(buf) + PACKETBUF_HDR_SIZE; - for(i = PACKETBUF_HDR_SIZE; i < len; i++) { - uip_pkt_packetbuf(buf)[i] = uip_pkt_packetbuf(buf)[uip_pkt_bufptr(buf) + i]; - } - - uip_pkt_bufptr(buf) = 0; - } -} -/*---------------------------------------------------------------------------*/ -int -packetbuf_copyto_hdr(struct net_buf *buf, uint8_t *to) -{ -#if DEBUG_LEVEL > 0 - { - int i; - PRINTF("packetbuf %p\n", uip_pkt_packetbuf(buf)); - PRINTF("packetbuf_write_hdr: header (from %p, %d bytes):\n", uip_pkt_hdrptr(buf), PACKETBUF_HDR_SIZE); - for(i = uip_pkt_hdrptr(buf); i < PACKETBUF_HDR_SIZE; ++i) { - PRINTF("0x%02x, ", uip_pkt_packetbuf(buf)[i]); - } - PRINTF("\n"); - } -#endif /* DEBUG_LEVEL */ - memcpy(to, uip_pkt_packetbuf(buf) + uip_pkt_hdrptr(buf), PACKETBUF_HDR_SIZE - uip_pkt_hdrptr(buf)); - return PACKETBUF_HDR_SIZE - uip_pkt_hdrptr(buf); -} -/*---------------------------------------------------------------------------*/ -int -packetbuf_copyto(struct net_buf *buf, void *to) -{ -#if DEBUG_LEVEL > 0 - { - int i; - char buffer[1000]; - char *bufferptr = buffer; - - bufferptr[0] = 0; - for(i = uip_pkt_hdrptr(buf); i < PACKETBUF_HDR_SIZE; ++i) { - bufferptr += sprintf(bufferptr, "0x%02x, ", uip_pkt_packetbuf(buf)[i]); - } - PRINTF("packetbuf_write: header: %s\n", buffer); - bufferptr = buffer; - bufferptr[0] = 0; - for(i = uip_pkt_bufptr(buf); i < uip_pkt_buflen(buf) + uip_pkt_bufptr(buf); ++i) { - bufferptr += sprintf(bufferptr, "0x%02x, ", uip_pkt_packetbufptr(buf)[i]); - } - PRINTF("packetbuf_write: data: %s\n", buffer); - } -#endif /* DEBUG_LEVEL */ - if(PACKETBUF_HDR_SIZE - uip_pkt_hdrptr(buf) + uip_pkt_buflen(buf) > PACKETBUF_SIZE) { - /* Too large packet */ - return 0; - } - memcpy(to, uip_pkt_packetbuf(buf) + uip_pkt_hdrptr(buf), PACKETBUF_HDR_SIZE - uip_pkt_hdrptr(buf)); - memcpy((uint8_t *)to + PACKETBUF_HDR_SIZE - uip_pkt_hdrptr(buf), uip_pkt_packetbufptr(buf) + uip_pkt_bufptr(buf), - uip_pkt_buflen(buf)); - return PACKETBUF_HDR_SIZE - uip_pkt_hdrptr(buf) + uip_pkt_buflen(buf); -} -/*---------------------------------------------------------------------------*/ -int -packetbuf_hdralloc(struct net_buf *buf, int size) -{ - if(uip_pkt_hdrptr(buf) >= size && packetbuf_totlen(buf) + size <= PACKETBUF_SIZE) { - uip_pkt_hdrptr(buf) -= size; - return 1; - } - return 0; -} -/*---------------------------------------------------------------------------*/ -void -packetbuf_hdr_remove(struct net_buf *buf, int size) -{ - uip_pkt_hdrptr(buf) += size; -} -/*---------------------------------------------------------------------------*/ -int -packetbuf_hdrreduce(struct net_buf *buf, int size) -{ - if(uip_pkt_buflen(buf) < size) { - return 0; - } - - uip_pkt_bufptr(buf) += size; - uip_pkt_buflen(buf) -= size; - return 1; -} -/*---------------------------------------------------------------------------*/ -void -packetbuf_set_datalen(struct net_buf *buf, uint16_t len) -{ - PRINTF("packetbuf_set_len: len %d\n", len); - uip_pkt_buflen(buf) = len; -} -/*---------------------------------------------------------------------------*/ -void * -packetbuf_dataptr(struct net_buf *buf) -{ - return (void *)(&uip_pkt_packetbuf(buf)[uip_pkt_bufptr(buf) + PACKETBUF_HDR_SIZE]); -} -/*---------------------------------------------------------------------------*/ -void * -packetbuf_hdrptr(struct net_buf *buf) -{ - return (void *)(&uip_pkt_packetbuf(buf)[uip_pkt_hdrptr(buf)]); -} -/*---------------------------------------------------------------------------*/ -void -packetbuf_reference(struct net_buf *buf, void *ptr, uint16_t len) -{ - packetbuf_clear(buf); - uip_pkt_packetbufptr(buf) = ptr; - uip_pkt_buflen(buf) = len; -} -/*---------------------------------------------------------------------------*/ -int -packetbuf_is_reference(struct net_buf *buf) -{ - return uip_pkt_packetbufptr(buf) != &uip_pkt_packetbuf(buf)[PACKETBUF_HDR_SIZE]; -} -/*---------------------------------------------------------------------------*/ -void * -packetbuf_reference_ptr(struct net_buf *buf) -{ - return uip_pkt_packetbufptr(buf); -} -/*---------------------------------------------------------------------------*/ -uint16_t -packetbuf_datalen(struct net_buf *buf) -{ - return uip_pkt_buflen(buf); -} -/*---------------------------------------------------------------------------*/ -uint8_t -packetbuf_hdrlen(struct net_buf *buf) -{ - uint8_t hdrlen; - - hdrlen = PACKETBUF_HDR_SIZE - uip_pkt_hdrptr(buf); - if(hdrlen) { - /* outbound packet */ - return hdrlen; - } else { - /* inbound packet */ - return uip_pkt_bufptr(buf); - } -} -/*---------------------------------------------------------------------------*/ -uint16_t -packetbuf_totlen(struct net_buf *buf) -{ - return packetbuf_hdrlen(buf) + packetbuf_datalen(buf); -} -/*---------------------------------------------------------------------------*/ -void -packetbuf_attr_clear(struct net_buf *buf) -{ - int i; - for(i = 0; i < PACKETBUF_NUM_ATTRS; ++i) { - uip_pkt_packetbuf_attrs(buf)[i].val = 0; - } - for(i = 0; i < PACKETBUF_NUM_ADDRS; ++i) { - linkaddr_copy(&uip_pkt_packetbuf_addrs(buf)[i].addr, &linkaddr_null); - } -} -/*---------------------------------------------------------------------------*/ -void -packetbuf_attr_copyto(struct net_buf *buf, struct packetbuf_attr *attrs, - struct packetbuf_addr *addrs) -{ - memcpy(attrs, uip_pkt_packetbuf_attrs(buf), sizeof(uip_pkt_packetbuf_attrs(buf))); - memcpy(addrs, uip_pkt_packetbuf_addrs(buf), sizeof(uip_pkt_packetbuf_addrs(buf))); -} -/*---------------------------------------------------------------------------*/ -void -packetbuf_attr_copyfrom(struct net_buf *buf, struct packetbuf_attr *attrs, - struct packetbuf_addr *addrs) -{ - memcpy(uip_pkt_packetbuf_attrs(buf), attrs, sizeof(uip_pkt_packetbuf_attrs(buf))); - memcpy(uip_pkt_packetbuf_addrs(buf), addrs, sizeof(uip_pkt_packetbuf_addrs(buf))); -} -/*---------------------------------------------------------------------------*/ -#if !PACKETBUF_CONF_ATTRS_INLINE -int -packetbuf_set_attr(struct net_buf *buf, uint8_t type, const packetbuf_attr_t val) -{ -/* uip_pkt_packetbuf_attrs(buf)[type].type = type; */ - uip_pkt_packetbuf_attrs(buf)[type].val = val; - return 1; -} -/*---------------------------------------------------------------------------*/ -packetbuf_attr_t -packetbuf_attr(struct net_buf *buf, uint8_t type) -{ - return uip_pkt_packetbuf_attrs(buf)[type].val; -} -/*---------------------------------------------------------------------------*/ -int -packetbuf_set_addr(struct net_buf *buf, uint8_t type, const linkaddr_t *addr) -{ -/* uip_pkt_packetbuf_addrs(buf)[type - PACKETBUF_ADDR_FIRST].type = type; */ - linkaddr_copy(&uip_pkt_packetbuf_addrs(buf)[type - PACKETBUF_ADDR_FIRST].addr, addr); - return 1; -} -/*---------------------------------------------------------------------------*/ -const linkaddr_t * -packetbuf_addr(struct net_buf *buf, uint8_t type) -{ - return &uip_pkt_packetbuf_addrs(buf)[type - PACKETBUF_ADDR_FIRST].addr; -} -/*---------------------------------------------------------------------------*/ -#endif /* PACKETBUF_CONF_ATTRS_INLINE */ -int -packetbuf_holds_broadcast(struct net_buf *buf) -{ - return linkaddr_cmp(&uip_pkt_packetbuf_addrs(buf)[PACKETBUF_ADDR_RECEIVER - PACKETBUF_ADDR_FIRST].addr, &linkaddr_null); -} -/*---------------------------------------------------------------------------*/ - -/** @} */ diff --git a/net/ip/contiki/packetbuf.h b/net/ip/contiki/packetbuf.h deleted file mode 100644 index 6f93e8b83c969708e0bbf41e2f7e11b20eb72acd..0000000000000000000000000000000000000000 --- a/net/ip/contiki/packetbuf.h +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header file for the Rime buffer (packetbuf) management - * \author - * Adam Dunkels - */ - -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup packetbuf Rime buffer management - * @{ - * - * The packetbuf module does Rime's buffer management. - */ - -#include "contiki-conf.h" -#include "contiki/linkaddr.h" -#include "contiki/llsec/llsec802154.h" - -#ifndef PACKETBUF_H_ -#define PACKETBUF_H_ - -/** - * \brief The size of the packetbuf, in bytes - */ -#ifdef PACKETBUF_CONF_SIZE -#define PACKETBUF_SIZE PACKETBUF_CONF_SIZE -#else -#define PACKETBUF_SIZE 128 -#endif - -/** - * \brief The size of the packetbuf header, in bytes - */ -#ifdef PACKETBUF_CONF_HDR_SIZE -#define PACKETBUF_HDR_SIZE PACKETBUF_CONF_HDR_SIZE -#else -#define PACKETBUF_HDR_SIZE 48 -#endif - -struct net_buf; - -/** - * \brief Clear and reset the packetbuf - * - * This function clears the packetbuf and resets all - * internal state pointers (header size, header pointer, - * external data pointer). It is used before preparing a - * packet in the packetbuf. - * - */ -void packetbuf_clear(struct net_buf *buf); - -/** - * \brief Clear and reset the header of the packetbuf - * - * This function clears the header of the packetbuf and - * resets all the internal state pointers pertaining to - * the header (header size, header pointer, but not - * external data pointer). It is used before after sending - * a packet in the packetbuf, to be able to reuse the - * packet buffer for a later retransmission. - * - */ -void packetbuf_clear_hdr(struct net_buf *buf); - -void packetbuf_hdr_remove(struct net_buf *buf, int bytes); - -/** - * \brief Get a pointer to the data in the packetbuf - * \return Pointer to the packetbuf data - * - * This function is used to get a pointer to the data in - * the packetbuf. The data is either stored in the packetbuf, - * or referenced to an external location. - * - * For outbound packets, the packetbuf consists of two - * parts: header and data. The header is accessed with the - * packetbuf_hdrptr() function. - * - * For incoming packets, both the packet header and the - * packet data is stored in the data portion of the - * packetbuf. Thus this function is used to get a pointer to - * the header for incoming packets. - * - */ -void *packetbuf_dataptr(struct net_buf *buf); - -/** - * \brief Get a pointer to the header in the packetbuf, for outbound packets - * \return Pointer to the packetbuf header - * - * For outbound packets, the packetbuf consists of two - * parts: header and data. This function is used to get a - * pointer to the header in the packetbuf. The header is - * stored in the packetbuf. - * - */ -void *packetbuf_hdrptr(struct net_buf *buf); - -/** - * \brief Get the length of the header in the packetbuf - * \return Length of the header in the packetbuf - * - * For outbound packets, the packetbuf consists of two - * parts: header and data. This function is used to get - * the length of the header in the packetbuf. The header is - * stored in the packetbuf and accessed via the - * packetbuf_hdrptr() function. - * - */ -uint8_t packetbuf_hdrlen(struct net_buf *buf); - - -/** - * \brief Get the length of the data in the packetbuf - * \return Length of the data in the packetbuf - * - * For outbound packets, the packetbuf consists of two - * parts: header and data. This function is used to get - * the length of the data in the packetbuf. The data is - * stored in the packetbuf and accessed via the - * packetbuf_dataptr() function. - * - * For incoming packets, both the packet header and the - * packet data is stored in the data portion of the - * packetbuf. This function is then used to get the total - * length of the packet - both header and data. - * - */ -uint16_t packetbuf_datalen(struct net_buf *buf); - -/** - * \brief Get the total length of the header and data in the packetbuf - * \return Length of data and header in the packetbuf - * - */ -uint16_t packetbuf_totlen(struct net_buf *buf); - -/** - * \brief Set the length of the data in the packetbuf - * \param len The length of the data - * - * For outbound packets, the packetbuf consists of two - * parts: header and data. This function is used to set - * the length of the data in the packetbuf. - */ -void packetbuf_set_datalen(struct net_buf *buf, uint16_t len); - -/** - * \brief Point the packetbuf to external data - * \param ptr A pointer to the external data - * \param len The length of the external data - * - * For outbound packets, the packetbuf consists of two - * parts: header and data. This function is used to make - * the packetbuf point to external data. The function also - * specifies the length of the external data that the - * packetbuf references. - */ -void packetbuf_reference(struct net_buf *buf, void *ptr, uint16_t len); - -/** - * \brief Check if the packetbuf references external data - * \retval Non-zero if the packetbuf references external data, zero otherwise. - * - * For outbound packets, the packetbuf consists of two - * parts: header and data. This function is used to check - * if the packetbuf points to external data that has - * previously been referenced with packetbuf_reference(). - * - */ -int packetbuf_is_reference(struct net_buf *buf); - -/** - * \brief Get a pointer to external data referenced by the packetbuf - * \retval A pointer to the external data - * - * For outbound packets, the packetbuf consists of two - * parts: header and data. The data may point to external - * data that has previously been referenced with - * packetbuf_reference(). This function is used to get a - * pointer to the external data. - * - */ -void *packetbuf_reference_ptr(struct net_buf *buf); - -/** - * \brief Compact the packetbuf - * - * This function compacts the packetbuf by copying the data - * portion of the packetbuf so that becomes consecutive to - * the header. It also copies external data that has - * previously been referenced with packetbuf_reference() - * into the packetbuf. - * - * This function is called by the Rime code before a - * packet is to be sent by a device driver. This assures - * that the entire packet is consecutive in memory. - * - */ -void packetbuf_compact(struct net_buf *buf); - -/** - * \brief Copy from external data into the packetbuf - * \param from A pointer to the data from which to copy - * \param len The size of the data to copy - * \retval The number of bytes that was copied into the packetbuf - * - * This function copies data from a pointer into the - * packetbuf. If the data that is to be copied is larger - * than the packetbuf, only the data that fits in the - * packetbuf is copied. The number of bytes that could be - * copied into the rimbuf is returned. - * - */ -int packetbuf_copyfrom(struct net_buf *buf, const void *from, uint16_t len); - -/** - * \brief Copy the entire packetbuf to an external buffer - * \param to A pointer to the buffer to which the data is to be copied - * \retval The number of bytes that was copied to the external buffer - * - * This function copies the packetbuf to an external - * buffer. Both the data portion and the header portion of - * the packetbuf is copied. If the packetbuf referenced - * external data (referenced with packetbuf_reference()) the - * external data is copied. - * - * The external buffer to which the packetbuf is to be - * copied must be able to accommodate at least - * (PACKETBUF_SIZE + PACKETBUF_HDR_SIZE) bytes. The number of - * bytes that was copied to the external buffer is - * returned. - * - */ -int packetbuf_copyto(struct net_buf *buf, void *to); - -/** - * \brief Copy the header portion of the packetbuf to an external buffer - * \param to A pointer to the buffer to which the data is to be copied - * \retval The number of bytes that was copied to the external buffer - * - * This function copies the header portion of the packetbuf - * to an external buffer. - * - * The external buffer to which the packetbuf is to be - * copied must be able to accommodate at least - * PACKETBUF_HDR_SIZE bytes. The number of bytes that was - * copied to the external buffer is returned. - * - */ -int packetbuf_copyto_hdr(struct net_buf *buf, uint8_t *to); - -/** - * \brief Extend the header of the packetbuf, for outbound packets - * \param size The number of bytes the header should be extended - * \retval Non-zero if the header could be extended, zero otherwise - * - * This function is used to allocate extra space in the - * header portion in the packetbuf, when preparing outbound - * packets for transmission. If the function is unable to - * allocate sufficient header space, the function returns - * zero and does not allocate anything. - * - */ -int packetbuf_hdralloc(struct net_buf *buf, int size); - -/** - * \brief Reduce the header in the packetbuf, for incoming packets - * \param size The number of bytes the header should be reduced - * \retval Non-zero if the header could be reduced, zero otherwise - * - * This function is used to remove the first part of the - * header in the packetbuf, when processing incoming - * packets. If the function is unable to remove the - * requested amount of header space, the function returns - * zero and does not allocate anything. - * - */ -int packetbuf_hdrreduce(struct net_buf *buf, int size); - -/* Packet attributes stuff below: */ - -typedef uint16_t packetbuf_attr_t; - -struct packetbuf_attr { -/* uint8_t type; */ - packetbuf_attr_t val; -}; -struct packetbuf_addr { -/* uint8_t type; */ - linkaddr_t addr; -}; - -#define PACKETBUF_ATTR_PACKET_TYPE_DATA 0 -#define PACKETBUF_ATTR_PACKET_TYPE_ACK 1 -#define PACKETBUF_ATTR_PACKET_TYPE_STREAM 2 -#define PACKETBUF_ATTR_PACKET_TYPE_STREAM_END 3 -#define PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP 4 - -enum { - PACKETBUF_ATTR_NONE, - - /* Scope 0 attributes: used only on the local node. */ - PACKETBUF_ATTR_CHANNEL, - PACKETBUF_ATTR_NETWORK_ID, - PACKETBUF_ATTR_LINK_QUALITY, - PACKETBUF_ATTR_RSSI, - PACKETBUF_ATTR_TIMESTAMP, - PACKETBUF_ATTR_RADIO_TXPOWER, - PACKETBUF_ATTR_LISTEN_TIME, - PACKETBUF_ATTR_TRANSMIT_TIME, - PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, - PACKETBUF_ATTR_MAC_SEQNO, - PACKETBUF_ATTR_MAC_ACK, - PACKETBUF_ATTR_IS_CREATED_AND_SECURED, - - /* Scope 1 attributes: used between two neighbors only. */ - PACKETBUF_ATTR_RELIABLE, - PACKETBUF_ATTR_PACKET_ID, - PACKETBUF_ATTR_PACKET_TYPE, -#if NETSTACK_CONF_WITH_RIME - PACKETBUF_ATTR_REXMIT, - PACKETBUF_ATTR_MAX_REXMIT, - PACKETBUF_ATTR_NUM_REXMIT, -#endif /* NETSTACK_CONF_WITH_RIME */ - PACKETBUF_ATTR_PENDING, - PACKETBUF_ATTR_FRAME_TYPE, -#if LLSEC802154_SECURITY_LEVEL - PACKETBUF_ATTR_SECURITY_LEVEL, - PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, - PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, -#if LLSEC802154_USES_EXPLICIT_KEYS - PACKETBUF_ATTR_KEY_ID_MODE, - PACKETBUF_ATTR_KEY_INDEX, - PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1, -#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ -#endif /* LLSEC802154_SECURITY_LEVEL */ - - /* Scope 2 attributes: used between end-to-end nodes. */ -#if NETSTACK_CONF_WITH_RIME - PACKETBUF_ATTR_HOPS, - PACKETBUF_ATTR_TTL, - PACKETBUF_ATTR_EPACKET_ID, - PACKETBUF_ATTR_EPACKET_TYPE, - PACKETBUF_ATTR_ERELIABLE, -#endif /* NETSTACK_CONF_WITH_RIME */ - - /* These must be last */ - PACKETBUF_ADDR_SENDER, - PACKETBUF_ADDR_RECEIVER, -#if NETSTACK_CONF_WITH_RIME - PACKETBUF_ADDR_ESENDER, - PACKETBUF_ADDR_ERECEIVER, -#endif /* NETSTACK_CONF_WITH_RIME */ - - PACKETBUF_ATTR_MAX -}; - -/* Define surrogates when 802.15.4 security is off */ -#if !LLSEC802154_SECURITY_LEVEL -enum { - PACKETBUF_ATTR_SECURITY_LEVEL, - PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, - PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3 -}; -#endif /* LLSEC802154_SECURITY_LEVEL */ - -/* Define surrogates when not using explicit keys */ -#if !LLSEC802154_USES_EXPLICIT_KEYS -enum { - PACKETBUF_ATTR_KEY_ID_MODE, - PACKETBUF_ATTR_KEY_INDEX, - PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1 -}; -#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ - -#if NETSTACK_CONF_WITH_RIME -#define PACKETBUF_NUM_ADDRS 4 -#else /* NETSTACK_CONF_WITH_RIME */ -#define PACKETBUF_NUM_ADDRS 2 -#endif /* NETSTACK_CONF_WITH_RIME */ -#define PACKETBUF_NUM_ATTRS (PACKETBUF_ATTR_MAX - PACKETBUF_NUM_ADDRS) -#define PACKETBUF_ADDR_FIRST PACKETBUF_ADDR_SENDER - -#define PACKETBUF_IS_ADDR(type) ((type) >= PACKETBUF_ADDR_FIRST) - -#if PACKETBUF_CONF_ATTRS_INLINE - -#if 0 -/* Moved to net_buf.h */ -extern struct packetbuf_attr packetbuf_attrs[]; -extern struct packetbuf_addr packetbuf_addrs[]; -#endif - -static int packetbuf_set_attr(struct net_buf *buf, uint8_t type, const packetbuf_attr_t val); -static packetbuf_attr_t packetbuf_attr(struct net_buf *buf, uint8_t type); -static int packetbuf_set_addr(struct net_buf *buf, uint8_t type, const linkaddr_t *addr); -static const linkaddr_t *packetbuf_addr(struct net_buf *buf, uint8_t type); - -static inline int -packetbuf_set_attr(struct net_buf *buf, uint8_t type, const packetbuf_attr_t val) -{ -/* packetbuf_attrs[type].type = type; */ - uip_pkt_packetbuf_attrs(buf)[type].val = val; - return 1; -} -static inline packetbuf_attr_t -packetbuf_attr(struct net_buf *buf, uint8_t type) -{ - return uip_pkt_packetbuf_attrs(buf)[type].val; -} - -static inline int -packetbuf_set_addr(struct net_buf *buf, uint8_t type, const linkaddr_t *addr) -{ -/* packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].type = type; */ - linkaddr_copy(&uip_pkt_packetbuf_addrs(buf)[type - PACKETBUF_ADDR_FIRST].addr, addr); - return 1; -} - -static inline const linkaddr_t * -packetbuf_addr(struct net_buf *buf, uint8_t type) -{ - return &uip_pkt_packetbuf_addrs(buf)[type - PACKETBUF_ADDR_FIRST].addr; -} -#else /* PACKETBUF_CONF_ATTRS_INLINE */ -int packetbuf_set_attr(struct net_buf *buf, uint8_t type, const packetbuf_attr_t val); -packetbuf_attr_t packetbuf_attr(struct net_buf *buf, uint8_t type); -int packetbuf_set_addr(struct net_buf *buf, uint8_t type, const linkaddr_t *addr); -const linkaddr_t *packetbuf_addr(struct net_buf *buf, uint8_t type); -#endif /* PACKETBUF_CONF_ATTRS_INLINE */ - -/** - * \brief Checks whether the current packet is a broadcast. - * \retval 0 iff current packet is not a broadcast - */ -int packetbuf_holds_broadcast(struct net_buf *buf); - -void packetbuf_attr_clear(struct net_buf *buf); - -void packetbuf_attr_copyto(struct net_buf *buf, - struct packetbuf_attr *attrs, - struct packetbuf_addr *addrs); -void packetbuf_attr_copyfrom(struct net_buf *buf, - struct packetbuf_attr *attrs, - struct packetbuf_addr *addrs); - -#define PACKETBUF_ATTRIBUTES(...) { __VA_ARGS__ PACKETBUF_ATTR_LAST } -#define PACKETBUF_ATTR_LAST { PACKETBUF_ATTR_NONE, 0 } - -#define PACKETBUF_ATTR_BIT 1 -#define PACKETBUF_ATTR_BYTE 8 -#define PACKETBUF_ADDRSIZE (LINKADDR_SIZE * PACKETBUF_ATTR_BYTE) - -struct packetbuf_attrlist { - uint8_t type; - uint8_t len; -}; - -#endif /* PACKETBUF_H_ */ -/** @} */ -/** @} */ diff --git a/net/ip/contiki/queuebuf.c b/net/ip/contiki/queuebuf.c deleted file mode 100644 index 8b97809d3fe0b2e1ea6508cdf309817ed4df8bcb..0000000000000000000000000000000000000000 --- a/net/ip/contiki/queuebuf.c +++ /dev/null @@ -1,532 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Implementation of the Rime queue buffers - * \author - * Adam Dunkels - */ - -/** - * \addtogroup rimequeuebuf - * @{ - */ - -#include "contiki-net.h" -#include "memb.h" -#include "queuebuf.h" -#if WITH_SWAP -#include "cfs/cfs.h" -#endif - -#include /* for memcpy() */ - -#ifdef QUEUEBUF_CONF_REF_NUM -#define QUEUEBUF_REF_NUM QUEUEBUF_CONF_REF_NUM -#else -#define QUEUEBUF_REF_NUM 2 -#endif - -/* Structure pointing to a buffer either stored - in RAM or swapped in CFS */ -struct queuebuf { -#if QUEUEBUF_DEBUG - struct queuebuf *next; - const char *file; - int line; - clock_time_t time; -#endif /* QUEUEBUF_DEBUG */ -#if WITH_SWAP - enum {IN_RAM, IN_CFS} location; - union { -#endif - struct queuebuf_data *ram_ptr; -#if WITH_SWAP - int swap_id; - }; -#endif -}; - -/* The actual queuebuf data */ -struct queuebuf_data { - uint8_t data[PACKETBUF_SIZE]; - uint16_t len; - struct packetbuf_attr attrs[PACKETBUF_NUM_ATTRS]; - struct packetbuf_addr addrs[PACKETBUF_NUM_ADDRS]; -}; - -struct queuebuf_ref { - uint16_t len; - uint8_t *ref; - uint8_t hdr[PACKETBUF_HDR_SIZE]; - uint8_t hdrlen; -}; - -MEMB(bufmem, struct queuebuf, QUEUEBUF_NUM); -MEMB(refbufmem, struct queuebuf_ref, QUEUEBUF_REF_NUM); -MEMB(buframmem, struct queuebuf_data, QUEUEBUFRAM_NUM); - -#if WITH_SWAP - -/* Swapping allows to store up to QUEUEBUF_NUM - QUEUEBUFRAM_NUM - queuebufs in CFS. The swap is made of several large CFS files. - Every buffer stored in CFS has a swap id, referring to a specific - offset in one of these files. */ -#define NQBUF_FILES 4 -#define NQBUF_PER_FILE 256 -#define QBUF_FILE_SIZE (NQBUF_PER_FILE*sizeof(struct queuebuf_data)) -#define NQBUF_ID (NQBUF_PER_FILE * NQBUF_FILES) - -struct qbuf_file { - int fd; - int usage; - int renewable; -}; - -/* A statically allocated queuebuf used as a cache for swapped qbufs */ -static struct queuebuf_data tmpdata; -/* A pointer to the qbuf associated to the data in tmpdata */ -static struct queuebuf *tmpdata_qbuf = NULL; -/* The swap id counter */ -static int next_swap_id = 0; -/* The swap files */ -static struct qbuf_file qbuf_files[NQBUF_FILES]; -/* The timer used to renew files during inactivity periods */ -static struct ctimer renew_timer; - -#endif - -#if QUEUEBUF_DEBUG -#include "lib/list.h" -LIST(queuebuf_list); -#endif /* QUEUEBUF_DEBUG */ - -#define DEBUG 0 -#include "contiki/ip/uip-debug.h" - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif - -#ifdef QUEUEBUF_CONF_STATS -#define QUEUEBUF_STATS QUEUEBUF_CONF_STATS -#else -#define QUEUEBUF_STATS 0 -#endif /* QUEUEBUF_CONF_STATS */ - -#if QUEUEBUF_STATS -uint8_t queuebuf_len, queuebuf_ref_len, queuebuf_max_len; -#endif /* QUEUEBUF_STATS */ - -#if WITH_SWAP -/*---------------------------------------------------------------------------*/ -static void -qbuf_renew_file(int file) -{ - int ret; - char name[2]; - name[0] = 'a' + file; - name[1] = '\0'; - if(qbuf_files[file].renewable == 1) { - PRINTF("qbuf_renew_file: removing file %d\n", file); - cfs_remove(name); - } - ret = cfs_open(name, CFS_READ | CFS_WRITE); - if(ret == -1) { - PRINTF("qbuf_renew_file: cfs open error\n"); - } - qbuf_files[file].fd = ret; - qbuf_files[file].usage = 0; - qbuf_files[file].renewable = 0; -} -/*---------------------------------------------------------------------------*/ -/* Renews every file with renewable flag set */ -static void -qbuf_renew_all(void *unused) -{ - int i; - for(i=0; iswap_id == swap_id) { - tmpdata_qbuf->swap_id = -1; - } - } -} -/*---------------------------------------------------------------------------*/ -static int -get_new_swap_id(void) -{ - int fileid; - int swap_id = next_swap_id; - fileid = swap_id / NQBUF_PER_FILE; - if(swap_id % NQBUF_PER_FILE == 0) { /* This is the first id in the file */ - if(qbuf_files[fileid].renewable) { - qbuf_renew_file(fileid); - } - if(qbuf_files[fileid].usage>0) { - return -1; - } - } - qbuf_files[fileid].usage++; - next_swap_id = (next_swap_id+1) % NQBUF_ID; - return swap_id; -} -/*---------------------------------------------------------------------------*/ -/* Flush tmpdata to CFS */ -static int -queuebuf_flush_tmpdata(void) -{ - int fileid, fd, ret; - cfs_offset_t offset; - if(tmpdata_qbuf) { - queuebuf_remove_from_file(tmpdata_qbuf->swap_id); - tmpdata_qbuf->swap_id = get_new_swap_id(); - if(tmpdata_qbuf->swap_id == -1) { - return -1; - } - fileid = tmpdata_qbuf->swap_id / NQBUF_PER_FILE; - offset = (tmpdata_qbuf->swap_id % NQBUF_PER_FILE) * sizeof(struct queuebuf_data); - fd = qbuf_files[fileid].fd; - ret = cfs_seek(fd, offset, CFS_SEEK_SET); - if(ret == -1) { - PRINTF("queuebuf_flush_tmpdata: cfs seek error\n"); - return -1; - } - ret = cfs_write(fd, &tmpdata, sizeof(struct queuebuf_data)); - if(ret == -1) { - PRINTF("queuebuf_flush_tmpdata: cfs write error\n"); - return -1; - } - } - return 0; -} -/*---------------------------------------------------------------------------*/ -/* If the queuebuf is in CFS, load it to tmpdata */ -static struct queuebuf_data * -queuebuf_load_to_ram(struct queuebuf *b) -{ - int fileid, fd, ret; - cfs_offset_t offset; - if(b->location == IN_RAM) { /* the qbuf is loacted in RAM */ - return b->ram_ptr; - } else { /* the qbuf is located in CFS */ - if(tmpdata_qbuf && tmpdata_qbuf->swap_id == b->swap_id) { /* the qbuf is already in tmpdata */ - return &tmpdata; - } else { /* the qbuf needs to be loaded from CFS */ - tmpdata_qbuf = b; - /* read the qbuf from CFS */ - fileid = b->swap_id / NQBUF_PER_FILE; - offset = (b->swap_id % NQBUF_PER_FILE) * sizeof(struct queuebuf_data); - fd = qbuf_files[fileid].fd; - ret = cfs_seek(fd, offset, CFS_SEEK_SET); - if(ret == -1) { - PRINTF("queuebuf_load_to_ram: cfs seek error\n"); - } - ret = cfs_read(fd, &tmpdata, sizeof(struct queuebuf_data)); - if(ret == -1) { - PRINTF("queuebuf_load_to_ram: cfs read error\n"); - } - return &tmpdata; - } - } -} -#else /* WITH_SWAP */ -/*---------------------------------------------------------------------------*/ -static struct queuebuf_data * -queuebuf_load_to_ram(struct queuebuf *b) -{ - return b->ram_ptr; -} -#endif /* WITH_SWAP */ -/*---------------------------------------------------------------------------*/ -void -queuebuf_init(void) -{ -#if WITH_SWAP - int i; - for(i=0; ilen = packetbuf_datalen(netbuf); - rbuf->ref = packetbuf_reference_ptr(netbuf); - rbuf->hdrlen = packetbuf_copyto_hdr(netbuf, rbuf->hdr); - } else { - PRINTF("queuebuf_new_from_packetbuf: could not allocate a reference queuebuf\n"); - } - return (struct queuebuf *)rbuf; - } else { - struct queuebuf_data *buframptr; - buf = memb_alloc(&bufmem); - if(buf != NULL) { -#if QUEUEBUF_DEBUG - list_add(queuebuf_list, buf); - buf->file = file; - buf->line = line; - buf->time = clock_time(); -#endif /* QUEUEBUF_DEBUG */ - buf->ram_ptr = memb_alloc(&buframmem); -#if WITH_SWAP - /* If the allocation failed, store the qbuf in swap files */ - if(buf->ram_ptr != NULL) { - buf->location = IN_RAM; - buframptr = buf->ram_ptr; - } else { - buf->location = IN_CFS; - buf->swap_id = -1; - tmpdata_qbuf = buf; - buframptr = &tmpdata; - } -#else - if(buf->ram_ptr == NULL) { - PRINTF("queuebuf_new_from_packetbuf: could not queuebuf data\n"); - memb_free(&bufmem, buf); - return NULL; - } - buframptr = buf->ram_ptr; -#endif - - buframptr->len = packetbuf_copyto(netbuf, buframptr->data); - packetbuf_attr_copyto(netbuf, buframptr->attrs, buframptr->addrs); - -#if WITH_SWAP - if(buf->location == IN_CFS) { - if(queuebuf_flush_tmpdata() == -1) { - /* We were unable to write the data in the swap */ - memb_free(&bufmem, buf); - return NULL; - } - } -#endif - -#if QUEUEBUF_STATS - ++queuebuf_len; - PRINTF("queuebuf len %d\n", queuebuf_len); - printf("#A q=%d\n", queuebuf_len); - if(queuebuf_len == queuebuf_max_len + 1) { - queuebuf_free(buf); - queuebuf_len--; - return NULL; - } -#endif /* QUEUEBUF_STATS */ - - } else { - PRINTF("queuebuf_new_from_packetbuf: could not allocate a queuebuf\n"); - } - return buf; - } -} -/*---------------------------------------------------------------------------*/ -void -queuebuf_update_attr_from_packetbuf(struct net_buf *netbuf, struct queuebuf *buf) -{ - struct queuebuf_data *buframptr = queuebuf_load_to_ram(buf); - packetbuf_attr_copyto(netbuf, buframptr->attrs, buframptr->addrs); -#if WITH_SWAP - if(buf->location == IN_CFS) { - queuebuf_flush_tmpdata(); - } -#endif -} -/*---------------------------------------------------------------------------*/ -void -queuebuf_update_from_packetbuf(struct net_buf *netbuf, struct queuebuf *buf) -{ - struct queuebuf_data *buframptr = queuebuf_load_to_ram(buf); - packetbuf_attr_copyto(netbuf, buframptr->attrs, buframptr->addrs); - buframptr->len = packetbuf_copyto(netbuf, buframptr->data); -#if WITH_SWAP - if(buf->location == IN_CFS) { - queuebuf_flush_tmpdata(); - } -#endif -} -/*---------------------------------------------------------------------------*/ -void -queuebuf_free(struct queuebuf *buf) -{ - if(memb_inmemb(&bufmem, buf)) { -#if WITH_SWAP - if(buf->location == IN_RAM) { - memb_free(&buframmem, buf->ram_ptr); - } else { - queuebuf_remove_from_file(buf->swap_id); - } -#else - memb_free(&buframmem, buf->ram_ptr); -#endif - memb_free(&bufmem, buf); -#if QUEUEBUF_STATS - --queuebuf_len; - printf("#A q=%d\n", queuebuf_len); -#endif /* QUEUEBUF_STATS */ -#if QUEUEBUF_DEBUG - list_remove(queuebuf_list, buf); -#endif /* QUEUEBUF_DEBUG */ - } else if(memb_inmemb(&refbufmem, buf)) { - memb_free(&refbufmem, buf); -#if QUEUEBUF_STATS - --queuebuf_ref_len; -#endif /* QUEUEBUF_STATS */ - } -} -/*---------------------------------------------------------------------------*/ -void -queuebuf_to_packetbuf(struct net_buf *netbuf, struct queuebuf *b) -{ - struct queuebuf_ref *r; - if(memb_inmemb(&bufmem, b)) { - struct queuebuf_data *buframptr = queuebuf_load_to_ram(b); - packetbuf_copyfrom(netbuf, buframptr->data, buframptr->len); - packetbuf_attr_copyfrom(netbuf, buframptr->attrs, buframptr->addrs); - } else if(memb_inmemb(&refbufmem, b)) { - r = (struct queuebuf_ref *)b; - packetbuf_clear(netbuf); - packetbuf_copyfrom(netbuf, r->ref, r->len); - packetbuf_hdralloc(netbuf, r->hdrlen); - memcpy(packetbuf_hdrptr(netbuf), r->hdr, r->hdrlen); - } -} -/*---------------------------------------------------------------------------*/ -void * -queuebuf_dataptr(struct queuebuf *b) -{ - struct queuebuf_ref *r; - - if(memb_inmemb(&bufmem, b)) { - struct queuebuf_data *buframptr = queuebuf_load_to_ram(b); - return buframptr->data; - } else if(memb_inmemb(&refbufmem, b)) { - r = (struct queuebuf_ref *)b; - return r->ref; - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -int -queuebuf_datalen(struct queuebuf *b) -{ - struct queuebuf_data *buframptr = queuebuf_load_to_ram(b); - return buframptr->len; -} -/*---------------------------------------------------------------------------*/ -linkaddr_t * -queuebuf_addr(struct queuebuf *b, uint8_t type) -{ - struct queuebuf_data *buframptr = queuebuf_load_to_ram(b); - return &buframptr->addrs[type - PACKETBUF_ADDR_FIRST].addr; -} -/*---------------------------------------------------------------------------*/ -packetbuf_attr_t -queuebuf_attr(struct queuebuf *b, uint8_t type) -{ - struct queuebuf_data *buframptr = queuebuf_load_to_ram(b); - return buframptr->attrs[type].val; -} -/*---------------------------------------------------------------------------*/ -void -queuebuf_debug_print(void) -{ -#if QUEUEBUF_DEBUG - struct queuebuf *q; - printf("queuebuf_list: "); - for(q = list_head(queuebuf_list); q != NULL; - q = list_item_next(q)) { - printf("%s,%d,%lu ", q->file, q->line, q->time); - } - printf("\n"); -#endif /* QUEUEBUF_DEBUG */ -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/queuebuf.h b/net/ip/contiki/queuebuf.h deleted file mode 100644 index 437bd5b43e27caff018470422b17c84ea64b0c3d..0000000000000000000000000000000000000000 --- a/net/ip/contiki/queuebuf.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header file for the Rime queue buffer management - * \author - * Adam Dunkels - */ - -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rimequeuebuf Rime queue buffer management - * @{ - * - * The queuebuf module handles buffers that are queued. - * - */ - -#ifndef QUEUEBUF_H_ -#define QUEUEBUF_H_ - -#include "contiki/packetbuf.h" - -/* QUEUEBUF_NUM is the total number of queuebuf */ -#ifdef QUEUEBUF_CONF_NUM -#define QUEUEBUF_NUM QUEUEBUF_CONF_NUM -#else -#define QUEUEBUF_NUM 8 -#endif - -/* QUEUEBUFRAM_NUM is the number of queuebufs stored in RAM. - If QUEUEBUFRAM_CONF_NUM is set lower than QUEUEBUF_NUM, - swapping is enabled and queuebufs are stored either in RAM of CFS. - If QUEUEBUFRAM_CONF_NUM is unset or >= to QUEUEBUF_NUM, all - queuebufs are in RAM and swapping is disabled. */ -#ifdef QUEUEBUFRAM_CONF_NUM - #if QUEUEBUFRAM_CONF_NUM>QUEUEBUF_NUM - #error "QUEUEBUFRAM_CONF_NUM cannot be greater than QUEUEBUF_NUM" - #else - #define QUEUEBUFRAM_NUM QUEUEBUFRAM_CONF_NUM - #define WITH_SWAP (QUEUEBUFRAM_NUM < QUEUEBUF_NUM) - #endif -#else /* QUEUEBUFRAM_CONF_NUM */ - #define QUEUEBUFRAM_NUM QUEUEBUF_NUM - #define WITH_SWAP 0 -#endif /* QUEUEBUFRAM_CONF_NUM */ - -#ifdef QUEUEBUF_CONF_DEBUG -#define QUEUEBUF_DEBUG QUEUEBUF_CONF_DEBUG -#else /* QUEUEBUF_CONF_DEBUG */ -#define QUEUEBUF_DEBUG 0 -#endif /* QUEUEBUF_CONF_DEBUG */ - -struct queuebuf; - -void queuebuf_init(void); - -#if QUEUEBUF_DEBUG -struct queuebuf *queuebuf_new_from_packetbuf_debug(struct net_buf *buf, const char *file, int line); -#define queuebuf_new_from_packetbuf(buf) queuebuf_new_from_packetbuf_debug(buf,__FILE__, __LINE__) -#else /* QUEUEBUF_DEBUG */ -struct queuebuf *queuebuf_new_from_packetbuf(struct net_buf *buf); -#endif /* QUEUEBUF_DEBUG */ -void queuebuf_update_attr_from_packetbuf(struct net_buf *buf, struct queuebuf *b); -void queuebuf_update_from_packetbuf(struct net_buf *buf, struct queuebuf *b); - -void queuebuf_to_packetbuf(struct net_buf *buf, struct queuebuf *b); -void queuebuf_free(struct queuebuf *b); - -void *queuebuf_dataptr(struct queuebuf *b); -int queuebuf_datalen(struct queuebuf *b); - -linkaddr_t *queuebuf_addr(struct queuebuf *b, uint8_t type); -packetbuf_attr_t queuebuf_attr(struct queuebuf *b, uint8_t type); - -void queuebuf_debug_print(void); - -int queuebuf_numfree(struct net_buf *buf); - -#endif /* __QUEUEBUF_H__ */ - -/** @} */ -/** @} */ diff --git a/net/ip/contiki/rpl/rpl-conf.h b/net/ip/contiki/rpl/rpl-conf.h deleted file mode 100644 index a2c0e6dd27bcb12e5ce8143e2d2922bf64d1be42..0000000000000000000000000000000000000000 --- a/net/ip/contiki/rpl/rpl-conf.h +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * \file - * Public configuration and API declarations for ContikiRPL. - * \author - * Joakim Eriksson & Nicolas Tsiftes - * - */ - -#ifndef RPL_CONF_H -#define RPL_CONF_H - -#include "contiki-conf.h" - -/* Set to 1 to enable RPL statistics */ -#ifndef RPL_CONF_STATS -#define RPL_CONF_STATS 0 -#endif /* RPL_CONF_STATS */ - -/* - * Select routing metric supported at runtime. This must be a valid - * DAG Metric Container Object Type (see below). Currently, we only - * support RPL_DAG_MC_ETX and RPL_DAG_MC_ENERGY. - * When MRHOF (RFC6719) is used with ETX, no metric container must - * be used; instead the rank carries ETX directly. - */ -#ifdef RPL_CONF_DAG_MC -#define RPL_DAG_MC RPL_CONF_DAG_MC -#else -#define RPL_DAG_MC RPL_DAG_MC_NONE -#endif /* RPL_CONF_DAG_MC */ - -/* - * The objective function used by RPL is configurable through the - * RPL_CONF_OF parameter. This should be defined to be the name of an - * rpl_of object linked into the system image, e.g., rpl_of0. - */ -#ifdef RPL_CONF_OF -#define RPL_OF RPL_CONF_OF -#else -/* ETX is the default objective function. */ -#define RPL_OF rpl_mrhof -#endif /* RPL_CONF_OF */ - -/* This value decides which DAG instance we should participate in by default. */ -#ifdef RPL_CONF_DEFAULT_INSTANCE -#define RPL_DEFAULT_INSTANCE RPL_CONF_DEFAULT_INSTANCE -#else -#define RPL_DEFAULT_INSTANCE 0x1e -#endif /* RPL_CONF_DEFAULT_INSTANCE */ - -/* - * This value decides if this node must stay as a leaf or not - * as allowed by draft-ietf-roll-rpl-19#section-8.5 - */ -#ifdef RPL_CONF_LEAF_ONLY -#define RPL_LEAF_ONLY RPL_CONF_LEAF_ONLY -#else -#define RPL_LEAF_ONLY 0 -#endif - -/* - * Maximum of concurent RPL instances. - */ -#ifdef RPL_CONF_MAX_INSTANCES -#define RPL_MAX_INSTANCES RPL_CONF_MAX_INSTANCES -#else -#define RPL_MAX_INSTANCES 1 -#endif /* RPL_CONF_MAX_INSTANCES */ - -/* - * Maximum number of DAGs within an instance. - */ -#ifdef RPL_CONF_MAX_DAG_PER_INSTANCE -#define RPL_MAX_DAG_PER_INSTANCE RPL_CONF_MAX_DAG_PER_INSTANCE -#else -#define RPL_MAX_DAG_PER_INSTANCE 2 -#endif /* RPL_CONF_MAX_DAG_PER_INSTANCE */ - -/* - * - */ -#ifndef RPL_CONF_DAO_SPECIFY_DAG - #if RPL_MAX_DAG_PER_INSTANCE > 1 - #define RPL_DAO_SPECIFY_DAG 1 - #else - #define RPL_DAO_SPECIFY_DAG 0 - #endif /* RPL_MAX_DAG_PER_INSTANCE > 1 */ -#else - #define RPL_DAO_SPECIFY_DAG RPL_CONF_DAO_SPECIFY_DAG -#endif /* RPL_CONF_DAO_SPECIFY_DAG */ - -/* - * The DIO interval (n) represents 2^n ms. - * - * According to the specification, the default value is 3 which - * means 8 milliseconds. That is far too low when using duty cycling - * with wake-up intervals that are typically hundreds of milliseconds. - * ContikiRPL thus sets the default to 2^12 ms = 4.096 s. - */ -#ifdef RPL_CONF_DIO_INTERVAL_MIN -#define RPL_DIO_INTERVAL_MIN RPL_CONF_DIO_INTERVAL_MIN -#else -#define RPL_DIO_INTERVAL_MIN 12 -#endif - -/* - * Maximum amount of timer doublings. - * - * The maximum interval will by default be 2^(12+8) ms = 1048.576 s. - * RFC 6550 suggests a default value of 20, which of course would be - * unsuitable when we start with a minimum interval of 2^12. - */ -#ifdef RPL_CONF_DIO_INTERVAL_DOUBLINGS -#define RPL_DIO_INTERVAL_DOUBLINGS RPL_CONF_DIO_INTERVAL_DOUBLINGS -#else -#define RPL_DIO_INTERVAL_DOUBLINGS 8 -#endif - -/* - * DIO redundancy. To learn more about this, see RFC 6206. - * - * RFC 6550 suggests a default value of 10. It is unclear what the basis - * of this suggestion is. Network operators might attain more efficient - * operation by tuning this parameter for specific deployments. - */ -#ifdef RPL_CONF_DIO_REDUNDANCY -#define RPL_DIO_REDUNDANCY RPL_CONF_DIO_REDUNDANCY -#else -#define RPL_DIO_REDUNDANCY 10 -#endif - -/* - * Initial metric attributed to a link when the ETX is unknown - */ -#ifndef RPL_CONF_INIT_LINK_METRIC -#define RPL_INIT_LINK_METRIC 2 -#else -#define RPL_INIT_LINK_METRIC RPL_CONF_INIT_LINK_METRIC -#endif - -/* - * Default route lifetime unit. This is the granularity of time - * used in RPL lifetime values, in seconds. - */ -#ifndef RPL_CONF_DEFAULT_LIFETIME_UNIT -#define RPL_DEFAULT_LIFETIME_UNIT 0xffff -#else -#define RPL_DEFAULT_LIFETIME_UNIT RPL_CONF_DEFAULT_LIFETIME_UNIT -#endif - -/* - * Default route lifetime as a multiple of the lifetime unit. - */ -#ifndef RPL_CONF_DEFAULT_LIFETIME -#define RPL_DEFAULT_LIFETIME 0xff -#else -#define RPL_DEFAULT_LIFETIME RPL_CONF_DEFAULT_LIFETIME -#endif - -/* - * DAG preference field - */ -#ifdef RPL_CONF_PREFERENCE -#define RPL_PREFERENCE RPL_CONF_PREFERENCE -#else -#define RPL_PREFERENCE 0 -#endif - -/* - * Hop-by-hop option - * This option control the insertion of the RPL Hop-by-Hop extension header - * into packets originating from this node. Incoming Hop-by-hop extension - * header are still processed and forwarded. - */ -#ifdef RPL_CONF_INSERT_HBH_OPTION -#define RPL_INSERT_HBH_OPTION RPL_CONF_INSERT_HBH_OPTION -#else -#define RPL_INSERT_HBH_OPTION 1 -#endif - -/* - * RPL probing. When enabled, probes will be sent periodically to keep - * parent link estimates up to date. - * */ -#ifdef RPL_CONF_WITH_PROBING -#define RPL_WITH_PROBING RPL_CONF_WITH_PROBING -#else -#define RPL_WITH_PROBING 1 -#endif - -/* - * RPL probing interval. - * */ -#ifdef RPL_CONF_PROBING_INTERVAL -#define RPL_PROBING_INTERVAL RPL_CONF_PROBING_INTERVAL -#else -#define RPL_PROBING_INTERVAL (120 * CLOCK_SECOND) -#endif - -/* - * RPL probing expiration time. - * */ -#ifdef RPL_CONF_PROBING_EXPIRATION_TIME -#define RPL_PROBING_EXPIRATION_TIME RPL_CONF_PROBING_EXPIRATION_TIME -#else -#define RPL_PROBING_EXPIRATION_TIME (10 * 60 * CLOCK_SECOND) -#endif - -/* - * Function used to select the next parent to be probed. - * */ -#ifdef RPL_CONF_PROBING_SELECT_FUNC -#define RPL_PROBING_SELECT_FUNC RPL_CONF_PROBING_SELECT_FUNC -#else -#define RPL_PROBING_SELECT_FUNC(dag) get_probing_target((dag)) -#endif - -/* - * Function used to send RPL probes. - * To probe with DIO, use: - * #define RPL_CONF_PROBING_SEND_FUNC(instance, addr) dio_output((instance), (addr)) - * To probe with DIS, use: - * #define RPL_CONF_PROBING_SEND_FUNC(instance, addr) dis_output((addr)) - * Any other custom probing function is also acceptable. - * */ -#ifdef RPL_CONF_PROBING_SEND_FUNC -#define RPL_PROBING_SEND_FUNC RPL_CONF_PROBING_SEND_FUNC -#else -#define RPL_PROBING_SEND_FUNC(instance, addr) dio_output((instance), (addr)) -#endif - -/* - * Function used to calculate next RPL probing interval - * */ -#ifdef RPL_CONF_PROBING_DELAY_FUNC -#define RPL_PROBING_DELAY_FUNC RPL_CONF_PROBING_DELAY_FUNC -#else -#define RPL_PROBING_DELAY_FUNC() ((RPL_PROBING_INTERVAL / 2) \ - + random_rand() % (RPL_PROBING_INTERVAL)) -#endif - -#endif /* RPL_CONF_H */ diff --git a/net/ip/contiki/rpl/rpl-dag.c b/net/ip/contiki/rpl/rpl-dag.c deleted file mode 100644 index 2cbd6273c30272bd381eed70a67346fb0adb5382..0000000000000000000000000000000000000000 --- a/net/ip/contiki/rpl/rpl-dag.c +++ /dev/null @@ -1,1440 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Logic for Directed Acyclic Graphs in RPL. - * - * \author Joakim Eriksson , Nicolas Tsiftes - * Contributors: George Oikonomou (multicast) - */ - -/** - * \addtogroup uip6 - * @{ - */ - -#include "contiki.h" -#include "contiki/rpl/rpl-private.h" -#include "contiki/ip/uip.h" -#include "contiki/ipv6/uip-nd6.h" -#include "contiki/ipv6/uip-ds6-nbr.h" -#include "contiki/nbr-table.h" -#include "contiki/ipv6/multicast/uip-mcast6.h" -#include "lib/list.h" -#include "lib/memb.h" -#include "sys/ctimer.h" - -#include -#include - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_RPL -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -/*---------------------------------------------------------------------------*/ -extern rpl_of_t RPL_OF; -static rpl_of_t * const objective_functions[] = {&RPL_OF}; - -/*---------------------------------------------------------------------------*/ -/* RPL definitions. */ - -#ifndef RPL_CONF_GROUNDED -#define RPL_GROUNDED 0 -#else -#define RPL_GROUNDED RPL_CONF_GROUNDED -#endif /* !RPL_CONF_GROUNDED */ - -/*---------------------------------------------------------------------------*/ -/* Per-parent RPL information */ -NBR_TABLE_GLOBAL(rpl_parent_t, rpl_parents); -/*---------------------------------------------------------------------------*/ -/* Allocate instance table. */ -rpl_instance_t instance_table[RPL_MAX_INSTANCES]; -rpl_instance_t *default_instance; - -/*---------------------------------------------------------------------------*/ -void -rpl_print_neighbor_list() -{ - if(default_instance != NULL && default_instance->current_dag != NULL && - default_instance->of != NULL && default_instance->of->calculate_rank != NULL) { - int curr_dio_interval = default_instance->dio_intcurrent; - int curr_rank = default_instance->current_dag->rank; - rpl_parent_t *p = nbr_table_head(rpl_parents); - clock_time_t now = clock_time(); - - printf("RPL: rank %u dioint %u, %u nbr(s)\n", curr_rank, curr_dio_interval, uip_ds6_nbr_num()); - while(p != NULL) { - uip_ds6_nbr_t *nbr = rpl_get_nbr(p); - printf("RPL: nbr %3u %5u, %5u => %5u %c (last tx %u min ago)\n", - nbr_table_get_lladdr(rpl_parents, p)->u8[7], - p->rank, nbr ? nbr->link_metric : 0, - default_instance->of->calculate_rank(p, 0), - p == default_instance->current_dag->preferred_parent ? '*' : ' ', - (unsigned)((now - p->last_tx_time) / (60 * CLOCK_SECOND))); - p = nbr_table_next(rpl_parents, p); - } - printf("RPL: end of list\n"); - } -} -/*---------------------------------------------------------------------------*/ -uip_ds6_nbr_t * -rpl_get_nbr(rpl_parent_t *parent) -{ - linkaddr_t *lladdr = NULL; - lladdr = nbr_table_get_lladdr(rpl_parents, parent); - if(lladdr != NULL) { - return nbr_table_get_from_lladdr(ds6_neighbors, lladdr); - } else { - return NULL; - } -} -/*---------------------------------------------------------------------------*/ -static join_callback_t rpl_join_callback = NULL; - -void -rpl_set_join_callback(join_callback_t callback) -{ - rpl_join_callback = callback; -} -/*---------------------------------------------------------------------------*/ -static void -nbr_callback(void *ptr) -{ - rpl_remove_parent(ptr); -} - -void -rpl_dag_init(void) -{ - nbr_table_register(rpl_parents, (nbr_table_callback *)nbr_callback); -} -/*---------------------------------------------------------------------------*/ -rpl_parent_t * -rpl_get_parent(uip_lladdr_t *addr) -{ - rpl_parent_t *p = nbr_table_get_from_lladdr(rpl_parents, (linkaddr_t *)addr); - return p; -} -/*---------------------------------------------------------------------------*/ -rpl_rank_t -rpl_get_parent_rank(uip_lladdr_t *addr) -{ - rpl_parent_t *p = nbr_table_get_from_lladdr(rpl_parents, (linkaddr_t *)addr); - if(p != NULL) { - return p->rank; - } else { - return 0; - } -} -/*---------------------------------------------------------------------------*/ -uint16_t -rpl_get_parent_link_metric(const uip_lladdr_t *addr) -{ - uip_ds6_nbr_t *nbr; - nbr = nbr_table_get_from_lladdr(ds6_neighbors, (const linkaddr_t *)addr); - - if(nbr != NULL) { - return nbr->link_metric; - } else { - return 0; - } -} -/*---------------------------------------------------------------------------*/ -uip_ipaddr_t * -rpl_get_parent_ipaddr(rpl_parent_t *p) -{ - linkaddr_t *lladdr = nbr_table_get_lladdr(rpl_parents, p); - return uip_ds6_nbr_ipaddr_from_lladdr((uip_lladdr_t *)lladdr); -} -/*---------------------------------------------------------------------------*/ -static void -rpl_set_preferred_parent(rpl_dag_t *dag, rpl_parent_t *p) -{ - if(dag != NULL && dag->preferred_parent != p) { - PRINTF("RPL: rpl_set_preferred_parent "); - if(p != NULL) { - PRINT6ADDR(rpl_get_parent_ipaddr(p)); - } else { - PRINTF("NULL"); - } - PRINTF(" used to be "); - if(dag->preferred_parent != NULL) { - PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent)); - } else { - PRINTF("NULL"); - } - PRINTF("\n"); - - /* Always keep the preferred parent locked, so it remains in the - * neighbor table. */ - nbr_table_unlock(rpl_parents, dag->preferred_parent); - nbr_table_lock(rpl_parents, p); - dag->preferred_parent = p; - } -} -/*---------------------------------------------------------------------------*/ -/* Greater-than function for the lollipop counter. */ -/*---------------------------------------------------------------------------*/ -static int -lollipop_greater_than(int a, int b) -{ - /* Check if we are comparing an initial value with an old value */ - if(a > RPL_LOLLIPOP_CIRCULAR_REGION && b <= RPL_LOLLIPOP_CIRCULAR_REGION) { - return (RPL_LOLLIPOP_MAX_VALUE + 1 + b - a) > RPL_LOLLIPOP_SEQUENCE_WINDOWS; - } - /* Otherwise check if a > b and comparable => ok, or - if they have wrapped and are still comparable */ - return (a > b && (a - b) < RPL_LOLLIPOP_SEQUENCE_WINDOWS) || - (a < b && (b - a) > (RPL_LOLLIPOP_CIRCULAR_REGION + 1- - RPL_LOLLIPOP_SEQUENCE_WINDOWS)); -} -/*---------------------------------------------------------------------------*/ -/* Remove DAG parents with a rank that is at least the same as minimum_rank. */ -static void -remove_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank) -{ - rpl_parent_t *p; - - PRINTF("RPL: Removing parents (minimum rank %u)\n", - minimum_rank); - - p = nbr_table_head(rpl_parents); - while(p != NULL) { - if(dag == p->dag && p->rank >= minimum_rank) { - rpl_remove_parent(p); - } - p = nbr_table_next(rpl_parents, p); - } -} -/*---------------------------------------------------------------------------*/ -static void -nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank) -{ - rpl_parent_t *p; - - PRINTF("RPL: Nullifying parents (minimum rank %u)\n", - minimum_rank); - - p = nbr_table_head(rpl_parents); - while(p != NULL) { - if(dag == p->dag && p->rank >= minimum_rank) { - rpl_nullify_parent(p); - } - p = nbr_table_next(rpl_parents, p); - } -} -/*---------------------------------------------------------------------------*/ -static int -should_send_dao(rpl_instance_t *instance, rpl_dio_t *dio, rpl_parent_t *p) -{ - /* if MOP is set to no downward routes no DAO should be sent */ - if(instance->mop == RPL_MOP_NO_DOWNWARD_ROUTES) { - return 0; - } - /* check if the new DTSN is more recent */ - return p == instance->current_dag->preferred_parent && - (lollipop_greater_than(dio->dtsn, p->dtsn)); -} -/*---------------------------------------------------------------------------*/ -static int -acceptable_rank(rpl_dag_t *dag, rpl_rank_t rank) -{ - return rank != INFINITE_RANK && - ((dag->instance->max_rankinc == 0) || - DAG_RANK(rank, dag->instance) <= DAG_RANK(dag->min_rank + dag->instance->max_rankinc, dag->instance)); -} -/*---------------------------------------------------------------------------*/ -static rpl_dag_t * -get_dag(uint8_t instance_id, uip_ipaddr_t *dag_id) -{ - rpl_instance_t *instance; - rpl_dag_t *dag; - int i; - - instance = rpl_get_instance(instance_id); - if(instance == NULL) { - return NULL; - } - - for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; ++i) { - dag = &instance->dag_table[i]; - if(dag->used && uip_ipaddr_cmp(&dag->dag_id, dag_id)) { - return dag; - } - } - - return NULL; -} -/*---------------------------------------------------------------------------*/ -rpl_dag_t * -rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id) -{ - return rpl_set_root_with_version(instance_id, dag_id, RPL_LOLLIPOP_INIT); -} -/*---------------------------------------------------------------------------*/ -rpl_dag_t * -rpl_set_root_with_version(uint8_t instance_id, uip_ipaddr_t *dag_id, - uint8_t version) -{ - rpl_dag_t *dag; - rpl_instance_t *instance; - int i; - - instance = rpl_get_instance(instance_id); - if(instance != NULL) { - for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; ++i) { - dag = &instance->dag_table[i]; - if(dag->used) { - if(uip_ipaddr_cmp(&dag->dag_id, dag_id)) { - version = dag->version; - RPL_LOLLIPOP_INCREMENT(version); - } - if(dag == dag->instance->current_dag) { - PRINTF("RPL: Dropping a joined DAG when setting this node as root"); - dag->instance->current_dag = NULL; - } else { - PRINTF("RPL: Dropping a DAG when setting this node as root"); - } - rpl_free_dag(dag); - } - } - } - - dag = rpl_alloc_dag(instance_id, dag_id); - if(dag == NULL) { - PRINTF("RPL: Failed to allocate a DAG\n"); - return NULL; - } - - instance = dag->instance; - - dag->version = version; - dag->joined = 1; - dag->grounded = RPL_GROUNDED; - dag->preference = RPL_PREFERENCE; - instance->mop = RPL_MOP_DEFAULT; - instance->of = &RPL_OF; - rpl_set_preferred_parent(dag, NULL); - - memcpy(&dag->dag_id, dag_id, sizeof(dag->dag_id)); - - instance->dio_intdoubl = RPL_DIO_INTERVAL_DOUBLINGS; - instance->dio_intmin = RPL_DIO_INTERVAL_MIN; - /* The current interval must differ from the minimum interval in order to - trigger a DIO timer reset. */ - instance->dio_intcurrent = RPL_DIO_INTERVAL_MIN + - RPL_DIO_INTERVAL_DOUBLINGS; - instance->dio_redundancy = RPL_DIO_REDUNDANCY; - instance->max_rankinc = RPL_MAX_RANKINC; - instance->min_hoprankinc = RPL_MIN_HOPRANKINC; - instance->default_lifetime = RPL_DEFAULT_LIFETIME; - instance->lifetime_unit = RPL_DEFAULT_LIFETIME_UNIT; - - dag->rank = ROOT_RANK(instance); - - if(instance->current_dag != dag && instance->current_dag != NULL) { - /* Remove routes installed by DAOs. */ - rpl_remove_routes(instance->current_dag); - - instance->current_dag->joined = 0; - } - - instance->current_dag = dag; - instance->dtsn_out = RPL_LOLLIPOP_INIT; - instance->of->update_metric_container(instance); - default_instance = instance; - - PRINTF("RPL: Node set to be a DAG root with DAG ID "); - PRINT6ADDR(&dag->dag_id); - PRINTF("\n"); - - ANNOTATE("#A root=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]); - - rpl_reset_dio_timer(instance); - - return dag; -} -/*---------------------------------------------------------------------------*/ -int -rpl_repair_root(uint8_t instance_id) -{ - rpl_instance_t *instance; - - instance = rpl_get_instance(instance_id); - if(instance == NULL || - instance->current_dag->rank != ROOT_RANK(instance)) { - PRINTF("RPL: rpl_repair_root triggered but not root\n"); - return 0; - } - RPL_STAT(rpl_stats.root_repairs++); - - RPL_LOLLIPOP_INCREMENT(instance->current_dag->version); - RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); - PRINTF("RPL: rpl_repair_root initiating global repair with version %d\n", instance->current_dag->version); - rpl_reset_dio_timer(instance); - return 1; -} -/*---------------------------------------------------------------------------*/ -static void -set_ip_from_prefix(uip_ipaddr_t *ipaddr, rpl_prefix_t *prefix) -{ - memset(ipaddr, 0, sizeof(uip_ipaddr_t)); - memcpy(ipaddr, &prefix->prefix, (prefix->length + 7) / 8); - uip_ds6_set_addr_iid(ipaddr, &uip_lladdr); -} -/*---------------------------------------------------------------------------*/ -static void -check_prefix(rpl_prefix_t *last_prefix, rpl_prefix_t *new_prefix) -{ - uip_ipaddr_t ipaddr; - uip_ds6_addr_t *rep; - - if(last_prefix != NULL && new_prefix != NULL && - last_prefix->length == new_prefix->length && - uip_ipaddr_prefixcmp(&last_prefix->prefix, &new_prefix->prefix, new_prefix->length) && - last_prefix->flags == new_prefix->flags) { - /* Nothing has changed. */ - PRINTF("RPL: same prefix "); - PRINT6ADDR(&new_prefix->prefix); - PRINTF(" len %d flags 0x%x\n", new_prefix->length, new_prefix->flags); - return; - } - - if(last_prefix != NULL) { - set_ip_from_prefix(&ipaddr, last_prefix); - rep = uip_ds6_addr_lookup(&ipaddr); - if(rep != NULL) { - PRINTF("RPL: removing global IP address "); - PRINT6ADDR(&ipaddr); - PRINTF("\n"); - uip_ds6_addr_rm(rep); - } - } - - if(new_prefix != NULL) { - set_ip_from_prefix(&ipaddr, new_prefix); - if(uip_ds6_addr_lookup(&ipaddr) == NULL) { - PRINTF("RPL: adding global IP address "); - PRINT6ADDR(&ipaddr); - PRINTF("\n"); - uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); - } - } -} -/*---------------------------------------------------------------------------*/ -int -rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len) -{ - rpl_prefix_t last_prefix; - uint8_t last_len = dag->prefix_info.length; - - if(len > 128) { - return 0; - } - if(dag->prefix_info.length != 0) { - memcpy(&last_prefix, &dag->prefix_info, sizeof(rpl_prefix_t)); - } - memset(&dag->prefix_info.prefix, 0, sizeof(dag->prefix_info.prefix)); - memcpy(&dag->prefix_info.prefix, prefix, (len + 7) / 8); - dag->prefix_info.length = len; - dag->prefix_info.flags = UIP_ND6_RA_FLAG_AUTONOMOUS; - PRINTF("RPL: Prefix set - will announce this in DIOs\n"); - /* Autoconfigure an address if this node does not already have an address - with this prefix. Otherwise, update the prefix */ - if(last_len == 0) { - PRINTF("rpl_set_prefix - prefix NULL\n"); - check_prefix(NULL, &dag->prefix_info); - } else { - PRINTF("rpl_set_prefix - prefix NON-NULL\n"); - check_prefix(&last_prefix, &dag->prefix_info); - } - return 1; -} -/*---------------------------------------------------------------------------*/ -int -rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from) -{ - if(instance->def_route != NULL) { - PRINTF("RPL: Removing default route through "); - PRINT6ADDR(&instance->def_route->ipaddr); - PRINTF("\n"); - uip_ds6_defrt_rm(instance->def_route); - instance->def_route = NULL; - } - - if(from != NULL) { - PRINTF("RPL: Adding default route through "); - PRINT6ADDR(from); - PRINTF("\n"); - instance->def_route = uip_ds6_defrt_add(from, - RPL_LIFETIME(instance, - instance->default_lifetime)); - if(instance->def_route == NULL) { - return 0; - } - } else { - PRINTF("RPL: Removing default route\n"); - if(instance->def_route != NULL) { - uip_ds6_defrt_rm(instance->def_route); - } else { - PRINTF("RPL: Not actually removing default route, since instance had no default route\n"); - } - } - return 1; -} -/*---------------------------------------------------------------------------*/ -rpl_instance_t * -rpl_alloc_instance(uint8_t instance_id) -{ - rpl_instance_t *instance, *end; - - for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; - instance < end; ++instance) { - if(instance->used == 0) { - memset(instance, 0, sizeof(*instance)); - instance->instance_id = instance_id; - instance->def_route = NULL; - instance->used = 1; -#if RPL_WITH_PROBING - rpl_schedule_probing(instance); -#endif /* RPL_WITH_PROBING */ - return instance; - } - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -rpl_dag_t * -rpl_alloc_dag(uint8_t instance_id, uip_ipaddr_t *dag_id) -{ - rpl_dag_t *dag, *end; - rpl_instance_t *instance; - - instance = rpl_get_instance(instance_id); - if(instance == NULL) { - instance = rpl_alloc_instance(instance_id); - if(instance == NULL) { - RPL_STAT(rpl_stats.mem_overflows++); - return NULL; - } - } - - for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) { - if(!dag->used) { - memset(dag, 0, sizeof(*dag)); - dag->used = 1; - dag->rank = INFINITE_RANK; - dag->min_rank = INFINITE_RANK; - dag->instance = instance; - return dag; - } - } - - RPL_STAT(rpl_stats.mem_overflows++); - return NULL; -} -/*---------------------------------------------------------------------------*/ -void -rpl_set_default_instance(rpl_instance_t *instance) -{ - default_instance = instance; -} -/*---------------------------------------------------------------------------*/ -rpl_instance_t * -rpl_get_default_instance(void) -{ - return default_instance; -} -/*---------------------------------------------------------------------------*/ -void -rpl_free_instance(rpl_instance_t *instance) -{ - rpl_dag_t *dag; - rpl_dag_t *end; - - PRINTF("RPL: Leaving the instance %u\n", instance->instance_id); - - /* Remove any DAG inside this instance */ - for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) { - if(dag->used) { - rpl_free_dag(dag); - } - } - - rpl_set_default_route(instance, NULL); - -#if RPL_WITH_PROBING - ctimer_stop(&instance->probing_timer); -#endif /* RPL_WITH_PROBING */ - ctimer_stop(&instance->dio_timer); - ctimer_stop(&instance->dao_timer); - ctimer_stop(&instance->dao_lifetime_timer); - - if(default_instance == instance) { - default_instance = NULL; - } - - instance->used = 0; -} -/*---------------------------------------------------------------------------*/ -void -rpl_free_dag(rpl_dag_t *dag) -{ - if(dag->joined) { - PRINTF("RPL: Leaving the DAG "); - PRINT6ADDR(&dag->dag_id); - PRINTF("\n"); - dag->joined = 0; - - /* Remove routes installed by DAOs. */ - rpl_remove_routes(dag); - - /* Remove autoconfigured address */ - if((dag->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS)) { - check_prefix(&dag->prefix_info, NULL); - } - - remove_parents(dag, 0); - } - dag->used = 0; -} -/*---------------------------------------------------------------------------*/ -rpl_parent_t * -rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr) -{ - rpl_parent_t *p = NULL; - /* Is the parent known by ds6? Drop this request if not. - * Typically, the parent is added upon receiving a DIO. */ - const uip_lladdr_t *lladdr = uip_ds6_nbr_lladdr_from_ipaddr(addr); - - PRINTF("RPL: rpl_add_parent lladdr %p ", lladdr); - PRINT6ADDR(addr); - PRINTF("\n"); - if(lladdr != NULL) { - /* Add parent in rpl_parents */ - p = nbr_table_add_lladdr(rpl_parents, (linkaddr_t *)lladdr); - if(p == NULL) { - PRINTF("RPL: rpl_add_parent p NULL\n"); - } else { - uip_ds6_nbr_t *nbr; - nbr = rpl_get_nbr(p); - - p->dag = dag; - p->rank = dio->rank; - p->dtsn = dio->dtsn; - - /* Check whether we have a neighbor that has not gotten a link metric yet */ - if(nbr != NULL && nbr->link_metric == 0) { - nbr->link_metric = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR; - } -#if RPL_DAG_MC != RPL_DAG_MC_NONE - memcpy(&p->mc, &dio->mc, sizeof(p->mc)); -#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ - } - } - - return p; -} -/*---------------------------------------------------------------------------*/ -static rpl_parent_t * -find_parent_any_dag_any_instance(uip_ipaddr_t *addr) -{ - uip_ds6_nbr_t *ds6_nbr = uip_ds6_nbr_lookup(addr); - const uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(ds6_nbr); - return nbr_table_get_from_lladdr(rpl_parents, (linkaddr_t *)lladdr); -} -/*---------------------------------------------------------------------------*/ -rpl_parent_t * -rpl_find_parent(rpl_dag_t *dag, uip_ipaddr_t *addr) -{ - rpl_parent_t *p = find_parent_any_dag_any_instance(addr); - if(p != NULL && p->dag == dag) { - return p; - } else { - return NULL; - } -} -/*---------------------------------------------------------------------------*/ -static rpl_dag_t * -find_parent_dag(rpl_instance_t *instance, uip_ipaddr_t *addr) -{ - rpl_parent_t *p = find_parent_any_dag_any_instance(addr); - if(p != NULL) { - return p->dag; - } else { - return NULL; - } -} -/*---------------------------------------------------------------------------*/ -rpl_parent_t * -rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr) -{ - rpl_parent_t *p = find_parent_any_dag_any_instance(addr); - if(p && p->dag && p->dag->instance == instance) { - return p; - } else { - return NULL; - } -} -/*---------------------------------------------------------------------------*/ -rpl_dag_t * -rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p) -{ - rpl_parent_t *last_parent; - rpl_dag_t *dag, *end, *best_dag; - rpl_rank_t old_rank; - - old_rank = instance->current_dag->rank; - last_parent = instance->current_dag->preferred_parent; - - best_dag = instance->current_dag; - if(best_dag->rank != ROOT_RANK(instance)) { - if(rpl_select_parent(p->dag) != NULL) { - if(p->dag != best_dag) { - best_dag = instance->of->best_dag(best_dag, p->dag); - } - } else if(p->dag == best_dag) { - best_dag = NULL; - for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) { - if(dag->used && dag->preferred_parent != NULL && dag->preferred_parent->rank != INFINITE_RANK) { - if(best_dag == NULL) { - best_dag = dag; - } else { - best_dag = instance->of->best_dag(best_dag, dag); - } - } - } - } - } - - if(best_dag == NULL) { - /* No parent found: the calling function handle this problem. */ - return NULL; - } - - if(instance->current_dag != best_dag) { - /* Remove routes installed by DAOs. */ - rpl_remove_routes(instance->current_dag); - - PRINTF("RPL: New preferred DAG: "); - PRINT6ADDR(&best_dag->dag_id); - PRINTF("\n"); - - if(best_dag->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) { - check_prefix(&instance->current_dag->prefix_info, &best_dag->prefix_info); - } else if(instance->current_dag->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) { - check_prefix(&instance->current_dag->prefix_info, NULL); - } - - best_dag->joined = 1; - instance->current_dag->joined = 0; - instance->current_dag = best_dag; - } - - instance->of->update_metric_container(instance); - /* Update the DAG rank. */ - best_dag->rank = instance->of->calculate_rank(best_dag->preferred_parent, 0); - if(last_parent == NULL || best_dag->rank < best_dag->min_rank) { - best_dag->min_rank = best_dag->rank; - } else if(!acceptable_rank(best_dag, best_dag->rank)) { - PRINTF("RPL: New rank unacceptable!\n"); - rpl_set_preferred_parent(instance->current_dag, NULL); - if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES && last_parent != NULL) { - /* Send a No-Path DAO to the removed preferred parent. */ - dao_output(last_parent, RPL_ZERO_LIFETIME); - } - return NULL; - } - - if(best_dag->preferred_parent != last_parent) { - rpl_set_default_route(instance, rpl_get_parent_ipaddr(best_dag->preferred_parent)); - PRINTF("RPL: Changed preferred parent, rank changed from %u to %u\n", - (unsigned)old_rank, best_dag->rank); - RPL_STAT(rpl_stats.parent_switch++); - if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) { - if(last_parent != NULL) { - /* Send a No-Path DAO to the removed preferred parent. */ - dao_output(last_parent, RPL_ZERO_LIFETIME); - } - /* The DAO parent set changed - schedule a DAO transmission. */ - RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); - rpl_schedule_dao(instance); - } - rpl_reset_dio_timer(instance); -#if DEBUG - rpl_print_neighbor_list(); -#endif - } else if(best_dag->rank != old_rank) { - PRINTF("RPL: Preferred parent update, rank changed from %u to %u\n", - (unsigned)old_rank, best_dag->rank); - } - return best_dag; -} -/*---------------------------------------------------------------------------*/ -static rpl_parent_t * -best_parent(rpl_dag_t *dag) -{ - rpl_parent_t *p, *best; - - best = NULL; - - p = nbr_table_head(rpl_parents); - while(p != NULL) { - if(p->dag != dag || p->rank == INFINITE_RANK) { - /* ignore this neighbor */ - } else if(best == NULL) { - best = p; - } else { - best = dag->instance->of->best_parent(best, p); - } - p = nbr_table_next(rpl_parents, p); - } - - return best; -} -/*---------------------------------------------------------------------------*/ -rpl_parent_t * -rpl_select_parent(rpl_dag_t *dag) -{ - rpl_parent_t *best = best_parent(dag); - - if(best != NULL) { - rpl_set_preferred_parent(dag, best); - } - - return best; -} -/*---------------------------------------------------------------------------*/ -void -rpl_remove_parent(rpl_parent_t *parent) -{ - PRINTF("RPL: Removing parent "); - PRINT6ADDR(rpl_get_parent_ipaddr(parent)); - PRINTF("\n"); - - rpl_nullify_parent(parent); - - nbr_table_remove(rpl_parents, parent); -} -/*---------------------------------------------------------------------------*/ -void -rpl_nullify_parent(rpl_parent_t *parent) -{ - rpl_dag_t *dag = parent->dag; - /* This function can be called when the preferred parent is NULL, so we - need to handle this condition in order to trigger uip_ds6_defrt_rm. */ - if(parent == dag->preferred_parent || dag->preferred_parent == NULL) { - dag->rank = INFINITE_RANK; - if(dag->joined) { - if(dag->instance->def_route != NULL) { - PRINTF("RPL: Removing default route "); - PRINT6ADDR(rpl_get_parent_ipaddr(parent)); - PRINTF("\n"); - uip_ds6_defrt_rm(dag->instance->def_route); - dag->instance->def_route = NULL; - } - /* Send no-path DAO only to preferred parent, if any */ - if(parent == dag->preferred_parent) { - dao_output(parent, RPL_ZERO_LIFETIME); - rpl_set_preferred_parent(dag, NULL); - } - } - } - - PRINTF("RPL: Nullifying parent "); - PRINT6ADDR(rpl_get_parent_ipaddr(parent)); - PRINTF("\n"); -} -/*---------------------------------------------------------------------------*/ -void -rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent) -{ - if(parent == dag_src->preferred_parent) { - rpl_set_preferred_parent(dag_src, NULL); - dag_src->rank = INFINITE_RANK; - if(dag_src->joined && dag_src->instance->def_route != NULL) { - PRINTF("RPL: Removing default route "); - PRINT6ADDR(rpl_get_parent_ipaddr(parent)); - PRINTF("\n"); - PRINTF("rpl_move_parent\n"); - uip_ds6_defrt_rm(dag_src->instance->def_route); - dag_src->instance->def_route = NULL; - } - } else if(dag_src->joined) { - /* Remove uIPv6 routes that have this parent as the next hop. */ - rpl_remove_routes_by_nexthop(rpl_get_parent_ipaddr(parent), dag_src); - } - - PRINTF("RPL: Moving parent "); - PRINT6ADDR(rpl_get_parent_ipaddr(parent)); - PRINTF("\n"); - - parent->dag = dag_dst; -} -/*---------------------------------------------------------------------------*/ -rpl_dag_t * -rpl_get_any_dag(void) -{ - int i; - - for(i = 0; i < RPL_MAX_INSTANCES; ++i) { - if(instance_table[i].used && instance_table[i].current_dag->joined) { - return instance_table[i].current_dag; - } - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -rpl_instance_t * -rpl_get_instance(uint8_t instance_id) -{ - int i; - - for(i = 0; i < RPL_MAX_INSTANCES; ++i) { - if(instance_table[i].used && instance_table[i].instance_id == instance_id) { - return &instance_table[i]; - } - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -rpl_of_t * -rpl_find_of(rpl_ocp_t ocp) -{ - unsigned int i; - - for(i = 0; - i < sizeof(objective_functions) / sizeof(objective_functions[0]); - i++) { - if(objective_functions[i]->ocp == ocp) { - return objective_functions[i]; - } - } - - return NULL; -} -/*---------------------------------------------------------------------------*/ -void -rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio) -{ - rpl_instance_t *instance; - rpl_dag_t *dag; - rpl_parent_t *p; - rpl_of_t *of; - - dag = rpl_alloc_dag(dio->instance_id, &dio->dag_id); - if(dag == NULL) { - PRINTF("RPL: Failed to allocate a DAG object!\n"); - return; - } - - instance = dag->instance; - - p = rpl_add_parent(dag, dio, from); - PRINTF("RPL: Adding "); - PRINT6ADDR(from); - PRINTF(" as a parent: "); - if(p == NULL) { - PRINTF("failed\n"); - instance->used = 0; - return; - } - p->dtsn = dio->dtsn; - PRINTF("succeeded\n"); - - /* Determine the objective function by using the - objective code point of the DIO. */ - of = rpl_find_of(dio->ocp); - if(of == NULL) { - PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF\n", - dio->instance_id); - rpl_remove_parent(p); - instance->used = 0; - return; - } - - /* Autoconfigure an address if this node does not already have an address - with this prefix. */ - if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) { - check_prefix(NULL, &dio->prefix_info); - } - - dag->joined = 1; - dag->preference = dio->preference; - dag->grounded = dio->grounded; - dag->version = dio->version; - - instance->of = of; - instance->mop = dio->mop; - instance->current_dag = dag; - instance->dtsn_out = RPL_LOLLIPOP_INIT; - - instance->max_rankinc = dio->dag_max_rankinc; - instance->min_hoprankinc = dio->dag_min_hoprankinc; - instance->dio_intdoubl = dio->dag_intdoubl; - instance->dio_intmin = dio->dag_intmin; - instance->dio_intcurrent = instance->dio_intmin + instance->dio_intdoubl; - instance->dio_redundancy = dio->dag_redund; - instance->default_lifetime = dio->default_lifetime; - instance->lifetime_unit = dio->lifetime_unit; - - memcpy(&dag->dag_id, &dio->dag_id, sizeof(dio->dag_id)); - - /* Copy prefix information from the DIO into the DAG object. */ - memcpy(&dag->prefix_info, &dio->prefix_info, sizeof(rpl_prefix_t)); - - rpl_set_preferred_parent(dag, p); - instance->of->update_metric_container(instance); - dag->rank = instance->of->calculate_rank(p, 0); - /* So far this is the lowest rank we are aware of. */ - dag->min_rank = dag->rank; - - if(default_instance == NULL) { - default_instance = instance; - } - - PRINTF("RPL: Joined DAG with instance ID %u, rank %hu, DAG ID ", - dio->instance_id, dag->rank); - PRINT6ADDR(&dag->dag_id); - PRINTF("\n"); - - ANNOTATE("#A join=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]); - - rpl_reset_dio_timer(instance); - rpl_set_default_route(instance, from); - - if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) { - rpl_schedule_dao(instance); - } else { - PRINTF("RPL: The DIO does not meet the prerequisites for sending a DAO\n"); - } -} - -#if RPL_MAX_DAG_PER_INSTANCE > 1 -/*---------------------------------------------------------------------------*/ -void -rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio) -{ - rpl_instance_t *instance; - rpl_dag_t *dag, *previous_dag; - rpl_parent_t *p; - rpl_of_t *of; - - dag = rpl_alloc_dag(dio->instance_id, &dio->dag_id); - if(dag == NULL) { - PRINTF("RPL: Failed to allocate a DAG object!\n"); - return; - } - - instance = dag->instance; - - previous_dag = find_parent_dag(instance, from); - if(previous_dag == NULL) { - PRINTF("RPL: Adding "); - PRINT6ADDR(from); - PRINTF(" as a parent: "); - p = rpl_add_parent(dag, dio, from); - if(p == NULL) { - PRINTF("failed\n"); - dag->used = 0; - return; - } - PRINTF("succeeded\n"); - } else { - p = rpl_find_parent(previous_dag, from); - if(p != NULL) { - rpl_move_parent(previous_dag, dag, p); - } - } - - /* Determine the objective function by using the - objective code point of the DIO. */ - of = rpl_find_of(dio->ocp); - if(of != instance->of || - instance->mop != dio->mop || - instance->max_rankinc != dio->dag_max_rankinc || - instance->min_hoprankinc != dio->dag_min_hoprankinc || - instance->dio_intdoubl != dio->dag_intdoubl || - instance->dio_intmin != dio->dag_intmin || - instance->dio_redundancy != dio->dag_redund || - instance->default_lifetime != dio->default_lifetime || - instance->lifetime_unit != dio->lifetime_unit) { - PRINTF("RPL: DIO for DAG instance %u incompatible with previous DIO\n", - dio->instance_id); - rpl_remove_parent(p); - dag->used = 0; - return; - } - - dag->used = 1; - dag->grounded = dio->grounded; - dag->preference = dio->preference; - dag->version = dio->version; - - memcpy(&dag->dag_id, &dio->dag_id, sizeof(dio->dag_id)); - - /* copy prefix information into the dag */ - memcpy(&dag->prefix_info, &dio->prefix_info, sizeof(rpl_prefix_t)); - - rpl_set_preferred_parent(dag, p); - dag->rank = instance->of->calculate_rank(p, 0); - dag->min_rank = dag->rank; /* So far this is the lowest rank we know of. */ - - PRINTF("RPL: Joined DAG with instance ID %u, rank %hu, DAG ID ", - dio->instance_id, dag->rank); - PRINT6ADDR(&dag->dag_id); - PRINTF("\n"); - - ANNOTATE("#A join=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]); - - rpl_process_parent_event(instance, p); - p->dtsn = dio->dtsn; -} -#endif /* RPL_MAX_DAG_PER_INSTANCE > 1 */ - -/*---------------------------------------------------------------------------*/ -static void -global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio) -{ - rpl_parent_t *p; - - remove_parents(dag, 0); - dag->version = dio->version; - - /* copy parts of the configuration so that it propagates in the network */ - dag->instance->dio_intdoubl = dio->dag_intdoubl; - dag->instance->dio_intmin = dio->dag_intmin; - dag->instance->dio_redundancy = dio->dag_redund; - dag->instance->default_lifetime = dio->default_lifetime; - dag->instance->lifetime_unit = dio->lifetime_unit; - - dag->instance->of->reset(dag); - dag->min_rank = INFINITE_RANK; - RPL_LOLLIPOP_INCREMENT(dag->instance->dtsn_out); - - p = rpl_add_parent(dag, dio, from); - if(p == NULL) { - PRINTF("RPL: Failed to add a parent during the global repair\n"); - dag->rank = INFINITE_RANK; - } else { - dag->rank = dag->instance->of->calculate_rank(p, 0); - dag->min_rank = dag->rank; - PRINTF("RPL: rpl_process_parent_event global repair\n"); - rpl_process_parent_event(dag->instance, p); - } - - PRINTF("RPL: Participating in a global repair (version=%u, rank=%hu)\n", - dag->version, dag->rank); - - RPL_STAT(rpl_stats.global_repairs++); -} -/*---------------------------------------------------------------------------*/ -void -rpl_local_repair(rpl_instance_t *instance) -{ - int i; - - if(instance == NULL) { - PRINTF("RPL: local repair requested for instance NULL\n"); - return; - } - PRINTF("RPL: Starting a local instance repair\n"); - for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; i++) { - if(instance->dag_table[i].used) { - instance->dag_table[i].rank = INFINITE_RANK; - nullify_parents(&instance->dag_table[i], 0); - } - } - - rpl_reset_dio_timer(instance); - - RPL_STAT(rpl_stats.local_repairs++); -} -/*---------------------------------------------------------------------------*/ -void -rpl_recalculate_ranks(void) -{ - rpl_parent_t *p; - - /* - * We recalculate ranks when we receive feedback from the system rather - * than RPL protocol messages. This periodical recalculation is called - * from a timer in order to keep the stack depth reasonably low. - */ - p = nbr_table_head(rpl_parents); - while(p != NULL) { - if(p->dag != NULL && p->dag->instance && (p->flags & RPL_PARENT_FLAG_UPDATED)) { - p->flags &= ~RPL_PARENT_FLAG_UPDATED; - PRINTF("RPL: rpl_process_parent_event recalculate_ranks\n"); - if(!rpl_process_parent_event(p->dag->instance, p)) { - PRINTF("RPL: A parent was dropped\n"); - } - } - p = nbr_table_next(rpl_parents, p); - } -} -/*---------------------------------------------------------------------------*/ -int -rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p) -{ - int return_value; - -#if DEBUG - rpl_rank_t old_rank; - old_rank = instance->current_dag->rank; -#endif /* DEBUG */ - - return_value = 1; - - if(!acceptable_rank(p->dag, p->rank)) { - /* The candidate parent is no longer valid: the rank increase resulting - from the choice of it as a parent would be too high. */ - PRINTF("RPL: Unacceptable rank %u\n", (unsigned)p->rank); - rpl_nullify_parent(p); - if(p != instance->current_dag->preferred_parent) { - return 0; - } else { - return_value = 0; - } - } - - if(rpl_select_dag(instance, p) == NULL) { - /* No suitable parent; trigger a local repair. */ - PRINTF("RPL: No parents found in any DAG\n"); - rpl_local_repair(instance); - return 0; - } - -#if DEBUG - if(DAG_RANK(old_rank, instance) != DAG_RANK(instance->current_dag->rank, instance)) { - PRINTF("RPL: Moving in the instance from rank %hu to %hu\n", - DAG_RANK(old_rank, instance), DAG_RANK(instance->current_dag->rank, instance)); - if(instance->current_dag->rank != INFINITE_RANK) { - PRINTF("RPL: The preferred parent is "); - PRINT6ADDR(rpl_get_parent_ipaddr(instance->current_dag->preferred_parent)); - PRINTF(" (rank %u)\n", - (unsigned)DAG_RANK(instance->current_dag->preferred_parent->rank, instance)); - } else { - PRINTF("RPL: We don't have any parent"); - } - } -#endif /* DEBUG */ - - return return_value; -} -/*---------------------------------------------------------------------------*/ -void -rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) -{ - rpl_instance_t *instance; - rpl_dag_t *dag, *previous_dag; - rpl_parent_t *p; - -#if RPL_CONF_MULTICAST - /* If the root is advertising MOP 2 but we support MOP 3 we can still join - * In that scenario, we suppress DAOs for multicast targets */ - if(dio->mop < RPL_MOP_STORING_NO_MULTICAST) { -#else - if(dio->mop != RPL_MOP_DEFAULT) { -#endif - PRINTF("RPL: Ignoring a DIO with an unsupported MOP: %d\n", dio->mop); - return; - } - - dag = get_dag(dio->instance_id, &dio->dag_id); - instance = rpl_get_instance(dio->instance_id); - - if(dag != NULL && instance != NULL) { - if(lollipop_greater_than(dio->version, dag->version)) { - if(dag->rank == ROOT_RANK(instance)) { - PRINTF("RPL: Root received inconsistent DIO version number\n"); - dag->version = dio->version; - RPL_LOLLIPOP_INCREMENT(dag->version); - rpl_reset_dio_timer(instance); - } else { - PRINTF("RPL: Global repair\n"); - if(dio->prefix_info.length != 0) { - if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) { - PRINTF("RPL : Prefix announced in DIO\n"); - rpl_set_prefix(dag, &dio->prefix_info.prefix, dio->prefix_info.length); - } - } - global_repair(from, dag, dio); - } - return; - } - - if(lollipop_greater_than(dag->version, dio->version)) { - /* The DIO sender is on an older version of the DAG. */ - PRINTF("RPL: old version received => inconsistency detected\n"); - if(dag->joined) { - rpl_reset_dio_timer(instance); - return; - } - } - } - - if(instance == NULL) { - /* Join the RPL DAG if there is no join callback or the join callback tells us to join. */ - if(rpl_join_callback == NULL || rpl_join_callback(dio)) { - PRINTF("RPL: New instance detected: joining...\n"); - rpl_join_instance(from, dio); - } else { - PRINTF("RPL: New instance detected: not joining, rejected by join callback\n"); - } - return; - } - - if(instance->current_dag->rank == ROOT_RANK(instance) && instance->current_dag != dag) { - PRINTF("RPL: Root ignored DIO for different DAG\n"); - return; - } - - if(dag == NULL) { -#if RPL_MAX_DAG_PER_INSTANCE > 1 - PRINTF("RPL: Adding new DAG to known instance.\n"); - rpl_add_dag(from, dio); - return; -#else /* RPL_MAX_DAG_PER_INSTANCE > 1 */ - PRINTF("RPL: Only one instance supported.\n"); - return; -#endif /* RPL_MAX_DAG_PER_INSTANCE > 1 */ - } - - - if(dio->rank < ROOT_RANK(instance)) { - PRINTF("RPL: Ignoring DIO with too low rank: %u\n", - (unsigned)dio->rank); - return; - } else if(dio->rank == INFINITE_RANK && dag->joined) { - rpl_reset_dio_timer(instance); - } - - /* Prefix Information Option treated to add new prefix */ - if(dio->prefix_info.length != 0) { - if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) { - PRINTF("RPL : Prefix announced in DIO\n"); - rpl_set_prefix(dag, &dio->prefix_info.prefix, dio->prefix_info.length); - } - } - - if(dag->rank == ROOT_RANK(instance)) { - if(dio->rank != INFINITE_RANK) { - instance->dio_counter++; - } - return; - } - - /* - * At this point, we know that this DIO pertains to a DAG that - * we are already part of. We consider the sender of the DIO to be - * a candidate parent, and let rpl_process_parent_event decide - * whether to keep it in the set. - */ - - p = rpl_find_parent(dag, from); - if(p == NULL) { - previous_dag = find_parent_dag(instance, from); - if(previous_dag == NULL) { - /* Add the DIO sender as a candidate parent. */ - p = rpl_add_parent(dag, dio, from); - if(p == NULL) { - PRINTF("RPL: Failed to add a new parent ("); - PRINT6ADDR(from); - PRINTF(")\n"); - return; - } - PRINTF("RPL: New candidate parent with rank %u: ", (unsigned)p->rank); - PRINT6ADDR(from); - PRINTF("\n"); - } else { - p = rpl_find_parent(previous_dag, from); - if(p != NULL) { - rpl_move_parent(previous_dag, dag, p); - } - } - } else { - if(p->rank == dio->rank) { - PRINTF("RPL: Received consistent DIO\n"); - if(dag->joined) { - instance->dio_counter++; - } - } else { - p->rank=dio->rank; - } - } - - /* Parent info has been updated, trigger rank recalculation */ - p->flags |= RPL_PARENT_FLAG_UPDATED; - - PRINTF("RPL: preferred DAG "); - PRINT6ADDR(&instance->current_dag->dag_id); - PRINTF(", rank %u, min_rank %u, ", - instance->current_dag->rank, instance->current_dag->min_rank); - PRINTF("parent rank %u, parent etx %u, link metric %u, instance etx %u\n", - p->rank, -1/*p->mc.obj.etx*/, - rpl_get_nbr(p) ? rpl_get_nbr(p)->link_metric : 0, - instance->mc.obj.etx); - - /* We have allocated a candidate parent; process the DIO further. */ - -#if RPL_DAG_MC != RPL_DAG_MC_NONE - memcpy(&p->mc, &dio->mc, sizeof(p->mc)); -#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ - if(rpl_process_parent_event(instance, p) == 0) { - PRINTF("RPL: The candidate parent is rejected\n"); - return; - } - - /* We don't use route control, so we can have only one official parent. */ - if(dag->joined && p == dag->preferred_parent) { - if(should_send_dao(instance, dio, p)) { - RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); - rpl_schedule_dao(instance); - } - /* We received a new DIO from our preferred parent. - * Call uip_ds6_defrt_add to set a fresh value for the lifetime counter */ - uip_ds6_defrt_add(from, RPL_LIFETIME(instance, instance->default_lifetime)); - } - p->dtsn = dio->dtsn; -} -/*---------------------------------------------------------------------------*/ -void -rpl_lock_parent(rpl_parent_t *p) -{ - nbr_table_lock(rpl_parents, p); -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/rpl/rpl-ext-header.c b/net/ip/contiki/rpl/rpl-ext-header.c deleted file mode 100644 index 662a0a19ed55c12b9dc9a340e577ccca1992aca7..0000000000000000000000000000000000000000 --- a/net/ip/contiki/rpl/rpl-ext-header.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (c) 2009, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Management of extension headers for ContikiRPL. - * - * \author Vincent Brillault , - * Joakim Eriksson , - * Niclas Finne , - * Nicolas Tsiftes . - */ - -/** - * \addtogroup uip6 - * @{ - */ - -#include - -#include "contiki/ip/uip.h" -#include "contiki/ip/tcpip.h" -#include "contiki/ipv6/uip-ds6.h" -#include "contiki/rpl/rpl-private.h" -#include "contiki/packetbuf.h" - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_RPL_ICMPV6 -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#include -#include - -/*---------------------------------------------------------------------------*/ -#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) -#define UIP_EXT_BUF(buf) ((struct uip_ext_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)]) -#define UIP_HBHO_BUF(buf) ((struct uip_hbho_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)]) -#define UIP_HBHO_NEXT_BUF(buf) ((struct uip_ext_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf) + RPL_HOP_BY_HOP_LEN]) -#define UIP_EXT_HDR_OPT_BUF(buf) ((struct uip_ext_hdr_opt *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf) + uip_ext_opt_offset]) -#define UIP_EXT_HDR_OPT_PADN_BUF(buf) ((struct uip_ext_hdr_opt_padn *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf) + uip_ext_opt_offset]) -#define UIP_EXT_HDR_OPT_RPL_BUF(buf) ((struct uip_ext_hdr_opt_rpl *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf) + uip_ext_opt_offset]) -/*---------------------------------------------------------------------------*/ -int -rpl_verify_header(struct net_buf *buf, int uip_ext_opt_offset) -{ - rpl_instance_t *instance; - int down; - uint16_t sender_rank; - uint8_t sender_closer; - uip_ds6_route_t *route; - - if(UIP_HBHO_BUF(buf)->len != RPL_HOP_BY_HOP_LEN - 8) { - PRINTF("RPL: Hop-by-hop extension header has wrong size\n"); - return 1; - } - - if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_type != UIP_EXT_HDR_OPT_RPL) { - PRINTF("RPL: Non RPL Hop-by-hop option\n"); - return 1; - } - - if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_len != RPL_HDR_OPT_LEN) { - PRINTF("RPL: Bad header option! (wrong length)\n"); - return 1; - } - - instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance); - if(instance == NULL) { - PRINTF("RPL: Unknown instance: %u\n", - UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance); - return 1; - } - - if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags & RPL_HDR_OPT_FWD_ERR) { - PRINTF("RPL: Forward error!\n"); - /* We should try to repair it by removing the neighbor that caused - the packet to be forwareded in the first place. We drop any - routes that go through the neighbor that sent the packet to - us. */ - route = uip_ds6_route_lookup(&UIP_IP_BUF(buf)->destipaddr); - if(route != NULL) { - uip_ds6_route_rm(route); - } - RPL_STAT(rpl_stats.forward_errors++); - /* Trigger DAO retransmission */ - rpl_reset_dio_timer(instance); - /* drop the packet as it is not routable */ - return 1; - } - - if(!instance->current_dag->joined) { - PRINTF("RPL: No DAG in the instance\n"); - return 1; - } - - down = 0; - if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags & RPL_HDR_OPT_DOWN) { - down = 1; - } - - sender_rank = UIP_HTONS(UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank); - sender_closer = sender_rank < instance->current_dag->rank; - - PRINTF("RPL: Packet going %s, sender closer %d (%d < %d)\n", down == 1 ? "down" : "up", - sender_closer, - sender_rank, - instance->current_dag->rank - ); - - if((down && !sender_closer) || (!down && sender_closer)) { - PRINTF("RPL: Loop detected - senderrank: %d my-rank: %d sender_closer: %d\n", - sender_rank, instance->current_dag->rank, - sender_closer); - if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags & RPL_HDR_OPT_RANK_ERR) { - RPL_STAT(rpl_stats.loop_errors++); - PRINTF("RPL: Rank error signalled in RPL option!\n"); - /* Packet must be dropped and dio trickle timer reset, see RFC6550 - 11.2.2.2 */ - rpl_reset_dio_timer(instance); - return 1; - } - PRINTF("RPL: Single error tolerated\n"); - RPL_STAT(rpl_stats.loop_warnings++); - UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags |= RPL_HDR_OPT_RANK_ERR; - return 0; - } - - PRINTF("RPL: Rank OK\n"); - - return 0; -} -/*---------------------------------------------------------------------------*/ -static void -set_rpl_opt(struct net_buf *buf, unsigned uip_ext_opt_offset) -{ - uint8_t temp_len; - - memmove(UIP_HBHO_NEXT_BUF(buf), UIP_EXT_BUF(buf), uip_len(buf) - UIP_IPH_LEN); - memset(UIP_HBHO_BUF(buf), 0, RPL_HOP_BY_HOP_LEN); - UIP_HBHO_BUF(buf)->next = UIP_IP_BUF(buf)->proto; - UIP_IP_BUF(buf)->proto = UIP_PROTO_HBHO; - UIP_HBHO_BUF(buf)->len = RPL_HOP_BY_HOP_LEN - 8; - UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_type = UIP_EXT_HDR_OPT_RPL; - UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_len = RPL_HDR_OPT_LEN; - UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags = 0; - UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance = 0; - UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank = 0; - uip_len(buf) += RPL_HOP_BY_HOP_LEN; - temp_len = UIP_IP_BUF(buf)->len[1]; - UIP_IP_BUF(buf)->len[1] += UIP_HBHO_BUF(buf)->len + 8; - if(UIP_IP_BUF(buf)->len[1] < temp_len) { - UIP_IP_BUF(buf)->len[0]++; - } -} -/*---------------------------------------------------------------------------*/ -int -rpl_update_header_empty(struct net_buf *buf) -{ - rpl_instance_t *instance; - int uip_ext_opt_offset; - int last_uip_ext_len; - rpl_parent_t *parent; - - last_uip_ext_len = uip_ext_len(buf); - uip_ext_len(buf) = 0; - uip_ext_opt_offset = 2; - - PRINTF("RPL: Verifying the presence of the RPL header option\n"); - - switch(UIP_IP_BUF(buf)->proto) { - case UIP_PROTO_HBHO: - if(UIP_HBHO_BUF(buf)->len != RPL_HOP_BY_HOP_LEN - 8) { - PRINTF("RPL: Hop-by-hop extension header has wrong size\n"); - uip_ext_len(buf) = last_uip_ext_len; - return 0; - } - if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_type != UIP_EXT_HDR_OPT_RPL) { - PRINTF("RPL: Non RPL Hop-by-hop option support not implemented\n"); - uip_ext_len(buf) = last_uip_ext_len; - return 0; - } - if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_len != RPL_HDR_OPT_LEN) { - PRINTF("RPL: RPL Hop-by-hop option has wrong length\n"); - uip_ext_len(buf) = last_uip_ext_len; - return 0; - } - instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance); - if(instance == NULL || !instance->used || !instance->current_dag->joined) { - PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect instance\n"); - return 0; - } - break; - default: -#if RPL_INSERT_HBH_OPTION - PRINTF("RPL: No hop-by-hop option found, creating it\n"); - if(uip_len(buf) + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE) { - PRINTF("RPL: Packet too long: impossible to add hop-by-hop option\n"); - uip_ext_len(buf) = last_uip_ext_len; - return 0; - } - set_rpl_opt(buf, uip_ext_opt_offset); - uip_ext_len(buf) = last_uip_ext_len + RPL_HOP_BY_HOP_LEN; -#endif - return 0; - } - - switch(UIP_EXT_HDR_OPT_BUF(buf)->type) { - case UIP_EXT_HDR_OPT_RPL: - PRINTF("RPL: Updating RPL option\n"); - UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank = UIP_HTONS(instance->current_dag->rank); - - /* Check the direction of the down flag, as per Section 11.2.2.3, - which states that if a packet is going down it should in - general not go back up again. If this happens, a - RPL_HDR_OPT_FWD_ERR should be flagged. */ - if((UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags & RPL_HDR_OPT_DOWN)) { - if(uip_ds6_route_lookup(&UIP_IP_BUF(buf)->destipaddr) == NULL) { - UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags |= RPL_HDR_OPT_FWD_ERR; - PRINTF("RPL forwarding error\n"); - /* We should send back the packet to the originating parent, - but it is not feasible yet, so we send a No-Path DAO instead */ - PRINTF("RPL generate No-Path DAO\n"); - parent = rpl_get_parent((uip_lladdr_t *)&ip_buf_ll_src(buf)); - if(parent != NULL) { - dao_output_target(parent, &UIP_IP_BUF(buf)->destipaddr, RPL_ZERO_LIFETIME); - } - /* Drop packet */ - return 1; - } - } else { - /* Set the down extension flag correctly as described in Section - 11.2 of RFC6550. If the packet progresses along a DAO route, - the down flag should be set. */ - if(uip_ds6_route_lookup(&UIP_IP_BUF(buf)->destipaddr) == NULL) { - /* No route was found, so this packet will go towards the RPL - root. If so, we should not set the down flag. */ - UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags &= ~RPL_HDR_OPT_DOWN; - PRINTF("RPL option going up\n"); - } else { - /* A DAO route was found so we set the down flag. */ - UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags |= RPL_HDR_OPT_DOWN; - PRINTF("RPL option going down\n"); - } - } - - uip_ext_len(buf) = last_uip_ext_len; - return 0; - default: - PRINTF("RPL: Multi Hop-by-hop options not implemented\n"); - uip_ext_len(buf) = last_uip_ext_len; - return 0; - } -} -/*---------------------------------------------------------------------------*/ -int -rpl_update_header_final(struct net_buf *buf, uip_ipaddr_t *addr) -{ - rpl_parent_t *parent; - int uip_ext_opt_offset; - int last_uip_ext_len; - - last_uip_ext_len = uip_ext_len(buf); - uip_ext_len(buf) = 0; - uip_ext_opt_offset = 2; - - if(UIP_IP_BUF(buf)->proto == UIP_PROTO_HBHO) { - if(UIP_HBHO_BUF(buf)->len != RPL_HOP_BY_HOP_LEN - 8) { - PRINTF("RPL: Non RPL Hop-by-hop options support not implemented\n"); - uip_ext_len(buf) = last_uip_ext_len; - return 0; - } - - if(UIP_EXT_HDR_OPT_BUF(buf)->type == UIP_EXT_HDR_OPT_RPL) { - if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank == 0) { - PRINTF("RPL: Updating RPL option\n"); - if(default_instance == NULL || !default_instance->used || !default_instance->current_dag->joined) { - PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect default instance\n"); - return 1; - } - parent = rpl_find_parent(default_instance->current_dag, addr); - if(parent == NULL || parent != parent->dag->preferred_parent) { - UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags = RPL_HDR_OPT_DOWN; - } - UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance = default_instance->instance_id; - UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank = UIP_HTONS(default_instance->current_dag->rank); - } - } - } - return 0; -} -/*---------------------------------------------------------------------------*/ -void -rpl_remove_header(struct net_buf *buf) -{ - uint8_t temp_len; - - uip_ext_len(buf) = 0; - - PRINTF("RPL: Verifying the presence of the RPL header option\n"); - switch(UIP_IP_BUF(buf)->proto){ - case UIP_PROTO_HBHO: - PRINTF("RPL: Removing the RPL header option\n"); - UIP_IP_BUF(buf)->proto = UIP_HBHO_BUF(buf)->next; - temp_len = UIP_IP_BUF(buf)->len[1]; - uip_len(buf) -= UIP_HBHO_BUF(buf)->len + 8; - UIP_IP_BUF(buf)->len[1] -= UIP_HBHO_BUF(buf)->len + 8; - if(UIP_IP_BUF(buf)->len[1] > temp_len) { - UIP_IP_BUF(buf)->len[0]--; - } - memmove(UIP_EXT_BUF(buf), UIP_HBHO_NEXT_BUF(buf), uip_len(buf) - UIP_IPH_LEN); - break; - default: - PRINTF("RPL: No hop-by-hop Option found\n"); - } -} -/*---------------------------------------------------------------------------*/ -uint8_t -rpl_invert_header(struct net_buf *buf) -{ - uint8_t uip_ext_opt_offset; - uint8_t last_uip_ext_len; - - last_uip_ext_len = uip_ext_len(buf); - uip_ext_len(buf) = 0; - uip_ext_opt_offset = 2; - - PRINTF("RPL: Verifying the presence of the RPL header option\n"); - switch(UIP_IP_BUF(buf)->proto) { - case UIP_PROTO_HBHO: - break; - default: - PRINTF("RPL: No hop-by-hop Option found\n"); - uip_ext_len(buf) = last_uip_ext_len; - return 0; - } - - switch (UIP_EXT_HDR_OPT_BUF(buf)->type) { - case UIP_EXT_HDR_OPT_RPL: - PRINTF("RPL: Updating RPL option (switching direction)\n"); - UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags &= RPL_HDR_OPT_DOWN; - UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags ^= RPL_HDR_OPT_DOWN; - UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank = UIP_HTONS(rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance)->current_dag->rank); - uip_ext_len(buf) = last_uip_ext_len; - return RPL_HOP_BY_HOP_LEN; - default: - PRINTF("RPL: Multi Hop-by-hop options not implemented\n"); - uip_ext_len(buf) = last_uip_ext_len; - return 0; - } -} -/*---------------------------------------------------------------------------*/ -void -rpl_insert_header(struct net_buf *buf) -{ -#if RPL_INSERT_HBH_OPTION - if(default_instance != NULL && !uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr)) { - rpl_update_header_empty(buf); - } -#endif -} -/*---------------------------------------------------------------------------*/ - -/** @}*/ diff --git a/net/ip/contiki/rpl/rpl-icmp6.c b/net/ip/contiki/rpl/rpl-icmp6.c deleted file mode 100644 index 1fe5ed6d877410ace5a188fbf9131b84fd422fef..0000000000000000000000000000000000000000 --- a/net/ip/contiki/rpl/rpl-icmp6.c +++ /dev/null @@ -1,997 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * ICMP6 I/O for RPL control messages. - * - * \author Joakim Eriksson , Nicolas Tsiftes - * Contributors: Niclas Finne , Joel Hoglund , - * Mathieu Pouillot - * George Oikonomou (multicast) - */ - -/** - * \addtogroup uip6 - * @{ - */ - -#include - -#include "contiki/ip/tcpip.h" -#include "contiki/ip/uip.h" -#include "contiki/ipv6/uip-ds6.h" -#include "contiki/ipv6/uip-nd6.h" -#include "contiki/ipv6/uip-icmp6.h" -#include "contiki/rpl/rpl-private.h" -#include "contiki/ipv6/multicast/uip-mcast6.h" - -#include -#include - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_RPL_ICMPV6 -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -/*---------------------------------------------------------------------------*/ -#define RPL_DIO_GROUNDED 0x80 -#define RPL_DIO_MOP_SHIFT 3 -#define RPL_DIO_MOP_MASK 0x38 -#define RPL_DIO_PREFERENCE_MASK 0x07 - -#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) -#define UIP_ICMP_BUF(buf) ((struct uip_icmp_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)]) -#define UIP_ICMP_PAYLOAD(buf) ((unsigned char *)&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf)]) -/*---------------------------------------------------------------------------*/ -static void dis_input(struct net_buf *buf); -static void dio_input(struct net_buf *buf); -static void dao_input(struct net_buf *buf); -static void dao_ack_input(struct net_buf *buf); - -/* some debug callbacks useful when debugging RPL networks */ -#ifdef RPL_DEBUG_DIO_INPUT -void RPL_DEBUG_DIO_INPUT(uip_ipaddr_t *, rpl_dio_t *); -#endif - -#ifdef RPL_DEBUG_DAO_OUTPUT -void RPL_DEBUG_DAO_OUTPUT(rpl_parent_t *); -#endif - -static uint8_t dao_sequence = RPL_LOLLIPOP_INIT; - -extern rpl_of_t RPL_OF; - -#if RPL_CONF_MULTICAST -static uip_mcast6_route_t *mcast_group; -#endif -/*---------------------------------------------------------------------------*/ -/* Initialise RPL ICMPv6 message handlers */ -UIP_ICMP6_HANDLER(dis_handler, ICMP6_RPL, RPL_CODE_DIS, dis_input); -UIP_ICMP6_HANDLER(dio_handler, ICMP6_RPL, RPL_CODE_DIO, dio_input); -UIP_ICMP6_HANDLER(dao_handler, ICMP6_RPL, RPL_CODE_DAO, dao_input); -UIP_ICMP6_HANDLER(dao_ack_handler, ICMP6_RPL, RPL_CODE_DAO_ACK, dao_ack_input); -/*---------------------------------------------------------------------------*/ -static int -get_global_addr(uip_ipaddr_t *addr) -{ - int i; - int state; - - for(i = 0; i < UIP_DS6_ADDR_NB; i++) { - state = uip_ds6_if.addr_list[i].state; - if(uip_ds6_if.addr_list[i].isused && - (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { - if(!uip_is_addr_link_local(&uip_ds6_if.addr_list[i].ipaddr)) { - memcpy(addr, &uip_ds6_if.addr_list[i].ipaddr, sizeof(uip_ipaddr_t)); - return 1; - } - } - } - return 0; -} -/*---------------------------------------------------------------------------*/ -static uint32_t -get32(uint8_t *buffer, int pos) -{ - return (uint32_t)buffer[pos] << 24 | (uint32_t)buffer[pos + 1] << 16 | - (uint32_t)buffer[pos + 2] << 8 | buffer[pos + 3]; -} -/*---------------------------------------------------------------------------*/ -static void -set32(uint8_t *buffer, int pos, uint32_t value) -{ - buffer[pos++] = value >> 24; - buffer[pos++] = (value >> 16) & 0xff; - buffer[pos++] = (value >> 8) & 0xff; - buffer[pos++] = value & 0xff; -} -/*---------------------------------------------------------------------------*/ -static uint16_t -get16(uint8_t *buffer, int pos) -{ - return (uint16_t)buffer[pos] << 8 | buffer[pos + 1]; -} -/*---------------------------------------------------------------------------*/ -static void -set16(uint8_t *buffer, int pos, uint16_t value) -{ - buffer[pos++] = value >> 8; - buffer[pos++] = value & 0xff; -} -/*---------------------------------------------------------------------------*/ -static void -dis_input(struct net_buf *buf) -{ - rpl_instance_t *instance; - rpl_instance_t *end; - - /* DAG Information Solicitation */ - PRINTF("RPL: Received a DIS from "); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF("\n"); - - for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; - instance < end; ++instance) { - if(instance->used == 1) { -#if RPL_LEAF_ONLY - if(!uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr)) { - PRINTF("RPL: LEAF ONLY Multicast DIS will NOT reset DIO timer\n"); -#else /* !RPL_LEAF_ONLY */ - if(uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr)) { - PRINTF("RPL: Multicast DIS => reset DIO timer\n"); - rpl_reset_dio_timer(instance); - } else { -#endif /* !RPL_LEAF_ONLY */ - PRINTF("RPL: Unicast DIS, reply to sender\n"); - dio_output(instance, &UIP_IP_BUF(buf)->srcipaddr); - } - } - } - uip_len(buf) = 0; -} -/*---------------------------------------------------------------------------*/ -void -dis_output(struct net_buf *buf, uip_ipaddr_t *addr) -{ - unsigned char *buffer; - uip_ipaddr_t tmpaddr; - - /* - * DAG Information Solicitation - 2 bytes reserved - * 0 1 2 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Flags | Reserved | Option(s)... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - - if (!buf) { - buf = ip_buf_get_reserve_tx(0); - if (!buf) { - PRINTF("%s(): Cannot get net_buf\n", __FUNCTION__); - return; - } - } - buffer = UIP_ICMP_PAYLOAD(buf); - buffer[0] = buffer[1] = 0; - - if(addr == NULL) { - uip_create_linklocal_rplnodes_mcast(&tmpaddr); - addr = &tmpaddr; - } - - PRINTF("RPL: Sending a DIS to "); - PRINT6ADDR(addr); - PRINTF("\n"); - - uip_icmp6_send(buf, addr, ICMP6_RPL, RPL_CODE_DIS, 2); -} -/*---------------------------------------------------------------------------*/ -static void -dio_input(struct net_buf *buf) -{ - unsigned char *buffer; - uint8_t buffer_length; - rpl_dio_t dio; - uint8_t subopt_type; - int i; - int len; - uip_ipaddr_t from; - uip_ds6_nbr_t *nbr; - - memset(&dio, 0, sizeof(dio)); - - /* Set default values in case the DIO configuration option is missing. */ - dio.dag_intdoubl = RPL_DIO_INTERVAL_DOUBLINGS; - dio.dag_intmin = RPL_DIO_INTERVAL_MIN; - dio.dag_redund = RPL_DIO_REDUNDANCY; - dio.dag_min_hoprankinc = RPL_MIN_HOPRANKINC; - dio.dag_max_rankinc = RPL_MAX_RANKINC; - dio.ocp = RPL_OF.ocp; - dio.default_lifetime = RPL_DEFAULT_LIFETIME; - dio.lifetime_unit = RPL_DEFAULT_LIFETIME_UNIT; - - uip_ipaddr_copy(&from, &UIP_IP_BUF(buf)->srcipaddr); - - /* DAG Information Object */ - PRINTF("RPL: Received a DIO from "); - PRINT6ADDR(&from); - PRINTF("\n"); - - if((nbr = uip_ds6_nbr_lookup(&from)) == NULL) { - if((nbr = uip_ds6_nbr_add(&from, (uip_lladdr_t *)&ip_buf_ll_src(buf), - 0, NBR_REACHABLE)) != NULL) { - /* set reachable timer */ - stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000); - PRINTF("RPL: Neighbor added to neighbor cache "); - PRINT6ADDR(&from); - PRINTF(", "); - PRINTLLADDR((uip_lladdr_t *)&ip_buf_ll_src(buf)); - PRINTF("\n"); - } else { - PRINTF("RPL: Out of memory, dropping DIO from "); - PRINT6ADDR(&from); - PRINTF(", "); - PRINTLLADDR((uip_lladdr_t *)&ip_buf_ll_src(buf)); - PRINTF("\n"); - goto out; - } - } else { - PRINTF("RPL: Neighbor already in neighbor cache\n"); - } - - buffer_length = uip_len(buf) - uip_l3_icmp_hdr_len(buf); - - /* Process the DIO base option. */ - i = 0; - buffer = UIP_ICMP_PAYLOAD(buf); - - dio.instance_id = buffer[i++]; - dio.version = buffer[i++]; - dio.rank = get16(buffer, i); - i += 2; - - PRINTF("RPL: Incoming DIO (id, ver, rank) = (%u,%u,%u)\n", - (unsigned)dio.instance_id, - (unsigned)dio.version, - (unsigned)dio.rank); - - dio.grounded = buffer[i] & RPL_DIO_GROUNDED; - dio.mop = (buffer[i]& RPL_DIO_MOP_MASK) >> RPL_DIO_MOP_SHIFT; - dio.preference = buffer[i++] & RPL_DIO_PREFERENCE_MASK; - - dio.dtsn = buffer[i++]; - /* two reserved bytes */ - i += 2; - - memcpy(&dio.dag_id, buffer + i, sizeof(dio.dag_id)); - i += sizeof(dio.dag_id); - - PRINTF("RPL: Incoming DIO (dag_id, pref) = ("); - PRINT6ADDR(&dio.dag_id); - PRINTF(", %u)\n", dio.preference); - - /* Check if there are any DIO suboptions. */ - for(; i < buffer_length; i += len) { - subopt_type = buffer[i]; - if(subopt_type == RPL_OPTION_PAD1) { - len = 1; - } else { - /* Suboption with a two-byte header + payload */ - len = 2 + buffer[i + 1]; - } - - if(len + i > buffer_length) { - PRINTF("RPL: Invalid DIO packet\n"); - RPL_STAT(rpl_stats.malformed_msgs++); - goto out; - } - - PRINTF("RPL: DIO option %u, length: %u\n", subopt_type, len - 2); - - switch(subopt_type) { - case RPL_OPTION_DAG_METRIC_CONTAINER: - if(len < 6) { - PRINTF("RPL: Invalid DAG MC, len = %d\n", len); - RPL_STAT(rpl_stats.malformed_msgs++); - goto out; - } - dio.mc.type = buffer[i + 2]; - dio.mc.flags = buffer[i + 3] << 1; - dio.mc.flags |= buffer[i + 4] >> 7; - dio.mc.aggr = (buffer[i + 4] >> 4) & 0x3; - dio.mc.prec = buffer[i + 4] & 0xf; - dio.mc.length = buffer[i + 5]; - - if(dio.mc.type == RPL_DAG_MC_NONE) { - /* No metric container: do nothing */ - } else if(dio.mc.type == RPL_DAG_MC_ETX) { - dio.mc.obj.etx = get16(buffer, i + 6); - - PRINTF("RPL: DAG MC: type %u, flags %u, aggr %u, prec %u, length %u, ETX %u\n", - (unsigned)dio.mc.type, - (unsigned)dio.mc.flags, - (unsigned)dio.mc.aggr, - (unsigned)dio.mc.prec, - (unsigned)dio.mc.length, - (unsigned)dio.mc.obj.etx); - } else if(dio.mc.type == RPL_DAG_MC_ENERGY) { - dio.mc.obj.energy.flags = buffer[i + 6]; - dio.mc.obj.energy.energy_est = buffer[i + 7]; - } else { - PRINTF("RPL: Unhandled DAG MC type: %u\n", (unsigned)dio.mc.type); - goto out; - } - break; - case RPL_OPTION_ROUTE_INFO: - if(len < 9) { - PRINTF("RPL: Invalid destination prefix option, len = %d\n", len); - RPL_STAT(rpl_stats.malformed_msgs++); - goto out; - } - - /* The flags field includes the preference value. */ - dio.destination_prefix.length = buffer[i + 2]; - dio.destination_prefix.flags = buffer[i + 3]; - dio.destination_prefix.lifetime = get32(buffer, i + 4); - - if(((dio.destination_prefix.length + 7) / 8) + 8 <= len && - dio.destination_prefix.length <= 128) { - PRINTF("RPL: Copying destination prefix\n"); - memcpy(&dio.destination_prefix.prefix, &buffer[i + 8], - (dio.destination_prefix.length + 7) / 8); - } else { - PRINTF("RPL: Invalid route info option, len = %d\n", len); - RPL_STAT(rpl_stats.malformed_msgs++); - goto out; - } - - break; - case RPL_OPTION_DAG_CONF: - if(len != 16) { - PRINTF("RPL: Invalid DAG configuration option, len = %d\n", len); - RPL_STAT(rpl_stats.malformed_msgs++); - goto out; - } - - /* Path control field not yet implemented - at i + 2 */ - dio.dag_intdoubl = buffer[i + 3]; - dio.dag_intmin = buffer[i + 4]; - dio.dag_redund = buffer[i + 5]; - dio.dag_max_rankinc = get16(buffer, i + 6); - dio.dag_min_hoprankinc = get16(buffer, i + 8); - dio.ocp = get16(buffer, i + 10); - /* buffer + 12 is reserved */ - dio.default_lifetime = buffer[i + 13]; - dio.lifetime_unit = get16(buffer, i + 14); - PRINTF("RPL: DAG conf:dbl=%d, min=%d red=%d maxinc=%d mininc=%d ocp=%d d_l=%u l_u=%u\n", - dio.dag_intdoubl, dio.dag_intmin, dio.dag_redund, - dio.dag_max_rankinc, dio.dag_min_hoprankinc, dio.ocp, - dio.default_lifetime, dio.lifetime_unit); - break; - case RPL_OPTION_PREFIX_INFO: - if(len != 32) { - PRINTF("RPL: Invalid DAG prefix info, len(%d) != 32\n", len); - RPL_STAT(rpl_stats.malformed_msgs++); - goto out; - } - dio.prefix_info.length = buffer[i + 2]; - dio.prefix_info.flags = buffer[i + 3]; - /* valid lifetime is ingnored for now - at i + 4 */ - /* preferred lifetime stored in lifetime */ - dio.prefix_info.lifetime = get32(buffer, i + 8); - /* 32-bit reserved at i + 12 */ - PRINTF("RPL: Copying prefix information\n"); - memcpy(&dio.prefix_info.prefix, &buffer[i + 16], 16); - break; - default: - PRINTF("RPL: Unsupported suboption type in DIO: %u\n", - (unsigned)subopt_type); - } - } - -#ifdef RPL_DEBUG_DIO_INPUT - RPL_DEBUG_DIO_INPUT(&from, &dio); -#endif - - rpl_process_dio(&from, &dio); - -out: - uip_len(buf) = 0; -} -/*---------------------------------------------------------------------------*/ -void -dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr) -{ - struct net_buf *buf; - unsigned char *buffer; - int pos; - rpl_dag_t *dag = instance->current_dag; -#if !RPL_LEAF_ONLY - uip_ipaddr_t addr; -#endif /* !RPL_LEAF_ONLY */ - -#if RPL_LEAF_ONLY - /* In leaf mode, we only send DIO messages as unicasts in response to - unicast DIS messages. */ - if(uc_addr == NULL) { - PRINTF("RPL: LEAF ONLY have multicast addr: skip dio_output\n"); - return; - } -#endif /* RPL_LEAF_ONLY */ - - /* DAG Information Object */ - pos = 0; - - buf = ip_buf_get_reserve_tx(0); - if (!buf) { - PRINTF("%s(): Cannot get net_buf\n", __FUNCTION__); - return; - } - - buffer = UIP_ICMP_PAYLOAD(buf); - buffer[pos++] = instance->instance_id; - buffer[pos++] = dag->version; - -#if RPL_LEAF_ONLY - PRINTF("RPL: LEAF ONLY DIO rank set to INFINITE_RANK\n"); - set16(buffer, pos, INFINITE_RANK); -#else /* RPL_LEAF_ONLY */ - set16(buffer, pos, dag->rank); -#endif /* RPL_LEAF_ONLY */ - pos += 2; - - buffer[pos] = 0; - if(dag->grounded) { - buffer[pos] |= RPL_DIO_GROUNDED; - } - - buffer[pos] |= instance->mop << RPL_DIO_MOP_SHIFT; - buffer[pos] |= dag->preference & RPL_DIO_PREFERENCE_MASK; - pos++; - - buffer[pos++] = instance->dtsn_out; - - if(uc_addr == NULL) { - /* Request new DAO to refresh route. We do not do this for unicast DIO - * in order to avoid DAO messages after a DIS-DIO update, - * or upon unicast DIO probing. */ - RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); - } - - /* reserved 2 bytes */ - buffer[pos++] = 0; /* flags */ - buffer[pos++] = 0; /* reserved */ - - memcpy(buffer + pos, &dag->dag_id, sizeof(dag->dag_id)); - pos += 16; - -#if !RPL_LEAF_ONLY - if(instance->mc.type != RPL_DAG_MC_NONE) { - instance->of->update_metric_container(instance); - - buffer[pos++] = RPL_OPTION_DAG_METRIC_CONTAINER; - buffer[pos++] = 6; - buffer[pos++] = instance->mc.type; - buffer[pos++] = instance->mc.flags >> 1; - buffer[pos] = (instance->mc.flags & 1) << 7; - buffer[pos++] |= (instance->mc.aggr << 4) | instance->mc.prec; - if(instance->mc.type == RPL_DAG_MC_ETX) { - buffer[pos++] = 2; - set16(buffer, pos, instance->mc.obj.etx); - pos += 2; - } else if(instance->mc.type == RPL_DAG_MC_ENERGY) { - buffer[pos++] = 2; - buffer[pos++] = instance->mc.obj.energy.flags; - buffer[pos++] = instance->mc.obj.energy.energy_est; - } else { - PRINTF("RPL: Unable to send DIO because of unhandled DAG MC type %u\n", - (unsigned)instance->mc.type); - ip_buf_unref(buf); - return; - } - } -#endif /* !RPL_LEAF_ONLY */ - - /* Always add a DAG configuration option. */ - buffer[pos++] = RPL_OPTION_DAG_CONF; - buffer[pos++] = 14; - buffer[pos++] = 0; /* No Auth, PCS = 0 */ - buffer[pos++] = instance->dio_intdoubl; - buffer[pos++] = instance->dio_intmin; - buffer[pos++] = instance->dio_redundancy; - set16(buffer, pos, instance->max_rankinc); - pos += 2; - set16(buffer, pos, instance->min_hoprankinc); - pos += 2; - /* OCP is in the DAG_CONF option */ - set16(buffer, pos, instance->of->ocp); - pos += 2; - buffer[pos++] = 0; /* reserved */ - buffer[pos++] = instance->default_lifetime; - set16(buffer, pos, instance->lifetime_unit); - pos += 2; - - /* Check if we have a prefix to send also. */ - if(dag->prefix_info.length > 0) { - buffer[pos++] = RPL_OPTION_PREFIX_INFO; - buffer[pos++] = 30; /* always 30 bytes + 2 long */ - buffer[pos++] = dag->prefix_info.length; - buffer[pos++] = dag->prefix_info.flags; - set32(buffer, pos, dag->prefix_info.lifetime); - pos += 4; - set32(buffer, pos, dag->prefix_info.lifetime); - pos += 4; - memset(&buffer[pos], 0, 4); - pos += 4; - memcpy(&buffer[pos], &dag->prefix_info.prefix, 16); - pos += 16; - PRINTF("RPL: Sending prefix info in DIO for "); - PRINT6ADDR(&dag->prefix_info.prefix); - PRINTF("\n"); - } else { - PRINTF("RPL: No prefix to announce (len %d)\n", - dag->prefix_info.length); - } - -#if RPL_LEAF_ONLY -#if (DEBUG) & DEBUG_PRINT - if(uc_addr == NULL) { - PRINTF("RPL: LEAF ONLY sending unicast-DIO from multicast-DIO\n"); - } -#endif /* DEBUG_PRINT */ - PRINTF("RPL: Sending unicast-DIO with rank %u to ", - (unsigned)dag->rank); - PRINT6ADDR(uc_addr); - PRINTF("\n"); - uip_icmp6_send(buf, uc_addr, ICMP6_RPL, RPL_CODE_DIO, pos); -#else /* RPL_LEAF_ONLY */ - /* Unicast requests get unicast replies! */ - if(uc_addr == NULL) { - PRINTF("RPL: Sending a multicast-DIO with rank %u\n", - (unsigned)instance->current_dag->rank); - uip_create_linklocal_rplnodes_mcast(&addr); - uip_icmp6_send(buf, &addr, ICMP6_RPL, RPL_CODE_DIO, pos); - } else { - PRINTF("RPL: Sending unicast-DIO with rank %u to ", - (unsigned)instance->current_dag->rank); - PRINT6ADDR(uc_addr); - PRINTF("\n"); - uip_icmp6_send(buf, uc_addr, ICMP6_RPL, RPL_CODE_DIO, pos); - } -#endif /* RPL_LEAF_ONLY */ -} -/*---------------------------------------------------------------------------*/ -static void -dao_input(struct net_buf *buf) -{ - uip_ipaddr_t dao_sender_addr; - rpl_dag_t *dag; - rpl_instance_t *instance; - unsigned char *buffer; - uint16_t sequence; - uint8_t instance_id; - uint8_t lifetime; - uint8_t prefixlen; - uint8_t flags; - uint8_t subopt_type; - /* - uint8_t pathcontrol; - uint8_t pathsequence; - */ - uip_ipaddr_t prefix; - uip_ds6_route_t *rep; - uint8_t buffer_length; - int pos; - int len; - int i; - int learned_from; - rpl_parent_t *parent; - uip_ds6_nbr_t *nbr; - - prefixlen = 0; - parent = NULL; - - uip_ipaddr_copy(&dao_sender_addr, &UIP_IP_BUF(buf)->srcipaddr); - - /* Destination Advertisement Object */ - PRINTF("RPL: Received a DAO from "); - PRINT6ADDR(&dao_sender_addr); - PRINTF("\n"); - - buffer = UIP_ICMP_PAYLOAD(buf); - buffer_length = uip_len(buf) - uip_l3_icmp_hdr_len(buf); - - pos = 0; - instance_id = buffer[pos++]; - - instance = rpl_get_instance(instance_id); - if(instance == NULL) { - PRINTF("RPL: Ignoring a DAO for an unknown RPL instance(%u)\n", - instance_id); - return; - } - - lifetime = instance->default_lifetime; - - flags = buffer[pos++]; - /* reserved */ - pos++; - sequence = buffer[pos++]; - - dag = instance->current_dag; - /* Is the DAG ID present? */ - if(flags & RPL_DAO_D_FLAG) { - if(memcmp(&dag->dag_id, &buffer[pos], sizeof(dag->dag_id))) { - PRINTF("RPL: Ignoring a DAO for a DAG different from ours\n"); - return; - } - pos += 16; - } - - learned_from = uip_is_addr_mcast(&dao_sender_addr) ? - RPL_ROUTE_FROM_MULTICAST_DAO : RPL_ROUTE_FROM_UNICAST_DAO; - - PRINTF("RPL: DAO from %s\n", - learned_from == RPL_ROUTE_FROM_UNICAST_DAO? "unicast": "multicast"); - if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) { - /* Check whether this is a DAO forwarding loop. */ - parent = rpl_find_parent(dag, &dao_sender_addr); - /* check if this is a new DAO registration with an "illegal" rank */ - /* if we already route to this node it is likely */ - if(parent != NULL && - DAG_RANK(parent->rank, instance) < DAG_RANK(dag->rank, instance)) { - PRINTF("RPL: Loop detected when receiving a unicast DAO from a node with a lower rank! (%u < %u)\n", - DAG_RANK(parent->rank, instance), DAG_RANK(dag->rank, instance)); - parent->rank = INFINITE_RANK; - parent->flags |= RPL_PARENT_FLAG_UPDATED; - return; - } - - /* If we get the DAO from our parent, we also have a loop. */ - if(parent != NULL && parent == dag->preferred_parent) { - PRINTF("RPL: Loop detected when receiving a unicast DAO from our parent\n"); - parent->rank = INFINITE_RANK; - parent->flags |= RPL_PARENT_FLAG_UPDATED; - return; - } - } - - /* Check if there are any RPL options present. */ - for(i = pos; i < buffer_length; i += len) { - subopt_type = buffer[i]; - if(subopt_type == RPL_OPTION_PAD1) { - len = 1; - } else { - /* The option consists of a two-byte header and a payload. */ - len = 2 + buffer[i + 1]; - } - - switch(subopt_type) { - case RPL_OPTION_TARGET: - /* Handle the target option. */ - prefixlen = buffer[i + 3]; - memset(&prefix, 0, sizeof(prefix)); - memcpy(&prefix, buffer + i + 4, (prefixlen + 7) / CHAR_BIT); - break; - case RPL_OPTION_TRANSIT: - /* The path sequence and control are ignored. */ - /* pathcontrol = buffer[i + 3]; - pathsequence = buffer[i + 4];*/ - lifetime = buffer[i + 5]; - /* The parent address is also ignored. */ - break; - } - } - - PRINTF("RPL: DAO lifetime: %u, prefix length: %u prefix: ", - (unsigned)lifetime, (unsigned)prefixlen); - PRINT6ADDR(&prefix); - PRINTF("\n"); - -#if RPL_CONF_MULTICAST - if(uip_is_addr_mcast_global(&prefix)) { - mcast_group = uip_mcast6_route_add(&prefix); - if(mcast_group) { - mcast_group->dag = dag; - mcast_group->lifetime = RPL_LIFETIME(instance, lifetime); - } - goto fwd_dao; - } -#endif - - rep = uip_ds6_route_lookup(&prefix); - - if(lifetime == RPL_ZERO_LIFETIME) { - PRINTF("RPL: No-Path DAO received\n"); - /* No-Path DAO received; invoke the route purging routine. */ - if(rep != NULL && - rep->state.nopath_received == 0 && - rep->length == prefixlen && - uip_ds6_route_nexthop(rep) != NULL && - uip_ipaddr_cmp(uip_ds6_route_nexthop(rep), &dao_sender_addr)) { - PRINTF("RPL: Setting expiration timer for prefix "); - PRINT6ADDR(&prefix); - PRINTF("\n"); - rep->state.nopath_received = 1; - rep->state.lifetime = DAO_EXPIRATION_TIMEOUT; - - /* We forward the incoming no-path DAO to our parent, if we have - one. */ - if(dag->preferred_parent != NULL && - rpl_get_parent_ipaddr(dag->preferred_parent) != NULL) { - PRINTF("RPL: Forwarding no-path DAO to parent "); - PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent)); - PRINTF("\n"); - uip_icmp6_send(buf, rpl_get_parent_ipaddr(dag->preferred_parent), - ICMP6_RPL, RPL_CODE_DAO, buffer_length); - } - if(flags & RPL_DAO_K_FLAG) { - dao_ack_output(buf, instance, &dao_sender_addr, sequence); - } - } - return; - } - - PRINTF("RPL: adding DAO route\n"); - - if((nbr = uip_ds6_nbr_lookup(&dao_sender_addr)) == NULL) { - if((nbr = uip_ds6_nbr_add(&dao_sender_addr, - (uip_lladdr_t *)&ip_buf_ll_src(buf), - 0, NBR_REACHABLE)) != NULL) { - /* set reachable timer */ - stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000); - PRINTF("RPL: Neighbor added to neighbor cache "); - PRINT6ADDR(&dao_sender_addr); - PRINTF(", "); - PRINTLLADDR((uip_lladdr_t *)&ip_buf_ll_src(buf)); - PRINTF("\n"); - } else { - PRINTF("RPL: Out of Memory, dropping DAO from "); - PRINT6ADDR(&dao_sender_addr); - PRINTF(", "); - PRINTLLADDR((uip_lladdr_t *)&ip_buf_ll_src(buf)); - PRINTF("\n"); - return; - } - } else { - PRINTF("RPL: Neighbor already in neighbor cache\n"); - } - - rpl_lock_parent(parent); - - rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr); - if(rep == NULL) { - RPL_STAT(rpl_stats.mem_overflows++); - PRINTF("RPL: Could not add a route after receiving a DAO\n"); - return; - } - - rep->state.lifetime = RPL_LIFETIME(instance, lifetime); - rep->state.learned_from = learned_from; - rep->state.nopath_received = 0; - -#if RPL_CONF_MULTICAST -fwd_dao: -#endif - - if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) { - if(dag->preferred_parent != NULL && - rpl_get_parent_ipaddr(dag->preferred_parent) != NULL) { - PRINTF("RPL: Forwarding DAO to parent "); - PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent)); - PRINTF("\n"); - uip_icmp6_send(buf, rpl_get_parent_ipaddr(dag->preferred_parent), - ICMP6_RPL, RPL_CODE_DAO, buffer_length); - } - if(flags & RPL_DAO_K_FLAG) { - dao_ack_output(buf, instance, &dao_sender_addr, sequence); - } - } - uip_len(buf) = 0; -} -/*---------------------------------------------------------------------------*/ -/* Return true if msg was sent, false otherwise */ -void -dao_output(rpl_parent_t *parent, uint8_t lifetime) -{ - /* Destination Advertisement Object */ - uip_ipaddr_t prefix; - - if(get_global_addr(&prefix) == 0) { - PRINTF("RPL: No global address set for this node - suppressing DAO\n"); - return; - } - - /* Sending a DAO with own prefix as target */ - dao_output_target(parent, &prefix, lifetime); -} -/*---------------------------------------------------------------------------*/ -/* Return true if we sent a RPL message, false otherwise. - */ -void -dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime) -{ - struct net_buf *buf; - rpl_dag_t *dag; - rpl_instance_t *instance; - unsigned char *buffer; - uint8_t prefixlen; - int pos; - - /* Destination Advertisement Object */ - - /* If we are in feather mode, we should not send any DAOs */ - if(rpl_get_mode() == RPL_MODE_FEATHER) { - return; - } - - if(parent == NULL) { - PRINTF("RPL dao_output_target error parent NULL\n"); - return; - } - - dag = parent->dag; - if(dag == NULL) { - PRINTF("RPL dao_output_target error dag NULL\n"); - return; - } - - instance = dag->instance; - - if(instance == NULL) { - PRINTF("RPL dao_output_target error instance NULL\n"); - return; - } - if(prefix == NULL) { - PRINTF("RPL dao_output_target error prefix NULL\n"); - return; - } -#ifdef RPL_DEBUG_DAO_OUTPUT - RPL_DEBUG_DAO_OUTPUT(parent); -#endif - - buf = ip_buf_get_reserve_tx(0); - if (!buf) { - PRINTF("%s(): Cannot get net_buf\n", __FUNCTION__); - return; - } - - buffer = UIP_ICMP_PAYLOAD(buf); - - RPL_LOLLIPOP_INCREMENT(dao_sequence); - pos = 0; - - buffer[pos++] = instance->instance_id; - buffer[pos] = 0; -#if RPL_DAO_SPECIFY_DAG - buffer[pos] |= RPL_DAO_D_FLAG; -#endif /* RPL_DAO_SPECIFY_DAG */ -#if RPL_CONF_DAO_ACK - buffer[pos] |= RPL_DAO_K_FLAG; -#endif /* RPL_CONF_DAO_ACK */ - ++pos; - buffer[pos++] = 0; /* reserved */ - buffer[pos++] = dao_sequence; -#if RPL_DAO_SPECIFY_DAG - memcpy(buffer + pos, &dag->dag_id, sizeof(dag->dag_id)); - pos+=sizeof(dag->dag_id); -#endif /* RPL_DAO_SPECIFY_DAG */ - - /* create target subopt */ - prefixlen = sizeof(*prefix) * CHAR_BIT; - buffer[pos++] = RPL_OPTION_TARGET; - buffer[pos++] = 2 + ((prefixlen + 7) / CHAR_BIT); - buffer[pos++] = 0; /* reserved */ - buffer[pos++] = prefixlen; - memcpy(buffer + pos, prefix, (prefixlen + 7) / CHAR_BIT); - pos += ((prefixlen + 7) / CHAR_BIT); - - /* Create a transit information sub-option. */ - buffer[pos++] = RPL_OPTION_TRANSIT; - buffer[pos++] = 4; - buffer[pos++] = 0; /* flags - ignored */ - buffer[pos++] = 0; /* path control - ignored */ - buffer[pos++] = 0; /* path seq - ignored */ - buffer[pos++] = lifetime; - - PRINTF("RPL: Sending DAO with prefix "); - PRINT6ADDR(prefix); - PRINTF(" to "); - PRINT6ADDR(rpl_get_parent_ipaddr(parent)); - PRINTF("\n"); - - if(rpl_get_parent_ipaddr(parent) != NULL) { - uip_icmp6_send(buf, rpl_get_parent_ipaddr(parent), ICMP6_RPL, RPL_CODE_DAO, pos); - return; - } - - ip_buf_unref(buf); - return; -} -/*---------------------------------------------------------------------------*/ -static void -dao_ack_input(struct net_buf *buf) -{ -#if DEBUG - unsigned char *buffer; - uint8_t buffer_length; - uint8_t instance_id; - uint8_t sequence; - uint8_t status; - - buffer = UIP_ICMP_PAYLOAD(buf); - buffer_length = uip_len(buf) - uip_l3_icmp_hdr_len(buf); - - instance_id = buffer[0]; - sequence = buffer[2]; - status = buffer[3]; - - PRINTF("RPL: Received a DAO ACK with sequence number %d and status %d from ", - sequence, status); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF("\n"); -#endif /* DEBUG */ - uip_len(buf) = 0; -} -/*---------------------------------------------------------------------------*/ -void -dao_ack_output(struct net_buf *buf, rpl_instance_t *instance, uip_ipaddr_t *dest, uint8_t sequence) -{ - unsigned char *buffer; - - PRINTF("RPL: Sending a DAO ACK with sequence number %d to ", sequence); - PRINT6ADDR(dest); - PRINTF("\n"); - - buffer = UIP_ICMP_PAYLOAD(buf); - - buffer[0] = instance->instance_id; - buffer[1] = 0; - buffer[2] = sequence; - buffer[3] = 0; - - uip_icmp6_send(buf, dest, ICMP6_RPL, RPL_CODE_DAO_ACK, 4); -} -/*---------------------------------------------------------------------------*/ -void -rpl_icmp6_register_handlers() -{ - uip_icmp6_register_input_handler(&dis_handler); - uip_icmp6_register_input_handler(&dio_handler); - uip_icmp6_register_input_handler(&dao_handler); - uip_icmp6_register_input_handler(&dao_ack_handler); -} -/*---------------------------------------------------------------------------*/ - -/** @}*/ diff --git a/net/ip/contiki/rpl/rpl-mrhof.c b/net/ip/contiki/rpl/rpl-mrhof.c deleted file mode 100644 index ad412fe8b185aae9fa136c5a218356b33eb015e6..0000000000000000000000000000000000000000 --- a/net/ip/contiki/rpl/rpl-mrhof.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * The Minimum Rank with Hysteresis Objective Function (MRHOF) - * - * This implementation uses the estimated number of - * transmissions (ETX) as the additive routing metric, - * and also provides stubs for the energy metric. - * - * \author Joakim Eriksson , Nicolas Tsiftes - */ - -/** - * \addtogroup uip6 - * @{ - */ - -#include "contiki/rpl/rpl-private.h" -#include "contiki/nbr-table.h" - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_RPL_OF -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -static void reset(rpl_dag_t *); -static void neighbor_link_callback(rpl_parent_t *, int, int); -static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *); -static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *); -static rpl_rank_t calculate_rank(rpl_parent_t *, rpl_rank_t); -static void update_metric_container(rpl_instance_t *); - -rpl_of_t rpl_mrhof = { - reset, - neighbor_link_callback, - best_parent, - best_dag, - calculate_rank, - update_metric_container, - 1 -}; - -/* Constants for the ETX moving average */ -#define ETX_SCALE 100 -#define ETX_ALPHA 90 - -/* Reject parents that have a higher link metric than the following. */ -#define MAX_LINK_METRIC 10 - -/* Reject parents that have a higher path cost than the following. */ -#define MAX_PATH_COST 100 - -/* - * The rank must differ more than 1/PARENT_SWITCH_THRESHOLD_DIV in order - * to switch preferred parent. - */ -#define PARENT_SWITCH_THRESHOLD_DIV 2 - -typedef uint16_t rpl_path_metric_t; - -static rpl_path_metric_t -calculate_path_metric(rpl_parent_t *p) -{ - uip_ds6_nbr_t *nbr; - if(p == NULL) { - return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR; - } - nbr = rpl_get_nbr(p); - if(nbr == NULL) { - return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR; - } -#if RPL_DAG_MC == RPL_DAG_MC_NONE - { - return p->rank + (uint16_t)nbr->link_metric; - } -#elif RPL_DAG_MC == RPL_DAG_MC_ETX - return p->mc.obj.etx + (uint16_t)nbr->link_metric; -#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY - return p->mc.obj.energy.energy_est + (uint16_t)nbr->link_metric; -#else -#error "Unsupported RPL_DAG_MC configured. See rpl.h." -#endif /* RPL_DAG_MC */ -} - -static void -reset(rpl_dag_t *dag) -{ - PRINTF("RPL: Reset MRHOF\n"); -} - -static void -neighbor_link_callback(rpl_parent_t *p, int status, int numtx) -{ - uint16_t recorded_etx = 0; - uint16_t packet_etx = numtx * RPL_DAG_MC_ETX_DIVISOR; - uint16_t new_etx; - uip_ds6_nbr_t *nbr = NULL; - - nbr = rpl_get_nbr(p); - if(nbr == NULL) { - /* No neighbor for this parent - something bad has occurred */ - return; - } - - recorded_etx = nbr->link_metric; - - /* Do not penalize the ETX when collisions or transmission errors occur. */ - if(status == MAC_TX_OK || status == MAC_TX_NOACK) { - if(status == MAC_TX_NOACK) { - packet_etx = MAX_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR; - } - - if(p->flags & RPL_PARENT_FLAG_LINK_METRIC_VALID) { - /* We already have a valid link metric, use weighted moving average to update it */ - new_etx = ((uint32_t)recorded_etx * ETX_ALPHA + - (uint32_t)packet_etx * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE; - } else { - /* We don't have a valid link metric, set it to the current packet's ETX */ - new_etx = packet_etx; - /* Set link metric as valid */ - p->flags |= RPL_PARENT_FLAG_LINK_METRIC_VALID; - } - - PRINTF("RPL: ETX changed from %u to %u (packet ETX = %u)\n", - (unsigned)(recorded_etx / RPL_DAG_MC_ETX_DIVISOR), - (unsigned)(new_etx / RPL_DAG_MC_ETX_DIVISOR), - (unsigned)(packet_etx / RPL_DAG_MC_ETX_DIVISOR)); - /* update the link metric for this nbr */ - nbr->link_metric = new_etx; - } -} - -static rpl_rank_t -calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank) -{ - rpl_rank_t new_rank; - rpl_rank_t rank_increase; - uip_ds6_nbr_t *nbr; - - if(p == NULL || (nbr = rpl_get_nbr(p)) == NULL) { - if(base_rank == 0) { - return INFINITE_RANK; - } - rank_increase = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR; - } else { - rank_increase = nbr->link_metric; - if(base_rank == 0) { - base_rank = p->rank; - } - } - - if(INFINITE_RANK - base_rank < rank_increase) { - /* Reached the maximum rank. */ - new_rank = INFINITE_RANK; - } else { - /* Calculate the rank based on the new rank information from DIO or - stored otherwise. */ - new_rank = base_rank + rank_increase; - } - - return new_rank; -} - -static rpl_dag_t * -best_dag(rpl_dag_t *d1, rpl_dag_t *d2) -{ - if(d1->grounded != d2->grounded) { - return d1->grounded ? d1 : d2; - } - - if(d1->preference != d2->preference) { - return d1->preference > d2->preference ? d1 : d2; - } - - return d1->rank < d2->rank ? d1 : d2; -} - -static rpl_parent_t * -best_parent(rpl_parent_t *p1, rpl_parent_t *p2) -{ - rpl_dag_t *dag; - rpl_path_metric_t min_diff; - rpl_path_metric_t p1_metric; - rpl_path_metric_t p2_metric; - - dag = p1->dag; /* Both parents are in the same DAG. */ - - min_diff = RPL_DAG_MC_ETX_DIVISOR / - PARENT_SWITCH_THRESHOLD_DIV; - - p1_metric = calculate_path_metric(p1); - p2_metric = calculate_path_metric(p2); - - /* Maintain stability of the preferred parent in case of similar ranks. */ - if(p1 == dag->preferred_parent || p2 == dag->preferred_parent) { - if(p1_metric < p2_metric + min_diff && - p1_metric > p2_metric - min_diff) { - PRINTF("RPL: MRHOF hysteresis: %u <= %u <= %u\n", - p2_metric - min_diff, - p1_metric, - p2_metric + min_diff); - return dag->preferred_parent; - } - } - - return p1_metric < p2_metric ? p1 : p2; -} - -#if RPL_DAG_MC == RPL_DAG_MC_NONE -static void -update_metric_container(rpl_instance_t *instance) -{ - instance->mc.type = RPL_DAG_MC; -} -#else -static void -update_metric_container(rpl_instance_t *instance) -{ - rpl_path_metric_t path_metric; - rpl_dag_t *dag; -#if RPL_DAG_MC == RPL_DAG_MC_ENERGY - uint8_t type; -#endif - - instance->mc.type = RPL_DAG_MC; - instance->mc.flags = RPL_DAG_MC_FLAG_P; - instance->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE; - instance->mc.prec = 0; - - dag = instance->current_dag; - - if (!dag->joined) { - PRINTF("RPL: Cannot update the metric container when not joined\n"); - return; - } - - if(dag->rank == ROOT_RANK(instance)) { - path_metric = 0; - } else { - path_metric = calculate_path_metric(dag->preferred_parent); - } - -#if RPL_DAG_MC == RPL_DAG_MC_ETX - instance->mc.length = sizeof(instance->mc.obj.etx); - instance->mc.obj.etx = path_metric; - - PRINTF("RPL: My path ETX to the root is %u.%u\n", - instance->mc.obj.etx / RPL_DAG_MC_ETX_DIVISOR, - (instance->mc.obj.etx % RPL_DAG_MC_ETX_DIVISOR * 100) / - RPL_DAG_MC_ETX_DIVISOR); -#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY - instance->mc.length = sizeof(instance->mc.obj.energy); - - if(dag->rank == ROOT_RANK(instance)) { - type = RPL_DAG_MC_ENERGY_TYPE_MAINS; - } else { - type = RPL_DAG_MC_ENERGY_TYPE_BATTERY; - } - - instance->mc.obj.energy.flags = type << RPL_DAG_MC_ENERGY_TYPE; - instance->mc.obj.energy.energy_est = path_metric; -#endif /* RPL_DAG_MC == RPL_DAG_MC_ETX */ -} -#endif /* RPL_DAG_MC == RPL_DAG_MC_NONE */ - -/** @}*/ diff --git a/net/ip/contiki/rpl/rpl-of0.c b/net/ip/contiki/rpl/rpl-of0.c deleted file mode 100644 index f4d596b2239b3342b8efbfabd5eae85ebc9b7303..0000000000000000000000000000000000000000 --- a/net/ip/contiki/rpl/rpl-of0.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * An implementation of RPL's objective function 0. - * - * \author Joakim Eriksson , Nicolas Tsiftes - */ - -/** - * \addtogroup uip6 - * @{ - */ - -#include "contiki/rpl/rpl-private.h" - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_RPL_OF -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -static void reset(rpl_dag_t *); -static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *); -static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *); -static rpl_rank_t calculate_rank(rpl_parent_t *, rpl_rank_t); -static void update_metric_container(rpl_instance_t *); - -rpl_of_t rpl_of0 = { - reset, - NULL, - best_parent, - best_dag, - calculate_rank, - update_metric_container, - 0 -}; - -#define DEFAULT_RANK_INCREMENT RPL_MIN_HOPRANKINC - -#define MIN_DIFFERENCE (RPL_MIN_HOPRANKINC + RPL_MIN_HOPRANKINC / 2) - -static void -reset(rpl_dag_t *dag) -{ - PRINTF("RPL: Resetting OF0\n"); -} - -static rpl_rank_t -calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank) -{ - rpl_rank_t increment; - if(base_rank == 0) { - if(p == NULL) { - return INFINITE_RANK; - } - base_rank = p->rank; - } - - increment = p != NULL ? - p->dag->instance->min_hoprankinc : - DEFAULT_RANK_INCREMENT; - - if((rpl_rank_t)(base_rank + increment) < base_rank) { - PRINTF("RPL: OF0 rank %d incremented to infinite rank due to wrapping\n", - base_rank); - return INFINITE_RANK; - } - return base_rank + increment; - -} - -static rpl_dag_t * -best_dag(rpl_dag_t *d1, rpl_dag_t *d2) -{ - if(d1->grounded) { - if (!d2->grounded) { - return d1; - } - } else if(d2->grounded) { - return d2; - } - - if(d1->preference < d2->preference) { - return d2; - } else { - if(d1->preference > d2->preference) { - return d1; - } - } - - if(d2->rank < d1->rank) { - return d2; - } else { - return d1; - } -} - -static rpl_parent_t * -best_parent(rpl_parent_t *p1, rpl_parent_t *p2) -{ - rpl_rank_t r1, r2; - rpl_dag_t *dag; - uip_ds6_nbr_t *nbr1, *nbr2; - nbr1 = rpl_get_nbr(p1); - nbr2 = rpl_get_nbr(p2); - - dag = (rpl_dag_t *)p1->dag; /* Both parents must be in the same DAG. */ - - if(nbr1 == NULL || nbr2 == NULL) { - return dag->preferred_parent; - } - - PRINTF("RPL: Comparing parent "); - PRINT6ADDR(rpl_get_parent_ipaddr(p1)); - PRINTF(" (confidence %d, rank %d) with parent ", - nbr1->link_metric, p1->rank); - PRINT6ADDR(rpl_get_parent_ipaddr(p2)); - PRINTF(" (confidence %d, rank %d)\n", - nbr2->link_metric, p2->rank); - - - r1 = DAG_RANK(p1->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC + - nbr1->link_metric; - r2 = DAG_RANK(p2->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC + - nbr2->link_metric; - /* Compare two parents by looking both and their rank and at the ETX - for that parent. We choose the parent that has the most - favourable combination. */ - - if(r1 < r2 + MIN_DIFFERENCE && - r1 > r2 - MIN_DIFFERENCE) { - return dag->preferred_parent; - } else if(r1 < r2) { - return p1; - } else { - return p2; - } -} - -static void -update_metric_container(rpl_instance_t *instance) -{ - instance->mc.type = RPL_DAG_MC_NONE; -} - -/** @}*/ diff --git a/net/ip/contiki/rpl/rpl-private.h b/net/ip/contiki/rpl/rpl-private.h deleted file mode 100644 index 7a7dcf09b445410d05e0045597e1a1ee9bb491bb..0000000000000000000000000000000000000000 --- a/net/ip/contiki/rpl/rpl-private.h +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * \file - * Private declarations for ContikiRPL. - * \author - * Joakim Eriksson , Nicolas Tsiftes - */ - -#ifndef RPL_PRIVATE_H -#define RPL_PRIVATE_H - -#include "contiki/rpl/rpl.h" - -#include "lib/list.h" -#include "contiki/ip/uip.h" -#include "sys/clock.h" -#include "sys/ctimer.h" -#include "contiki/ipv6/uip-ds6.h" -#include "contiki/ipv6/multicast/uip-mcast6.h" - -/*---------------------------------------------------------------------------*/ -/** \brief Is IPv6 address addr the link-local, all-RPL-nodes - multicast address? */ -#define uip_is_addr_linklocal_rplnodes_mcast(addr) \ - ((addr)->u8[0] == 0xff) && \ - ((addr)->u8[1] == 0x02) && \ - ((addr)->u16[1] == 0) && \ - ((addr)->u16[2] == 0) && \ - ((addr)->u16[3] == 0) && \ - ((addr)->u16[4] == 0) && \ - ((addr)->u16[5] == 0) && \ - ((addr)->u16[6] == 0) && \ - ((addr)->u8[14] == 0) && \ - ((addr)->u8[15] == 0x1a)) - -/** \brief Set IP address addr to the link-local, all-rpl-nodes - multicast address. */ -#define uip_create_linklocal_rplnodes_mcast(addr) \ - uip_ip6addr((addr), 0xff02, 0, 0, 0, 0, 0, 0, 0x001a) -/*---------------------------------------------------------------------------*/ -/* RPL message types */ -#define RPL_CODE_DIS 0x00 /* DAG Information Solicitation */ -#define RPL_CODE_DIO 0x01 /* DAG Information Option */ -#define RPL_CODE_DAO 0x02 /* Destination Advertisement Option */ -#define RPL_CODE_DAO_ACK 0x03 /* DAO acknowledgment */ -#define RPL_CODE_SEC_DIS 0x80 /* Secure DIS */ -#define RPL_CODE_SEC_DIO 0x81 /* Secure DIO */ -#define RPL_CODE_SEC_DAO 0x82 /* Secure DAO */ -#define RPL_CODE_SEC_DAO_ACK 0x83 /* Secure DAO ACK */ - -/* RPL control message options. */ -#define RPL_OPTION_PAD1 0 -#define RPL_OPTION_PADN 1 -#define RPL_OPTION_DAG_METRIC_CONTAINER 2 -#define RPL_OPTION_ROUTE_INFO 3 -#define RPL_OPTION_DAG_CONF 4 -#define RPL_OPTION_TARGET 5 -#define RPL_OPTION_TRANSIT 6 -#define RPL_OPTION_SOLICITED_INFO 7 -#define RPL_OPTION_PREFIX_INFO 8 -#define RPL_OPTION_TARGET_DESC 9 - -#define RPL_DAO_K_FLAG 0x80 /* DAO ACK requested */ -#define RPL_DAO_D_FLAG 0x40 /* DODAG ID present */ -/*---------------------------------------------------------------------------*/ -/* RPL IPv6 extension header option. */ -#define RPL_HDR_OPT_LEN 4 -#define RPL_HOP_BY_HOP_LEN (RPL_HDR_OPT_LEN + 2 + 2) -#define RPL_HDR_OPT_DOWN 0x80 -#define RPL_HDR_OPT_DOWN_SHIFT 7 -#define RPL_HDR_OPT_RANK_ERR 0x40 -#define RPL_HDR_OPT_RANK_ERR_SHIFT 6 -#define RPL_HDR_OPT_FWD_ERR 0x20 -#define RPL_HDR_OPT_FWD_ERR_SHIFT 5 -/*---------------------------------------------------------------------------*/ -/* Default values for RPL constants and variables. */ - -/* The default value for the DAO timer. */ -#ifdef RPL_CONF_DAO_LATENCY -#define RPL_DAO_LATENCY RPL_CONF_DAO_LATENCY -#else /* RPL_CONF_DAO_LATENCY */ -#define RPL_DAO_LATENCY (CLOCK_SECOND * 4) -#endif /* RPL_DAO_LATENCY */ - -/* Special value indicating immediate removal. */ -#define RPL_ZERO_LIFETIME 0 - -#define RPL_LIFETIME(instance, lifetime) \ - ((unsigned long)(instance)->lifetime_unit * (lifetime)) - -#ifndef RPL_CONF_MIN_HOPRANKINC -#define RPL_MIN_HOPRANKINC 256 -#else -#define RPL_MIN_HOPRANKINC RPL_CONF_MIN_HOPRANKINC -#endif -#define RPL_MAX_RANKINC (7 * RPL_MIN_HOPRANKINC) - -#define DAG_RANK(fixpt_rank, instance) \ - ((fixpt_rank) / (instance)->min_hoprankinc) - -/* Rank of a virtual root node that coordinates DAG root nodes. */ -#define BASE_RANK 0 - -/* Rank of a root node. */ -#define ROOT_RANK(instance) (instance)->min_hoprankinc - -#define INFINITE_RANK 0xffff - - -/* Expire DAOs from neighbors that do not respond in this time. (seconds) */ -#define DAO_EXPIRATION_TIMEOUT 60 -/*---------------------------------------------------------------------------*/ -#define RPL_INSTANCE_LOCAL_FLAG 0x80 -#define RPL_INSTANCE_D_FLAG 0x40 - -/* Values that tell where a route came from. */ -#define RPL_ROUTE_FROM_INTERNAL 0 -#define RPL_ROUTE_FROM_UNICAST_DAO 1 -#define RPL_ROUTE_FROM_MULTICAST_DAO 2 -#define RPL_ROUTE_FROM_DIO 3 - -/* DAG Mode of Operation */ -#define RPL_MOP_NO_DOWNWARD_ROUTES 0 -#define RPL_MOP_NON_STORING 1 -#define RPL_MOP_STORING_NO_MULTICAST 2 -#define RPL_MOP_STORING_MULTICAST 3 - -#ifdef RPL_CONF_MOP -#define RPL_MOP_DEFAULT RPL_CONF_MOP -#else /* RPL_CONF_MOP */ -#if RPL_CONF_MULTICAST -#define RPL_MOP_DEFAULT RPL_MOP_STORING_MULTICAST -#else -#define RPL_MOP_DEFAULT RPL_MOP_STORING_NO_MULTICAST -#endif /* UIP_IPV6_MULTICAST_RPL */ -#endif /* RPL_CONF_MOP */ - -/* Emit a pre-processor error if the user configured multicast with bad MOP */ -#if RPL_CONF_MULTICAST && (RPL_MOP_DEFAULT != RPL_MOP_STORING_MULTICAST) -#error "RPL Multicast requires RPL_MOP_DEFAULT==3. Check contiki-conf.h" -#endif - -/* Multicast Route Lifetime as a multiple of the lifetime unit */ -#ifdef RPL_CONF_MCAST_LIFETIME -#define RPL_MCAST_LIFETIME RPL_CONF_MCAST_LIFETIME -#else -#define RPL_MCAST_LIFETIME 3 -#endif - -/* - * The ETX in the metric container is expressed as a fixed-point value - * whose integer part can be obtained by dividing the value by - * RPL_DAG_MC_ETX_DIVISOR. - */ -#define RPL_DAG_MC_ETX_DIVISOR 256 - -/* DIS related */ -#define RPL_DIS_SEND 1 -#ifdef RPL_DIS_INTERVAL_CONF -#define RPL_DIS_INTERVAL RPL_DIS_INTERVAL_CONF -#else -#define RPL_DIS_INTERVAL 60 -#endif -#define RPL_DIS_START_DELAY 5 -/*---------------------------------------------------------------------------*/ -/* Lollipop counters */ - -#define RPL_LOLLIPOP_MAX_VALUE 255 -#define RPL_LOLLIPOP_CIRCULAR_REGION 127 -#define RPL_LOLLIPOP_SEQUENCE_WINDOWS 16 -#define RPL_LOLLIPOP_INIT (RPL_LOLLIPOP_MAX_VALUE - RPL_LOLLIPOP_SEQUENCE_WINDOWS + 1) -#define RPL_LOLLIPOP_INCREMENT(counter) \ - do { \ - if((counter) > RPL_LOLLIPOP_CIRCULAR_REGION) { \ - (counter) = ((counter) + 1) & RPL_LOLLIPOP_MAX_VALUE; \ - } else { \ - (counter) = ((counter) + 1) & RPL_LOLLIPOP_CIRCULAR_REGION; \ - } \ - } while(0) - -#define RPL_LOLLIPOP_IS_INIT(counter) \ - ((counter) > RPL_LOLLIPOP_CIRCULAR_REGION) -/*---------------------------------------------------------------------------*/ -/* Logical representation of a DAG Information Object (DIO.) */ -struct rpl_dio { - uip_ipaddr_t dag_id; - rpl_ocp_t ocp; - rpl_rank_t rank; - uint8_t grounded; - uint8_t mop; - uint8_t preference; - uint8_t version; - uint8_t instance_id; - uint8_t dtsn; - uint8_t dag_intdoubl; - uint8_t dag_intmin; - uint8_t dag_redund; - uint8_t default_lifetime; - uint16_t lifetime_unit; - rpl_rank_t dag_max_rankinc; - rpl_rank_t dag_min_hoprankinc; - rpl_prefix_t destination_prefix; - rpl_prefix_t prefix_info; - struct rpl_metric_container mc; -}; -typedef struct rpl_dio rpl_dio_t; - -/* Callback for evaluating if this is a network to join or not */ -typedef int (*join_callback_t) (rpl_dio_t* dio); -void rpl_set_join_callback(join_callback_t callback); - -#if RPL_CONF_STATS -/* Statistics for fault management. */ -struct rpl_stats { - uint16_t mem_overflows; - uint16_t local_repairs; - uint16_t global_repairs; - uint16_t malformed_msgs; - uint16_t resets; - uint16_t parent_switch; - uint16_t forward_errors; - uint16_t loop_errors; - uint16_t loop_warnings; - uint16_t root_repairs; -}; -typedef struct rpl_stats rpl_stats_t; - -extern rpl_stats_t rpl_stats; -#endif -/*---------------------------------------------------------------------------*/ -/* RPL macros. */ - -#if RPL_CONF_STATS -#define RPL_STAT(code) (code) -#else -#define RPL_STAT(code) -#endif /* RPL_CONF_STATS */ -/*---------------------------------------------------------------------------*/ -/* Instances */ -extern rpl_instance_t instance_table[]; -extern rpl_instance_t *default_instance; - -/* ICMPv6 functions for RPL. */ -void dis_output(struct net_buf *buf, uip_ipaddr_t *addr); -void dio_output(rpl_instance_t *, uip_ipaddr_t *uc_addr); -void dao_output(rpl_parent_t *, uint8_t lifetime); -void dao_output_target(rpl_parent_t *, uip_ipaddr_t *, uint8_t lifetime); -void dao_ack_output(struct net_buf *buf, rpl_instance_t *, uip_ipaddr_t *, uint8_t); -void rpl_icmp6_register_handlers(void); - -/* RPL logic functions. */ -void rpl_join_dag(uip_ipaddr_t *from, rpl_dio_t *dio); -void rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio); -void rpl_local_repair(rpl_instance_t *instance); -void rpl_process_dio(uip_ipaddr_t *, rpl_dio_t *); -int rpl_process_parent_event(rpl_instance_t *, rpl_parent_t *); - -/* DAG object management. */ -rpl_dag_t *rpl_alloc_dag(uint8_t, uip_ipaddr_t *); -rpl_instance_t *rpl_alloc_instance(uint8_t); -void rpl_free_dag(rpl_dag_t *); -void rpl_free_instance(rpl_instance_t *); - -/* DAG parent management function. */ -rpl_parent_t *rpl_add_parent(rpl_dag_t *, rpl_dio_t *dio, uip_ipaddr_t *); -rpl_parent_t *rpl_find_parent(rpl_dag_t *, uip_ipaddr_t *); -rpl_parent_t *rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr); -void rpl_nullify_parent(rpl_parent_t *); -void rpl_remove_parent(rpl_parent_t *); -void rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent); -rpl_parent_t *rpl_select_parent(rpl_dag_t *dag); -rpl_dag_t *rpl_select_dag(rpl_instance_t *instance,rpl_parent_t *parent); -void rpl_recalculate_ranks(void); - -/* RPL routing table functions. */ -void rpl_remove_routes(rpl_dag_t *dag); -void rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag); -uip_ds6_route_t *rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, - int prefix_len, uip_ipaddr_t *next_hop); -void rpl_purge_routes(void); - -/* Lock a parent in the neighbor cache. */ -void rpl_lock_parent(rpl_parent_t *p); - -/* Objective function. */ -rpl_of_t *rpl_find_of(rpl_ocp_t); - -/* Timer functions. */ -void rpl_schedule_dao(rpl_instance_t *); -void rpl_schedule_dao_immediately(rpl_instance_t *); -void rpl_cancel_dao(rpl_instance_t *instance); -void rpl_schedule_probing(rpl_instance_t *instance); - -void rpl_reset_dio_timer(rpl_instance_t *); -void rpl_reset_periodic_timer(void); - -/* Route poisoning. */ -void rpl_poison_routes(rpl_dag_t *, rpl_parent_t *); - -rpl_instance_t *rpl_get_default_instance(void); - -#endif /* RPL_PRIVATE_H */ diff --git a/net/ip/contiki/rpl/rpl-timers.c b/net/ip/contiki/rpl/rpl-timers.c deleted file mode 100644 index 80b6cd7dac84308ed930a43289d75f535ceacdca..0000000000000000000000000000000000000000 --- a/net/ip/contiki/rpl/rpl-timers.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * RPL timer management. - * - * \author Joakim Eriksson , Nicolas Tsiftes - */ - -/** - * \addtogroup uip6 - * @{ - */ - -#include "contiki-conf.h" -#include "contiki/rpl/rpl-private.h" -#include "contiki/ipv6/multicast/uip-mcast6.h" -#include "lib/random.h" -#include "sys/ctimer.h" - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_RPL_TIMERS -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -/*---------------------------------------------------------------------------*/ -static struct ctimer periodic_timer; - -static void handle_periodic_timer(struct net_buf *mbuf, void *ptr); -static void new_dio_interval(rpl_instance_t *instance); -static void handle_dio_timer(struct net_buf *mbuf, void *ptr); - -static uint16_t next_dis; - -/* dio_send_ok is true if the node is ready to send DIOs */ -static uint8_t dio_send_ok; - -/*---------------------------------------------------------------------------*/ -static void -handle_periodic_timer(struct net_buf *not_used, void *ptr) -{ - rpl_purge_routes(); - rpl_recalculate_ranks(); - - /* handle DIS */ -#if RPL_DIS_SEND - next_dis++; - if(rpl_get_any_dag() == NULL && next_dis >= RPL_DIS_INTERVAL) { - next_dis = 0; - dis_output(NULL, NULL); - } -#endif - ctimer_reset(&periodic_timer); -} -/*---------------------------------------------------------------------------*/ -static void -new_dio_interval(rpl_instance_t *instance) -{ - uint32_t time; - clock_time_t ticks; - - /* TODO: too small timer intervals for many cases */ - time = 1UL << instance->dio_intcurrent; - - /* Convert from milliseconds to CLOCK_TICKS. */ - ticks = (time * CLOCK_SECOND) / 1000; - instance->dio_next_delay = ticks; - - /* random number between I/2 and I */ - ticks = ticks / 2 + (ticks / 2 * (uint32_t)random_rand()) / RANDOM_RAND_MAX; - - /* - * The intervals must be equally long among the nodes for Trickle to - * operate efficiently. Therefore we need to calculate the delay between - * the randomized time and the start time of the next interval. - */ - instance->dio_next_delay -= ticks; - instance->dio_send = 1; - -#if RPL_CONF_STATS - /* keep some stats */ - instance->dio_totint++; - instance->dio_totrecv += instance->dio_counter; - ANNOTATE("#A rank=%u.%u(%u),stats=%d %d %d %d,color=%s\n", - DAG_RANK(instance->current_dag->rank, instance), - (10 * (instance->current_dag->rank % instance->min_hoprankinc)) / instance->min_hoprankinc, - instance->current_dag->version, - instance->dio_totint, instance->dio_totsend, - instance->dio_totrecv,instance->dio_intcurrent, - instance->current_dag->rank == ROOT_RANK(instance) ? "BLUE" : "ORANGE"); -#endif /* RPL_CONF_STATS */ - - /* reset the redundancy counter */ - instance->dio_counter = 0; - - /* schedule the timer */ - PRINTF("RPL: Scheduling DIO timer %lu ticks in future (Interval)\n", ticks); - ctimer_set(NULL, &instance->dio_timer, ticks, &handle_dio_timer, instance); -} -/*---------------------------------------------------------------------------*/ -static void -handle_dio_timer(struct net_buf *not_used, void *ptr) -{ - rpl_instance_t *instance; - - instance = (rpl_instance_t *)ptr; - - PRINTF("RPL: DIO Timer triggered\n"); - if(!dio_send_ok) { - if(uip_ds6_get_link_local(ADDR_PREFERRED) != NULL) { - dio_send_ok = 1; - } else { - PRINTF("RPL: Postponing DIO transmission since link local address is not ok\n"); - ctimer_set(NULL, &instance->dio_timer, CLOCK_SECOND, &handle_dio_timer, - instance); - return; - } - } - - if(instance->dio_send) { - /* send DIO if counter is less than desired redundancy */ - if(instance->dio_redundancy != 0 && instance->dio_counter < instance->dio_redundancy) { -#if RPL_CONF_STATS - instance->dio_totsend++; -#endif /* RPL_CONF_STATS */ - dio_output(instance, NULL); - } else { - PRINTF("RPL: Supressing DIO transmission (%d >= %d)\n", - instance->dio_counter, instance->dio_redundancy); - } - instance->dio_send = 0; - PRINTF("RPL: Scheduling DIO timer %lu ticks in future (sent)\n", - instance->dio_next_delay); - ctimer_set(NULL, &instance->dio_timer, instance->dio_next_delay, - handle_dio_timer, instance); - } else { - /* check if we need to double interval */ - if(instance->dio_intcurrent < instance->dio_intmin + instance->dio_intdoubl) { - instance->dio_intcurrent++; - PRINTF("RPL: DIO Timer interval doubled %d\n", instance->dio_intcurrent); - } - new_dio_interval(instance); - } - -#if DEBUG - rpl_print_neighbor_list(); -#endif -} -/*---------------------------------------------------------------------------*/ -void -rpl_reset_periodic_timer() -{ - next_dis = RPL_DIS_INTERVAL / 2 + - ((uint32_t)RPL_DIS_INTERVAL * (uint32_t)random_rand()) / RANDOM_RAND_MAX - - RPL_DIS_START_DELAY; - ctimer_set(NULL, &periodic_timer, CLOCK_SECOND, handle_periodic_timer, NULL); -} -/*---------------------------------------------------------------------------*/ -/* Resets the DIO timer in the instance to its minimal interval. */ -void -rpl_reset_dio_timer(rpl_instance_t *instance) -{ -#if !RPL_LEAF_ONLY - /* Do not reset if we are already on the minimum interval, - unless forced to do so. */ - if(instance->dio_intcurrent > instance->dio_intmin) { - instance->dio_counter = 0; - instance->dio_intcurrent = instance->dio_intmin; - new_dio_interval(instance); - } -#if RPL_CONF_STATS - rpl_stats.resets++; -#endif /* RPL_CONF_STATS */ -#endif /* RPL_LEAF_ONLY */ -} -/*---------------------------------------------------------------------------*/ -static void handle_dao_timer(struct net_buf *mbuf, void *ptr); -static void -set_dao_lifetime_timer(rpl_instance_t *instance) -{ - if(rpl_get_mode() == RPL_MODE_FEATHER) { - return; - } - - /* Set up another DAO within half the expiration time, if such a - time has been configured */ - if(instance->lifetime_unit != 0xffff && instance->default_lifetime != 0xff) { - clock_time_t expiration_time; - expiration_time = (clock_time_t)instance->default_lifetime * - (clock_time_t)instance->lifetime_unit * - CLOCK_SECOND / 2; - PRINTF("RPL: Scheduling DAO lifetime timer %u ticks in the future\n", - (unsigned)expiration_time); - ctimer_set(NULL, &instance->dao_lifetime_timer, expiration_time, - handle_dao_timer, instance); - } -} -/*---------------------------------------------------------------------------*/ -static void -handle_dao_timer(struct net_buf *not_used, void *ptr) -{ - rpl_instance_t *instance; -#if RPL_CONF_MULTICAST - uip_mcast6_route_t *mcast_route; - uint8_t i; -#endif - - instance = (rpl_instance_t *)ptr; - - if(!dio_send_ok && uip_ds6_get_link_local(ADDR_PREFERRED) == NULL) { - PRINTF("RPL: Postpone DAO transmission\n"); - ctimer_set(NULL, &instance->dao_timer, CLOCK_SECOND, handle_dao_timer, instance); - return; - } - - /* Send the DAO to the DAO parent set -- the preferred parent in our case. */ - if(instance->current_dag->preferred_parent != NULL) { - PRINTF("RPL: handle_dao_timer - sending DAO\n"); - /* Set the route lifetime to the default value. */ - dao_output(instance->current_dag->preferred_parent, - instance->default_lifetime); - -#if RPL_CONF_MULTICAST - /* Send DAOs for multicast prefixes only if the instance is in MOP 3 */ - if(instance->mop == RPL_MOP_STORING_MULTICAST) { - /* Send a DAO for own multicast addresses */ - for(i = 0; i < UIP_DS6_MADDR_NB; i++) { - if(uip_ds6_if.maddr_list[i].isused - && uip_is_addr_mcast_global(&uip_ds6_if.maddr_list[i].ipaddr)) { - dao_output_target(instance->current_dag->preferred_parent, - &uip_ds6_if.maddr_list[i].ipaddr, - RPL_MCAST_LIFETIME); - } - } - - /* Iterate over multicast routes and send DAOs */ - mcast_route = uip_mcast6_route_list_head(); - while(mcast_route != NULL) { - /* Don't send if it's also our own address, done that already */ - if(uip_ds6_maddr_lookup(&mcast_route->group) == NULL) { - dao_output_target(instance->current_dag->preferred_parent, - &mcast_route->group, RPL_MCAST_LIFETIME); - } - mcast_route = list_item_next(mcast_route); - } - } -#endif - } else { - PRINTF("RPL: No suitable DAO parent\n"); - } - - ctimer_stop(&instance->dao_timer); - - if(etimer_expired(&instance->dao_lifetime_timer.etimer)) { - set_dao_lifetime_timer(instance); - } -} -/*---------------------------------------------------------------------------*/ -static void -schedule_dao(rpl_instance_t *instance, clock_time_t latency) -{ - clock_time_t expiration_time; - - if(rpl_get_mode() == RPL_MODE_FEATHER) { - return; - } - - expiration_time = etimer_expiration_time(&instance->dao_timer.etimer); - - if(!etimer_expired(&instance->dao_timer.etimer)) { - PRINTF("RPL: DAO timer already scheduled\n"); - } else { - if(latency != 0) { - expiration_time = latency / 2 + - (random_rand() % (latency)); - } else { - expiration_time = 0; - } - PRINTF("RPL: Scheduling DAO timer %u ticks in the future\n", - (unsigned)expiration_time); - ctimer_set(NULL, &instance->dao_timer, expiration_time, - handle_dao_timer, instance); - - set_dao_lifetime_timer(instance); - } -} -/*---------------------------------------------------------------------------*/ -void -rpl_schedule_dao(rpl_instance_t *instance) -{ - schedule_dao(instance, RPL_DAO_LATENCY); -} -/*---------------------------------------------------------------------------*/ -void -rpl_schedule_dao_immediately(rpl_instance_t *instance) -{ - schedule_dao(instance, 0); -} -/*---------------------------------------------------------------------------*/ -void -rpl_cancel_dao(rpl_instance_t *instance) -{ - ctimer_stop(&instance->dao_timer); - ctimer_stop(&instance->dao_lifetime_timer); -} -/*---------------------------------------------------------------------------*/ -#if RPL_WITH_PROBING -static rpl_parent_t * -get_probing_target(rpl_dag_t *dag) -{ - /* Returns the next probing target. The current implementation probes the current - * preferred parent if we have not updated its link for RPL_PROBING_EXPIRATION_TIME. - * Otherwise, it picks at random between: - * (1) selecting the best parent not updated for RPL_PROBING_EXPIRATION_TIME - * (2) selecting the least recently updated parent - */ - - rpl_parent_t *p; - rpl_parent_t *probing_target = NULL; - rpl_rank_t probing_target_rank = INFINITE_RANK; - /* min_last_tx is the clock time RPL_PROBING_EXPIRATION_TIME in the past */ - clock_time_t min_last_tx = clock_time(); - min_last_tx = min_last_tx > 2 * RPL_PROBING_EXPIRATION_TIME - ? min_last_tx - RPL_PROBING_EXPIRATION_TIME : 1; - - if(dag == NULL || - dag->instance == NULL || - dag->preferred_parent == NULL) { - return NULL; - } - - /* Our preferred parent needs probing */ - if(dag->preferred_parent->last_tx_time < min_last_tx) { - probing_target = dag->preferred_parent; - } - - /* With 50% probability: probe best parent not updated for RPL_PROBING_EXPIRATION_TIME */ - if(probing_target == NULL && (random_rand() % 2) == 0) { - p = nbr_table_head(rpl_parents); - while(p != NULL) { - if(p->dag == dag && p->last_tx_time < min_last_tx) { - /* p is in our dag and needs probing */ - rpl_rank_t p_rank = dag->instance->of->calculate_rank(p, 0); - if(probing_target == NULL - || p_rank < probing_target_rank) { - probing_target = p; - probing_target_rank = p_rank; - } - } - p = nbr_table_next(rpl_parents, p); - } - } - - /* The default probing target is the least recently updated parent */ - if(probing_target == NULL) { - p = nbr_table_head(rpl_parents); - while(p != NULL) { - if(p->dag == dag) { - if(probing_target == NULL - || p->last_tx_time < probing_target->last_tx_time) { - probing_target = p; - } - } - p = nbr_table_next(rpl_parents, p); - } - } - - return probing_target; -} -/*---------------------------------------------------------------------------*/ -static void -handle_probing_timer(struct net_buf *not_used, void *ptr) -{ - rpl_instance_t *instance = (rpl_instance_t *)ptr; - rpl_parent_t *probing_target = RPL_PROBING_SELECT_FUNC(instance->current_dag); - - /* Perform probing */ - if(probing_target != NULL && rpl_get_parent_ipaddr(probing_target) != NULL) { - PRINTF("RPL: probing %3u\n", - nbr_table_get_lladdr(rpl_parents, probing_target)->u8[7]); - /* Send probe, e.g. unicast DIO or DIS */ - RPL_PROBING_SEND_FUNC(instance, rpl_get_parent_ipaddr(probing_target)); - } - - /* Schedule next probing */ - rpl_schedule_probing(instance); - -#if DEBUG - rpl_print_neighbor_list(); -#endif -} -/*---------------------------------------------------------------------------*/ -void -rpl_schedule_probing(rpl_instance_t *instance) -{ - ctimer_set(NULL, &instance->probing_timer, RPL_PROBING_DELAY_FUNC(), - handle_probing_timer, instance); -} -#endif /* RPL_WITH_PROBING */ -/** @}*/ diff --git a/net/ip/contiki/rpl/rpl.c b/net/ip/contiki/rpl/rpl.c deleted file mode 100644 index c4eb5cbb70e6cccf572333c62327b2a28e885eb2..0000000000000000000000000000000000000000 --- a/net/ip/contiki/rpl/rpl.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (c) 2009, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ContikiRPL, an implementation of RPL: IPv6 Routing Protocol - * for Low-Power and Lossy Networks (IETF RFC 6550) - * - * \author Joakim Eriksson , Nicolas Tsiftes - */ - -/** - * \addtogroup uip6 - * @{ - */ - -#include "contiki/ip/uip.h" -#include "contiki/ip/tcpip.h" -#include "contiki/ipv6/uip-ds6.h" -#include "contiki/ipv6/uip-icmp6.h" -#include "contiki/rpl/rpl-private.h" -#include "contiki/ipv6/multicast/uip-mcast6.h" - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_RPL -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#include -#include - -#if RPL_CONF_STATS -rpl_stats_t rpl_stats; -#endif - -static enum rpl_mode mode = RPL_MODE_MESH; -/*---------------------------------------------------------------------------*/ -enum rpl_mode -rpl_get_mode(void) -{ - return mode; -} -/*---------------------------------------------------------------------------*/ -enum rpl_mode -rpl_set_mode(enum rpl_mode m) -{ - enum rpl_mode oldmode = mode; - - /* We need to do different things depending on what mode we are - switching to. */ - if(m == RPL_MODE_MESH) { - - /* If we switch to mesh mode, we should send out a DAO message to - inform our parent that we now are reachable. Before we do this, - we must set the mode variable, since DAOs will not be sent if - we are in feather mode. */ - PRINTF("RPL: switching to mesh mode\n"); - mode = m; - - if(default_instance != NULL) { - rpl_schedule_dao_immediately(default_instance); - } - } else if(m == RPL_MODE_FEATHER) { - - PRINTF("RPL: switching to feather mode\n"); - mode = m; - if(default_instance != NULL) { - rpl_cancel_dao(default_instance); - } - - } else { - mode = m; - } - - return oldmode; -} -/*---------------------------------------------------------------------------*/ -void -rpl_purge_routes(void) -{ - uip_ds6_route_t *r; - uip_ipaddr_t prefix; - rpl_dag_t *dag; -#if RPL_CONF_MULTICAST - uip_mcast6_route_t *mcast_route; -#endif - - /* First pass, decrement lifetime */ - r = uip_ds6_route_head(); - - while(r != NULL) { - if(r->state.lifetime >= 1) { - /* - * If a route is at lifetime == 1, set it to 0, scheduling it for - * immediate removal below. This achieves the same as the original code, - * which would delete lifetime <= 1 - */ - r->state.lifetime--; - } - r = uip_ds6_route_next(r); - } - - /* Second pass, remove dead routes */ - r = uip_ds6_route_head(); - - while(r != NULL) { - if(r->state.lifetime < 1) { - /* Routes with lifetime == 1 have only just been decremented from 2 to 1, - * thus we want to keep them. Hence < and not <= */ - uip_ipaddr_copy(&prefix, &r->ipaddr); - uip_ds6_route_rm(r); - r = uip_ds6_route_head(); - PRINTF("No more routes to "); - PRINT6ADDR(&prefix); - dag = default_instance->current_dag; - /* Propagate this information with a No-Path DAO to preferred parent if we are not a RPL Root */ - if(dag->rank != ROOT_RANK(default_instance)) { - PRINTF(" -> generate No-Path DAO\n"); - dao_output_target(dag->preferred_parent, &prefix, RPL_ZERO_LIFETIME); - /* Don't schedule more than 1 No-Path DAO, let next iteration handle that */ - return; - } - PRINTF("\n"); - } else { - r = uip_ds6_route_next(r); - } - } - -#if RPL_CONF_MULTICAST - mcast_route = uip_mcast6_route_list_head(); - - while(mcast_route != NULL) { - if(mcast_route->lifetime <= 1) { - uip_mcast6_route_rm(mcast_route); - mcast_route = uip_mcast6_route_list_head(); - } else { - mcast_route->lifetime--; - mcast_route = list_item_next(mcast_route); - } - } -#endif -} -/*---------------------------------------------------------------------------*/ -void -rpl_remove_routes(rpl_dag_t *dag) -{ - uip_ds6_route_t *r; -#if RPL_CONF_MULTICAST - uip_mcast6_route_t *mcast_route; -#endif - - r = uip_ds6_route_head(); - - while(r != NULL) { - if(r->state.dag == dag) { - uip_ds6_route_rm(r); - r = uip_ds6_route_head(); - } else { - r = uip_ds6_route_next(r); - } - } - -#if RPL_CONF_MULTICAST - mcast_route = uip_mcast6_route_list_head(); - - while(mcast_route != NULL) { - if(mcast_route->dag == dag) { - uip_mcast6_route_rm(mcast_route); - mcast_route = uip_mcast6_route_list_head(); - } else { - mcast_route = list_item_next(mcast_route); - } - } -#endif -} -/*---------------------------------------------------------------------------*/ -void -rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag) -{ - uip_ds6_route_t *r; - - r = uip_ds6_route_head(); - - while(r != NULL) { - if(uip_ipaddr_cmp(uip_ds6_route_nexthop(r), nexthop) && - r->state.dag == dag) { - uip_ds6_route_rm(r); - r = uip_ds6_route_head(); - } else { - r = uip_ds6_route_next(r); - } - } - ANNOTATE("#L %u 0\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]); -} -/*---------------------------------------------------------------------------*/ -uip_ds6_route_t * -rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len, - uip_ipaddr_t *next_hop) -{ - uip_ds6_route_t *rep; - - if((rep = uip_ds6_route_add(prefix, prefix_len, next_hop)) == NULL) { - PRINTF("RPL: No space for more route entries\n"); - return NULL; - } - - rep->state.dag = dag; - rep->state.lifetime = RPL_LIFETIME(dag->instance, dag->instance->default_lifetime); - rep->state.learned_from = RPL_ROUTE_FROM_INTERNAL; - - PRINTF("RPL: Added a route to "); - PRINT6ADDR(prefix); - PRINTF("/%d via ", prefix_len); - PRINT6ADDR(next_hop); - PRINTF("\n"); - - return rep; -} -/*---------------------------------------------------------------------------*/ -void -rpl_link_neighbor_callback(const linkaddr_t *addr, int status, int numtx) -{ - uip_ipaddr_t ipaddr; - rpl_parent_t *parent; - rpl_instance_t *instance; - rpl_instance_t *end; - - uip_ip6addr(&ipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0); - uip_ds6_set_addr_iid(&ipaddr, (uip_lladdr_t *)addr); - - for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) { - if(instance->used == 1 ) { - parent = rpl_find_parent_any_dag(instance, &ipaddr); - if(parent != NULL) { - /* Trigger DAG rank recalculation. */ - PRINTF("RPL: rpl_link_neighbor_callback triggering update\n"); - parent->flags |= RPL_PARENT_FLAG_UPDATED; - if(instance->of->neighbor_link_callback != NULL) { - instance->of->neighbor_link_callback(parent, status, numtx); - parent->last_tx_time = clock_time(); - } - } - } - } -} -/*---------------------------------------------------------------------------*/ -void -rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr) -{ - rpl_parent_t *p; - rpl_instance_t *instance; - rpl_instance_t *end; - - PRINTF("RPL: Removing neighbor "); - PRINT6ADDR(&nbr->ipaddr); - PRINTF("\n"); - for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) { - if(instance->used == 1 ) { - p = rpl_find_parent_any_dag(instance, &nbr->ipaddr); - if(p != NULL) { - p->rank = INFINITE_RANK; - /* Trigger DAG rank recalculation. */ - PRINTF("RPL: rpl_ipv6_neighbor_callback infinite rank\n"); - p->flags |= RPL_PARENT_FLAG_UPDATED; - } - } - } -} -/*---------------------------------------------------------------------------*/ -void -rpl_init(void) -{ - uip_ipaddr_t rplmaddr; - PRINTF("RPL started\n"); - default_instance = NULL; - - rpl_dag_init(); - rpl_reset_periodic_timer(); - rpl_icmp6_register_handlers(); - - /* add rpl multicast address */ - uip_create_linklocal_rplnodes_mcast(&rplmaddr); - uip_ds6_maddr_add(&rplmaddr); - -#if RPL_CONF_STATS - memset(&rpl_stats, 0, sizeof(rpl_stats)); -#endif - - RPL_OF.reset(NULL); -} -/*---------------------------------------------------------------------------*/ - -/** @}*/ diff --git a/net/ip/contiki/rpl/rpl.h b/net/ip/contiki/rpl/rpl.h deleted file mode 100644 index c257742127dfe66c8dbaaba87d342a6951accb4e..0000000000000000000000000000000000000000 --- a/net/ip/contiki/rpl/rpl.h +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * \file - * Public API declarations for ContikiRPL. - * \author - * Joakim Eriksson & Nicolas Tsiftes - * - */ - -#ifndef RPL_H -#define RPL_H - -#include - -#include "rpl-conf.h" - -#include "lib/list.h" -#include "contiki/ip/uip.h" -#include "contiki/ipv6/uip-ds6.h" -#include "sys/ctimer.h" - -/*---------------------------------------------------------------------------*/ -typedef uint16_t rpl_rank_t; -typedef uint16_t rpl_ocp_t; -/*---------------------------------------------------------------------------*/ -/* DAG Metric Container Object Types, to be confirmed by IANA. */ -#define RPL_DAG_MC_NONE 0 /* Local identifier for empty MC */ -#define RPL_DAG_MC_NSA 1 /* Node State and Attributes */ -#define RPL_DAG_MC_ENERGY 2 /* Node Energy */ -#define RPL_DAG_MC_HOPCOUNT 3 /* Hop Count */ -#define RPL_DAG_MC_THROUGHPUT 4 /* Throughput */ -#define RPL_DAG_MC_LATENCY 5 /* Latency */ -#define RPL_DAG_MC_LQL 6 /* Link Quality Level */ -#define RPL_DAG_MC_ETX 7 /* Expected Transmission Count */ -#define RPL_DAG_MC_LC 8 /* Link Color */ - -/* DAG Metric Container flags. */ -#define RPL_DAG_MC_FLAG_P 0x8 -#define RPL_DAG_MC_FLAG_C 0x4 -#define RPL_DAG_MC_FLAG_O 0x2 -#define RPL_DAG_MC_FLAG_R 0x1 - -/* DAG Metric Container aggregation mode. */ -#define RPL_DAG_MC_AGGR_ADDITIVE 0 -#define RPL_DAG_MC_AGGR_MAXIMUM 1 -#define RPL_DAG_MC_AGGR_MINIMUM 2 -#define RPL_DAG_MC_AGGR_MULTIPLICATIVE 3 - -/* The bit index within the flags field of - the rpl_metric_object_energy structure. */ -#define RPL_DAG_MC_ENERGY_INCLUDED 3 -#define RPL_DAG_MC_ENERGY_TYPE 1 -#define RPL_DAG_MC_ENERGY_ESTIMATION 0 - -#define RPL_DAG_MC_ENERGY_TYPE_MAINS 0 -#define RPL_DAG_MC_ENERGY_TYPE_BATTERY 1 -#define RPL_DAG_MC_ENERGY_TYPE_SCAVENGING 2 - -struct rpl_metric_object_energy { - uint8_t flags; - uint8_t energy_est; -}; - -/* Logical representation of a DAG Metric Container. */ -struct rpl_metric_container { - uint8_t type; - uint8_t flags; - uint8_t aggr; - uint8_t prec; - uint8_t length; - union metric_object { - struct rpl_metric_object_energy energy; - uint16_t etx; - } obj; -}; -typedef struct rpl_metric_container rpl_metric_container_t; -/*---------------------------------------------------------------------------*/ -struct rpl_instance; -struct rpl_dag; -/*---------------------------------------------------------------------------*/ -#define RPL_PARENT_FLAG_UPDATED 0x1 -#define RPL_PARENT_FLAG_LINK_METRIC_VALID 0x2 - -struct rpl_parent { - struct rpl_parent *next; - struct rpl_dag *dag; -#if RPL_DAG_MC != RPL_DAG_MC_NONE - rpl_metric_container_t mc; -#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ - rpl_rank_t rank; - clock_time_t last_tx_time; - uint8_t dtsn; - uint8_t flags; -}; -typedef struct rpl_parent rpl_parent_t; -/*---------------------------------------------------------------------------*/ -/* RPL DIO prefix suboption */ -struct rpl_prefix { - uip_ipaddr_t prefix; - uint32_t lifetime; - uint8_t length; - uint8_t flags; -}; -typedef struct rpl_prefix rpl_prefix_t; -/*---------------------------------------------------------------------------*/ -/* Directed Acyclic Graph */ -struct rpl_dag { - uip_ipaddr_t dag_id; - rpl_rank_t min_rank; /* should be reset per DAG iteration! */ - uint8_t version; - uint8_t grounded; - uint8_t preference; - uint8_t used; - /* live data for the DAG */ - uint8_t joined; - rpl_parent_t *preferred_parent; - rpl_rank_t rank; - struct rpl_instance *instance; - rpl_prefix_t prefix_info; -}; -typedef struct rpl_dag rpl_dag_t; -typedef struct rpl_instance rpl_instance_t; -/*---------------------------------------------------------------------------*/ -/* - * API for RPL objective functions (OF) - * - * reset(dag) - * - * Resets the objective function state for a specific DAG. This function is - * called when doing a global repair on the DAG. - * - * neighbor_link_callback(parent, known, etx) - * - * Receives link-layer neighbor information. The parameter "known" is set - * either to 0 or 1. The "etx" parameter specifies the current - * ETX(estimated transmissions) for the neighbor. - * - * best_parent(parent1, parent2) - * - * Compares two parents and returns the best one, according to the OF. - * - * best_dag(dag1, dag2) - * - * Compares two DAGs and returns the best one, according to the OF. - * - * calculate_rank(parent, base_rank) - * - * Calculates a rank value using the parent rank and a base rank. - * If "parent" is NULL, the objective function selects a default increment - * that is adds to the "base_rank". Otherwise, the OF uses information known - * about "parent" to select an increment to the "base_rank". - * - * update_metric_container(dag) - * - * Updates the metric container for outgoing DIOs in a certain DAG. - * If the objective function of the DAG does not use metric containers, - * the function should set the object type to RPL_DAG_MC_NONE. - */ -struct rpl_of { - void (*reset)(struct rpl_dag *); - void (*neighbor_link_callback)(rpl_parent_t *, int, int); - rpl_parent_t *(*best_parent)(rpl_parent_t *, rpl_parent_t *); - rpl_dag_t *(*best_dag)(rpl_dag_t *, rpl_dag_t *); - rpl_rank_t (*calculate_rank)(rpl_parent_t *, rpl_rank_t); - void (*update_metric_container)( rpl_instance_t *); - rpl_ocp_t ocp; -}; -typedef struct rpl_of rpl_of_t; - -/* Declare the selected objective function. */ -extern rpl_of_t RPL_OF; -/*---------------------------------------------------------------------------*/ -/* Instance */ -struct rpl_instance { - /* DAG configuration */ - rpl_metric_container_t mc; - rpl_of_t *of; - rpl_dag_t *current_dag; - rpl_dag_t dag_table[RPL_MAX_DAG_PER_INSTANCE]; - /* The current default router - used for routing "upwards" */ - uip_ds6_defrt_t *def_route; - uint8_t instance_id; - uint8_t used; - uint8_t dtsn_out; - uint8_t mop; - uint8_t dio_intdoubl; - uint8_t dio_intmin; - uint8_t dio_redundancy; - uint8_t default_lifetime; - uint8_t dio_intcurrent; - uint8_t dio_send; /* for keeping track of which mode the timer is in */ - uint8_t dio_counter; - rpl_rank_t max_rankinc; - rpl_rank_t min_hoprankinc; - uint16_t lifetime_unit; /* lifetime in seconds = l_u * d_l */ -#if RPL_CONF_STATS - uint16_t dio_totint; - uint16_t dio_totsend; - uint16_t dio_totrecv; -#endif /* RPL_CONF_STATS */ - clock_time_t dio_next_delay; /* delay for completion of dio interval */ -#if RPL_WITH_PROBING - struct ctimer probing_timer; -#endif /* RPL_WITH_PROBING */ - struct ctimer dio_timer; - struct ctimer dao_timer; - struct ctimer dao_lifetime_timer; -}; - -/*---------------------------------------------------------------------------*/ -/* Public RPL functions. */ -void rpl_init(void); -void uip_rpl_input(void); -rpl_dag_t *rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id); -rpl_dag_t *rpl_set_root_with_version(uint8_t instance_id, uip_ipaddr_t *dag_id, uint8_t version); -int rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len); -int rpl_repair_root(uint8_t instance_id); -int rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from); -rpl_dag_t *rpl_get_any_dag(void); -rpl_instance_t *rpl_get_instance(uint8_t instance_id); -int rpl_update_header_empty(struct net_buf *buf); -int rpl_update_header_final(struct net_buf *buf, uip_ipaddr_t *addr); -int rpl_verify_header(struct net_buf *buf, int); -void rpl_insert_header(struct net_buf *buf); -void rpl_remove_header(struct net_buf *buf); -uint8_t rpl_invert_header(struct net_buf *buf); -uip_ipaddr_t *rpl_get_parent_ipaddr(rpl_parent_t *nbr); -rpl_parent_t *rpl_get_parent(uip_lladdr_t *addr); -rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr); -uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr); -void rpl_dag_init(void); -uip_ds6_nbr_t *rpl_get_nbr(rpl_parent_t *parent); -void rpl_print_neighbor_list(); - -/* Per-parent RPL information */ -NBR_TABLE_DECLARE(rpl_parents); - -/** - * RPL modes - * - * The RPL module can be in either of three modes: mesh mode - * (RPL_MODE_MESH), feater mode (RPL_MODE_FEATHER), and leaf mode - * (RPL_MODE_LEAF). In mesh mode, nodes forward data for other nodes, - * and are reachable by others. In feather mode, nodes can forward - * data for other nodes, but are not reachable themselves. In leaf - * mode, nodes do not forward data for others, but are reachable by - * others. */ -enum rpl_mode { - RPL_MODE_MESH = 0, - RPL_MODE_FEATHER = 1, - RPL_MODE_LEAF = 2, -}; - -/** - * Set the RPL mode - * - * \param mode The new RPL mode - * \retval The previous RPL mode - */ -enum rpl_mode rpl_set_mode(enum rpl_mode mode); - -/** - * Get the RPL mode - * - * \retval The RPL mode - */ -enum rpl_mode rpl_get_mode(void); - -/*---------------------------------------------------------------------------*/ -#endif /* RPL_H */ diff --git a/net/ip/contiki/sicslowpan/compression.h b/net/ip/contiki/sicslowpan/compression.h deleted file mode 100644 index 97c644da8d41a9e5fc56a6c0baa3b3600c98cc29..0000000000000000000000000000000000000000 --- a/net/ip/contiki/sicslowpan/compression.h +++ /dev/null @@ -1,31 +0,0 @@ -/* compression.h - Header Compression */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "contiki-conf.h" -#include - -#ifndef COMPRESSION_H_ -#define COMPRESSION_H_ - -struct compression { - void (* init)(void); - int (* compress)(struct net_buf *buf); - int (* uncompress)(struct net_buf *buf); -}; - -#endif /* COMPRESSION_H_ */ diff --git a/net/ip/contiki/sicslowpan/fragmentation.h b/net/ip/contiki/sicslowpan/fragmentation.h deleted file mode 100644 index aacc5afa74956587a4931366f592260c64b6293b..0000000000000000000000000000000000000000 --- a/net/ip/contiki/sicslowpan/fragmentation.h +++ /dev/null @@ -1,31 +0,0 @@ -/* fragmentation.h - Fragmentation */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "contiki-conf.h" -#include -#include "contiki/mac/mac.h" - -#ifndef FRAGMENTATION_H_ -#define FRAGMENTATION_H_ - -struct fragmentation { - int (* fragment)(struct net_buf *buf, void *ptr); - int (* reassemble)(struct net_buf *buf); -}; - -#endif /* FRAGMENTATION_H_ */ diff --git a/net/ip/contiki/sicslowpan/null_compression.c b/net/ip/contiki/sicslowpan/null_compression.c deleted file mode 100644 index 674144a59e3afdaedddf363a6c1bb3ddaaf319d7..0000000000000000000000000000000000000000 --- a/net/ip/contiki/sicslowpan/null_compression.c +++ /dev/null @@ -1,55 +0,0 @@ -/* null_compression.c - null header compression */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include -#include "contiki/netstack.h" -#include "contiki/sicslowpan/null_compression.h" - -#define DEBUG 0 -#include "contiki/ip/uip-debug.h" - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif - -static void init(void) -{ -} - -static int compress(struct net_buf *buf) -{ - return 1; -} - -static int uncompress(struct net_buf *buf) -{ - return 1; -} - -const struct compression null_compression = { - .init = init, - .compress = compress, - .uncompress = uncompress, -}; diff --git a/net/ip/contiki/sicslowpan/null_compression.h b/net/ip/contiki/sicslowpan/null_compression.h deleted file mode 100644 index 6a7ae9b13b52c58501a8499c97c47b1dc29752ea..0000000000000000000000000000000000000000 --- a/net/ip/contiki/sicslowpan/null_compression.h +++ /dev/null @@ -1,26 +0,0 @@ -/* null_compression.h - NULL header Compression */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NULL_COMPRESSION_H_ -#define NULL_COMPRESSION_H_ - -#include "contiki/sicslowpan/compression.h" - -extern const struct compression null_compression; - -#endif /* NULL_COMPRESSION_H_ */ diff --git a/net/ip/contiki/sicslowpan/null_fragmentation.c b/net/ip/contiki/sicslowpan/null_fragmentation.c deleted file mode 100644 index 5a79566456e4cc63b3a267b6e0e0c728df39ea01..0000000000000000000000000000000000000000 --- a/net/ip/contiki/sicslowpan/null_fragmentation.c +++ /dev/null @@ -1,120 +0,0 @@ -/* null_fragmentation.c - NULL packet fragmentation for 802.15.4 */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#include -#include - -#include "contiki/sicslowpan/null_fragmentation.h" -#include "contiki/netstack.h" - -#include "contiki/ipv6/uip-ds6-nbr.h" - -#define DEBUG 0 -#include "contiki/ip/uip-debug.h" - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif - -static void -packet_sent(struct net_buf *buf, void *ptr, int status, int transmissions) -{ - const linkaddr_t *dest = packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER); - uip_ds6_link_neighbor_callback(dest, status, transmissions); - uip_last_tx_status(buf) = status; -} - -static int fragment(struct net_buf *buf, void *ptr) -{ - struct net_buf *mbuf; - int ret; - - mbuf = l2_buf_get_reserve(0); - if (!mbuf) { - return 0; - } - - NET_BUF_CHECK_IF_NOT_IN_USE(buf); - - ret = packetbuf_copyfrom(mbuf, &uip_buf(buf)[UIP_LLH_LEN], - uip_len(buf)); - PRINTF("%s: buffer len %d copied %d\n", __FUNCTION__, uip_len(buf), ret); - packetbuf_set_addr(mbuf, PACKETBUF_ADDR_RECEIVER, &ip_buf_ll_dest(buf)); - ip_buf_unref(buf); - - return NETSTACK_LLSEC.send(mbuf, &packet_sent, true, ptr); -} - -static int send_upstream(struct net_buf *buf) -{ - if (!NETSTACK_COMPRESS.uncompress(buf)) { - UIP_LOG("Uncompression failed."); - return -EINVAL; - } - - if (net_recv(buf) < 0) { - UIP_LOG("Input to IP stack failed."); - return -EINVAL; - } - - return 0; -} - -static int reassemble(struct net_buf *mbuf) -{ - struct net_buf *buf; - - buf = ip_buf_get_reserve_rx(0); - if (!buf) { - return 0; - } - - if(packetbuf_datalen(mbuf) > 0 && - packetbuf_datalen(mbuf) <= UIP_BUFSIZE - UIP_LLH_LEN) { - memcpy(uip_buf(buf), packetbuf_dataptr(mbuf), - packetbuf_datalen(mbuf)); - uip_len(buf) = packetbuf_datalen(mbuf); - net_buf_add(buf, uip_len(buf)); - - if (send_upstream(buf) < 0) { - ip_buf_unref(buf); - } else { - l2_buf_unref(mbuf); - } - - return 1; - } else { - PRINTF("packet discarded, datalen %d MAX %d\n", - packetbuf_datalen(mbuf), UIP_BUFSIZE - UIP_LLH_LEN); - ip_buf_unref(buf); - return 0; - } -} - -const struct fragmentation null_fragmentation = { - fragment, - reassemble -}; diff --git a/net/ip/contiki/sicslowpan/null_fragmentation.h b/net/ip/contiki/sicslowpan/null_fragmentation.h deleted file mode 100644 index 842adef6e8f0414dd30e0654d99b935f5395fa0c..0000000000000000000000000000000000000000 --- a/net/ip/contiki/sicslowpan/null_fragmentation.h +++ /dev/null @@ -1,26 +0,0 @@ -/* null_fragmentation.h - NULL fragmentation for 802.15.4 */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NULL_FRAGMENTATION_H_ -#define NULL_FRAGMENTATION_H_ - -#include "contiki/sicslowpan/fragmentation.h" - -extern const struct fragmentation null_fragmentation; - -#endif /* NULL_FRGAMENTATION_H_ */ diff --git a/net/ip/contiki/sicslowpan/sicslowpan_compression.c b/net/ip/contiki/sicslowpan/sicslowpan_compression.c deleted file mode 100644 index 1e0e1f7b0aac1ede6d07488c9bdf97de124d5fbb..0000000000000000000000000000000000000000 --- a/net/ip/contiki/sicslowpan/sicslowpan_compression.c +++ /dev/null @@ -1,1102 +0,0 @@ -/* sicslowpan_compression.c - IPv6 header compression */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Copyright (c) 2008, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * 6lowpan implementation (RFC4944 and draft-ietf-6lowpan-hc-06) - * - * \author Adam Dunkels - * \author Nicolas Tsiftes - * \author Niclas Finne - * \author Mathilde Durvy - * \author Julien Abeille - * \author Joakim Eriksson - * \author Joel Hoglund - */ - -#include -#include - -#include -#include "contiki/sicslowpan/sicslowpan_compression.h" -#include "contiki/netstack.h" -#include "contiki/packetbuf.h" -#include "contiki/ip/uip.h" -#include "contiki/ip/tcpip.h" -#include "dev/watchdog.h" -#include "contiki/ipv6/uip-ds6.h" - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_6LOWPAN_COMPRESSION -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#if DEBUG -#define PRINTPACKETBUF() do { uint8_t p; PRINTF("packetbuf buffer: "); for(p = 0; p < packetbuf_datalen(); p++){PRINTF("%.2X", *(packetbuf_ptr + p));} PRINTF("\n"); } while(0) -#define PRINTUIPBUF() do { uint8_t p; PRINTF("UIP buffer: "); for(p = 0; p < uip_len; p++){PRINTF("%.2X", uip_buf[p]);}PRINTF("\n"); } while(0) -#define PRINTSICSLOWPANBUF() do { uint8_t p; PRINTF("SICSLOWPAN buffer: "); for(p = 0; p < sicslowpan_len; p++){PRINTF("%.2X", sicslowpan_buf[p]);}PRINTF("\n"); } while(0) -#else -#define PRINTPACKETBUF() -#define PRINTUIPBUF() -#define PRINTSICSLOWPANBUF() -#endif /* DEBUG == 1*/ - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif /* UIP_LOGGING == 1 */ - -#ifndef SICSLOWPAN_COMPRESSION -#ifdef SICSLOWPAN_CONF_COMPRESSION -#define SICSLOWPAN_COMPRESSION SICSLOWPAN_CONF_COMPRESSION -#else -#define SICSLOWPAN_COMPRESSION SICSLOWPAN_COMPRESSION_IPV6 -#endif /* SICSLOWPAN_CONF_COMPRESSION */ -#endif /* SICSLOWPAN_COMPRESSION */ - -#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 -#error 6LoWPAN HC1 compression not supported -#endif - -#if (SICSLOWPAN_COMPRESSION != SICSLOWPAN_COMPRESSION_IPHC) && (SICSLOWPAN_COMPRESSION != SICSLOWPAN_COMPRESSION_IPV6) -#error Unsupported 6LoWPAN compression. Please set SICSLOWPAN_CONF_COMPRESSION. -#endif - -#define GET16(ptr,index) (((uint16_t)((ptr)[index] << 8)) | ((ptr)[(index) + 1])) -#define SET16(ptr,index,value) do { \ - (ptr)[index] = ((value) >> 8) & 0xff; \ - (ptr)[index + 1] = (value) & 0xff; \ -} while(0) - -/** \name Pointers in the packetbuf buffer - * @{ - */ - -/* define the buffer as a byte array */ -#define PACKETBUF_IPHC_BUF(buf) ((uint8_t *)(uip_packetbuf_ptr(buf) + uip_packetbuf_hdr_len(buf))) - -#define PACKETBUF_HC1_PTR(buf) (uip_packetbuf_ptr(buf) + uip_packetbuf_hdr_len(buf)) -#define PACKETBUF_HC1_DISPATCH 0 /* 8 bit */ - -/** \name Pointers in the sicslowpan and uip buffer - * @{ - */ -#define SICSLOWPAN_IP_BUF(buf) ((struct uip_ip_hdr *)&buf[UIP_LLH_LEN]) -#define SICSLOWPAN_UDP_BUF(buf) ((struct uip_udp_hdr *)&buf[UIP_LLIPH_LEN]) - -#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) -#define UIP_UDP_BUF(buf) ((struct uip_udp_hdr *)&uip_buf(buf)[UIP_LLIPH_LEN]) -#define UIP_TCP_BUF(buf) ((struct uip_tcp_hdr *)&uip_buf(buf)[UIP_LLIPH_LEN]) -#define UIP_ICMP_BUF(buf) ((struct uip_icmp_hdr *)&uip_buf(buf)[UIP_LLIPH_LEN]) -/** @} */ - -#define sicslowpan_buf uip_buf -#define sicslowpan_len uip_len - -/** \brief Maximum available size for frame headers, - link layer security-related overhead, as well as - 6LoWPAN payload. */ -#ifdef SICSLOWPAN_CONF_MAC_MAX_PAYLOAD -#define MAC_MAX_PAYLOAD SICSLOWPAN_CONF_MAC_MAX_PAYLOAD -#else /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */ -#define MAC_MAX_PAYLOAD (127 - 2) -#endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */ - - -/** \brief Some MAC layers need a minimum payload, which is - configurable through the SICSLOWPAN_CONF_MIN_MAC_PAYLOAD - option. */ -#ifdef SICSLOWPAN_CONF_COMPRESSION_THRESHOLD -#define COMPRESSION_THRESHOLD SICSLOWPAN_CONF_COMPRESSION_THRESHOLD -#else -#define COMPRESSION_THRESHOLD 0 -#endif - -#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPHC -/** \name IPHC specific variables - * @{ - */ - -/** Addresses contexts for IPHC. */ -#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 -static struct sicslowpan_addr_context -addr_contexts[SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS]; -#endif - -/** pointer to an address context. */ -static struct sicslowpan_addr_context *context; - -/** pointer to the byte where to write next inline field. */ -static uint8_t *iphc_ptr; - -/* Uncompression of linklocal */ -/* 0 -> 16 bytes from packet */ -/* 1 -> 2 bytes from prefix - bunch of zeroes and 8 from packet */ -/* 2 -> 2 bytes from prefix - 0000::00ff:fe00:XXXX from packet */ -/* 3 -> 2 bytes from prefix - infer 8 bytes from lladdr */ -/* NOTE: => the uncompress function does change 0xf to 0x10 */ -/* NOTE: 0x00 => no-autoconfig => unspecified */ -const uint8_t unc_llconf[] = {0x0f,0x28,0x22,0x20}; - -/* Uncompression of ctx-based */ -/* 0 -> 0 bits from packet [unspecified / reserved] */ -/* 1 -> 8 bytes from prefix - bunch of zeroes and 8 from packet */ -/* 2 -> 8 bytes from prefix - 0000::00ff:fe00:XXXX + 2 from packet */ -/* 3 -> 8 bytes from prefix - infer 8 bytes from lladdr */ -const uint8_t unc_ctxconf[] = {0x00,0x88,0x82,0x80}; - -/* Uncompression of ctx-based */ -/* 0 -> 0 bits from packet */ -/* 1 -> 2 bytes from prefix - bunch of zeroes 5 from packet */ -/* 2 -> 2 bytes from prefix - zeroes + 3 from packet */ -/* 3 -> 2 bytes from prefix - infer 1 bytes from lladdr */ -const uint8_t unc_mxconf[] = {0x0f, 0x25, 0x23, 0x21}; - -/* Link local prefix */ -const uint8_t llprefix[] = {0xfe, 0x80}; - -/* TTL uncompression values */ -static const uint8_t ttl_values[] = {0, 1, 64, 255}; - -/*--------------------------------------------------------------------*/ -/** \name IPHC related functions - * @{ */ -/*--------------------------------------------------------------------*/ -/** \brief find the context corresponding to prefix ipaddr */ -static struct sicslowpan_addr_context* -addr_context_lookup_by_prefix(uip_ipaddr_t *ipaddr) -{ -/* Remove code to avoid warnings and save flash if no context is used */ -#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 - int i; - for(i = 0; i < SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; i++) { - if((addr_contexts[i].used == 1) && - uip_ipaddr_prefixcmp(&addr_contexts[i].prefix, ipaddr, 64)) { - return &addr_contexts[i]; - } - } -#endif /* SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 */ - return NULL; -} -/*--------------------------------------------------------------------*/ -/** \brief find the context with the given number */ -static struct sicslowpan_addr_context* -addr_context_lookup_by_number(uint8_t number) -{ -/* Remove code to avoid warnings and save flash if no context is used */ -#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 - int i; - for(i = 0; i < SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; i++) { - if((addr_contexts[i].used == 1) && - addr_contexts[i].number == number) { - return &addr_contexts[i]; - } - } -#endif /* SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 */ - return NULL; -} -/*--------------------------------------------------------------------*/ -static uint8_t -compress_addr_64(uint8_t bitpos, uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr) -{ - if(uip_is_addr_mac_addr_based(ipaddr, lladdr)) { - return 3 << bitpos; /* 0-bits */ - } else if(sicslowpan_is_iid_16_bit_compressable(ipaddr)) { - /* compress IID to 16 bits xxxx::0000:00ff:fe00:XXXX */ - memcpy(iphc_ptr, &ipaddr->u16[7], 2); - iphc_ptr += 2; - return 2 << bitpos; /* 16-bits */ - } else { - /* do not compress IID => xxxx::IID */ - memcpy(iphc_ptr, &ipaddr->u16[4], 8); - iphc_ptr += 8; - return 1 << bitpos; /* 64-bits */ - } -} - -/*-------------------------------------------------------------------- */ -/* Uncompress addresses based on a prefix and a postfix with zeroes in - * between. If the postfix is zero in length it will use the link address - * to configure the IP address (autoconf style). - * pref_post_count takes a byte where the first nibble specify prefix count - * and the second postfix count (NOTE: 15/0xf => 16 bytes copy). - */ -static void -uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[], - uint8_t pref_post_count, uip_lladdr_t *lladdr) -{ - uint8_t prefcount = pref_post_count >> 4; - uint8_t postcount = pref_post_count & 0x0f; - /* full nibble 15 => 16 */ - prefcount = prefcount == 15 ? 16 : prefcount; - postcount = postcount == 15 ? 16 : postcount; - - PRINTF("Uncompressing %d + %d => ", prefcount, postcount); - - if(prefcount > 0) { - memcpy(ipaddr, prefix, prefcount); - } - if(prefcount + postcount < 16) { - memset(&ipaddr->u8[prefcount], 0, 16 - (prefcount + postcount)); - } - if(postcount > 0) { - memcpy(&ipaddr->u8[16 - postcount], iphc_ptr, postcount); - if(postcount == 2 && prefcount < 11) { - /* 16 bits uncompression => 0000:00ff:fe00:XXXX */ - ipaddr->u8[11] = 0xff; - ipaddr->u8[12] = 0xfe; - } - iphc_ptr += postcount; - } else if (prefcount > 0) { - /* no IID based configuration if no prefix and no data => unspec */ - uip_ds6_set_addr_iid(ipaddr, lladdr); - } - - PRINT6ADDR(ipaddr); - PRINTF("\n"); -} - -/*--------------------------------------------------------------------*/ -/** - * \brief Compress IP/UDP header - * - * This function is called by the 6lowpan code to create a compressed - * 6lowpan packet in the packetbuf buffer from a full IPv6 packet in the - * uip_buf buffer. - * - * - * IPHC (RFC 6282) - * http://tools.ietf.org/html/ - * - * \note We do not support ISA100_UDP header compression - * - * For LOWPAN_UDP compression, we either compress both ports or none. - * General format with LOWPAN_UDP compression is - * \verbatim - * 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * |0|1|1|TF |N|HLI|C|S|SAM|M|D|DAM| SCI | DCI | comp. IPv6 hdr| - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | compressed IPv6 fields ..... | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | LOWPAN_UDP | non compressed UDP fields ... | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | L4 data ... | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * \endverbatim - * \note The context number 00 is reserved for the link local prefix. - * For unicast addresses, if we cannot compress the prefix, we neither - * compress the IID. - * \param link_destaddr L2 destination address, needed to compress IP - * dest - */ -static int -compress_hdr_iphc(struct net_buf *mbuf, struct net_buf *buf, linkaddr_t *link_destaddr) -{ - uint8_t tmp, iphc0, iphc1; - - iphc_ptr = uip_packetbuf_ptr(mbuf) + 2; - /* - * As we copy some bit-length fields, in the IPHC encoding bytes, - * we sometimes use |= - * If the field is 0, and the current bit value in memory is 1, - * this does not work. We therefore reset the IPHC encoding here - */ - - iphc0 = SICSLOWPAN_DISPATCH_IPHC; - iphc1 = 0; - PACKETBUF_IPHC_BUF(mbuf)[2] = 0; /* might not be used - but needs to be cleared */ - - /* - * Address handling needs to be made first since it might - * cause an extra byte with [ SCI | DCI ] - * - */ - - - /* check if dest context exists (for allocating third byte) */ - /* TODO: fix this so that it remembers the looked up values for - avoiding two lookups - or set the lookup values immediately */ - if(addr_context_lookup_by_prefix(&UIP_IP_BUF(buf)->destipaddr) != NULL || - addr_context_lookup_by_prefix(&UIP_IP_BUF(buf)->srcipaddr) != NULL) { - /* set context flag and increase iphc_ptr */ - PRINTF("IPHC: compressing dest or src ipaddr - setting CID\n"); - iphc1 |= SICSLOWPAN_IPHC_CID; - iphc_ptr++; - } - - /* - * Traffic class, flow label - * If flow label is 0, compress it. If traffic class is 0, compress it - * We have to process both in the same time as the offset of traffic class - * depends on the presence of version and flow label - */ - - /* IPHC format of tc is ECN | DSCP , original is DSCP | ECN */ - tmp = (UIP_IP_BUF(buf)->vtc << 4) | (UIP_IP_BUF(buf)->tcflow >> 4); - tmp = ((tmp & 0x03) << 6) | (tmp >> 2); - - if(((UIP_IP_BUF(buf)->tcflow & 0x0F) == 0) && - (UIP_IP_BUF(buf)->flow == 0)) { - /* flow label can be compressed */ - iphc0 |= SICSLOWPAN_IPHC_FL_C; - if(((UIP_IP_BUF(buf)->vtc & 0x0F) == 0) && - ((UIP_IP_BUF(buf)->tcflow & 0xF0) == 0)) { - /* compress (elide) all */ - iphc0 |= SICSLOWPAN_IPHC_TC_C; - } else { - /* compress only the flow label */ - *iphc_ptr = tmp; - iphc_ptr += 1; - } - } else { - /* Flow label cannot be compressed */ - if(((UIP_IP_BUF(buf)->vtc & 0x0F) == 0) && - ((UIP_IP_BUF(buf)->tcflow & 0xF0) == 0)) { - /* compress only traffic class */ - iphc0 |= SICSLOWPAN_IPHC_TC_C; - *iphc_ptr = (tmp & 0xc0) | - (UIP_IP_BUF(buf)->tcflow & 0x0F); - memcpy(iphc_ptr + 1, &UIP_IP_BUF(buf)->flow, 2); - iphc_ptr += 3; - } else { - /* compress nothing */ - memcpy(iphc_ptr, &UIP_IP_BUF(buf)->vtc, 4); - /* but replace the top byte with the new ECN | DSCP format*/ - *iphc_ptr = tmp; - iphc_ptr += 4; - } - } - - /* Note that the payload length is always compressed */ - - /* Next header. We compress it if UDP */ -#if UIP_CONF_UDP || UIP_CONF_ROUTER - if(UIP_IP_BUF(buf)->proto == UIP_PROTO_UDP) { - iphc0 |= SICSLOWPAN_IPHC_NH_C; - } -#endif /*UIP_CONF_UDP*/ - if ((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) { - *iphc_ptr = UIP_IP_BUF(buf)->proto; - iphc_ptr += 1; - } - - /* - * Hop limit - * if 1: compress, encoding is 01 - * if 64: compress, encoding is 10 - * if 255: compress, encoding is 11 - * else do not compress - */ - switch(UIP_IP_BUF(buf)->ttl) { - case 1: - iphc0 |= SICSLOWPAN_IPHC_TTL_1; - break; - case 64: - iphc0 |= SICSLOWPAN_IPHC_TTL_64; - break; - case 255: - iphc0 |= SICSLOWPAN_IPHC_TTL_255; - break; - default: - *iphc_ptr = UIP_IP_BUF(buf)->ttl; - iphc_ptr += 1; - break; - } - - /* source address - cannot be multicast */ - if(uip_is_addr_unspecified(&UIP_IP_BUF(buf)->srcipaddr)) { - PRINTF("IPHC: compressing unspecified - setting SAC\n"); - iphc1 |= SICSLOWPAN_IPHC_SAC; - iphc1 |= SICSLOWPAN_IPHC_SAM_00; - } else if((context = addr_context_lookup_by_prefix(&UIP_IP_BUF(buf)->srcipaddr)) - != NULL) { - /* elide the prefix - indicate by CID and set context + SAC */ - PRINTF("IPHC: compressing src with context - setting CID & SAC ctx: %d\n", - context->number); - iphc1 |= SICSLOWPAN_IPHC_CID | SICSLOWPAN_IPHC_SAC; - PACKETBUF_IPHC_BUF(mbuf)[2] |= context->number << 4; - /* compession compare with this nodes address (source) */ - - iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT, - &UIP_IP_BUF(buf)->srcipaddr, &uip_lladdr); - /* No context found for this address */ - } else if(uip_is_addr_link_local(&UIP_IP_BUF(buf)->srcipaddr) && - UIP_IP_BUF(buf)->destipaddr.u16[1] == 0 && - UIP_IP_BUF(buf)->destipaddr.u16[2] == 0 && - UIP_IP_BUF(buf)->destipaddr.u16[3] == 0) { - iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT, - &UIP_IP_BUF(buf)->srcipaddr, &uip_lladdr); - } else { - /* send the full address => SAC = 0, SAM = 00 */ - iphc1 |= SICSLOWPAN_IPHC_SAM_00; /* 128-bits */ - memcpy(iphc_ptr, &UIP_IP_BUF(buf)->srcipaddr.u16[0], 16); - iphc_ptr += 16; - } - - /* dest address*/ - if(uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr)) { - /* Address is multicast, try to compress */ - iphc1 |= SICSLOWPAN_IPHC_M; - if(sicslowpan_is_mcast_addr_compressable8(&UIP_IP_BUF(buf)->destipaddr)) { - iphc1 |= SICSLOWPAN_IPHC_DAM_11; - /* use last byte */ - *iphc_ptr = UIP_IP_BUF(buf)->destipaddr.u8[15]; - iphc_ptr += 1; - } else if(sicslowpan_is_mcast_addr_compressable32(&UIP_IP_BUF(buf)->destipaddr)) { - iphc1 |= SICSLOWPAN_IPHC_DAM_10; - /* second byte + the last three */ - *iphc_ptr = UIP_IP_BUF(buf)->destipaddr.u8[1]; - memcpy(iphc_ptr + 1, &UIP_IP_BUF(buf)->destipaddr.u8[13], 3); - iphc_ptr += 4; - } else if(sicslowpan_is_mcast_addr_compressable48(&UIP_IP_BUF(buf)->destipaddr)) { - iphc1 |= SICSLOWPAN_IPHC_DAM_01; - /* second byte + the last five */ - *iphc_ptr = UIP_IP_BUF(buf)->destipaddr.u8[1]; - memcpy(iphc_ptr + 1, &UIP_IP_BUF(buf)->destipaddr.u8[11], 5); - iphc_ptr += 6; - } else { - iphc1 |= SICSLOWPAN_IPHC_DAM_00; - /* full address */ - memcpy(iphc_ptr, &UIP_IP_BUF(buf)->destipaddr.u8[0], 16); - iphc_ptr += 16; - } - } else { - /* Address is unicast, try to compress */ - if((context = addr_context_lookup_by_prefix(&UIP_IP_BUF(buf)->destipaddr)) != NULL) { - /* elide the prefix */ - iphc1 |= SICSLOWPAN_IPHC_DAC; - PACKETBUF_IPHC_BUF(mbuf)[2] |= context->number; - /* compession compare with link adress (destination) */ - - iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT, - &UIP_IP_BUF(buf)->destipaddr, (uip_lladdr_t *)link_destaddr); - /* No context found for this address */ - } else if(uip_is_addr_link_local(&UIP_IP_BUF(buf)->destipaddr) && - UIP_IP_BUF(buf)->destipaddr.u16[1] == 0 && - UIP_IP_BUF(buf)->destipaddr.u16[2] == 0 && - UIP_IP_BUF(buf)->destipaddr.u16[3] == 0) { - iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT, - &UIP_IP_BUF(buf)->destipaddr, (uip_lladdr_t *)link_destaddr); - } else { - /* send the full address */ - iphc1 |= SICSLOWPAN_IPHC_DAM_00; /* 128-bits */ - memcpy(iphc_ptr, &UIP_IP_BUF(buf)->destipaddr.u16[0], 16); - iphc_ptr += 16; - } - } - - uip_uncomp_hdr_len(mbuf) = UIP_IPH_LEN; - -#if UIP_CONF_UDP || UIP_CONF_ROUTER - /* UDP header compression */ - if(UIP_IP_BUF(buf)->proto == UIP_PROTO_UDP) { - PRINTF("IPHC: Uncompressed UDP ports on send side: %x, %x\n", - UIP_HTONS(UIP_UDP_BUF(buf)->srcport), UIP_HTONS(UIP_UDP_BUF(buf)->destport)); - /* Mask out the last 4 bits can be used as a mask */ - if(((UIP_HTONS(UIP_UDP_BUF(buf)->srcport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN) && - ((UIP_HTONS(UIP_UDP_BUF(buf)->destport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN)) { - /* we can compress 12 bits of both source and dest */ - *iphc_ptr = SICSLOWPAN_NHC_UDP_CS_P_11; - PRINTF("IPHC: remove 12 b of both source & dest with prefix 0xFOB\n"); - *(iphc_ptr + 1) = - (uint8_t)((UIP_HTONS(UIP_UDP_BUF(buf)->srcport) - - SICSLOWPAN_UDP_4_BIT_PORT_MIN) << 4) + - (uint8_t)((UIP_HTONS(UIP_UDP_BUF(buf)->destport) - - SICSLOWPAN_UDP_4_BIT_PORT_MIN)); - iphc_ptr += 2; - } else if((UIP_HTONS(UIP_UDP_BUF(buf)->destport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) { - /* we can compress 8 bits of dest, leave source. */ - *iphc_ptr = SICSLOWPAN_NHC_UDP_CS_P_01; - PRINTF("IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n"); - memcpy(iphc_ptr + 1, &UIP_UDP_BUF(buf)->srcport, 2); - *(iphc_ptr + 3) = - (uint8_t)((UIP_HTONS(UIP_UDP_BUF(buf)->destport) - - SICSLOWPAN_UDP_8_BIT_PORT_MIN)); - iphc_ptr += 4; - } else if((UIP_HTONS(UIP_UDP_BUF(buf)->srcport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) { - /* we can compress 8 bits of src, leave dest. Copy compressed port */ - *iphc_ptr = SICSLOWPAN_NHC_UDP_CS_P_10; - PRINTF("IPHC: remove 8 bits of source with prefix 0xF0, leave dest. hch: %i\n", *iphc_ptr); - *(iphc_ptr + 1) = - (uint8_t)((UIP_HTONS(UIP_UDP_BUF(buf)->srcport) - - SICSLOWPAN_UDP_8_BIT_PORT_MIN)); - memcpy(iphc_ptr + 2, &UIP_UDP_BUF(buf)->destport, 2); - iphc_ptr += 4; - } else { - /* we cannot compress. Copy uncompressed ports, full checksum */ - *iphc_ptr = SICSLOWPAN_NHC_UDP_CS_P_00; - PRINTF("IPHC: cannot compress headers\n"); - memcpy(iphc_ptr + 1, &UIP_UDP_BUF(buf)->srcport, 4); - iphc_ptr += 5; - } - /* always inline the checksum */ - if(1) { - memcpy(iphc_ptr, &UIP_UDP_BUF(buf)->udpchksum, 2); - iphc_ptr += 2; - } - uip_uncomp_hdr_len(mbuf) += UIP_UDPH_LEN; - } -#endif /*UIP_CONF_UDP*/ - - /* before the packetbuf_hdr_len operation */ - PACKETBUF_IPHC_BUF(mbuf)[0] = iphc0; - PACKETBUF_IPHC_BUF(mbuf)[1] = iphc1; - - uip_packetbuf_hdr_len(mbuf) = iphc_ptr - uip_packetbuf_ptr(mbuf); - - return 1; -} - -/*--------------------------------------------------------------------*/ -/** - * \brief Uncompress IPHC (i.e., IPHC and LOWPAN_UDP) headers and put - * them in sicslowpan_buf - * - * This function is called by the input function when the dispatch is - * IPHC. - * We %process the packet in the packetbuf buffer, uncompress the header - * fields, and copy the result in the sicslowpan buffer. - * At the end of the decompression, packetbuf_hdr_len and uncompressed_hdr_len - * are set to the appropriate values - * - * \param ip_len Equal to 0 if the packet is not a fragment (IP length - * is then inferred from the L2 length), non 0 if the packet is a 1st - * fragment. - */ -static int -uncompress_hdr_iphc(struct net_buf *mbuf, struct net_buf *ibuf) -{ - uint8_t tmp, iphc0, iphc1; - uint8_t buf[UIP_IPUDPH_LEN] = {}; /* Size of (IP + UDP) header*/ - int ip_len; - /* at least two byte will be used for the encoding */ - iphc_ptr = uip_packetbuf_ptr(mbuf) + uip_packetbuf_hdr_len(mbuf) + 2; - - iphc0 = PACKETBUF_IPHC_BUF(mbuf)[0]; - iphc1 = PACKETBUF_IPHC_BUF(mbuf)[1]; - - /* another if the CID flag is set */ - if(iphc1 & SICSLOWPAN_IPHC_CID) { - PRINTF("IPHC: CID flag set - increase header with one\n"); - iphc_ptr++; - } - - /* Traffic class and flow label */ - if((iphc0 & SICSLOWPAN_IPHC_FL_C) == 0) { - /* Flow label are carried inline */ - if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) { - /* Traffic class is carried inline */ - memcpy(&SICSLOWPAN_IP_BUF(buf)->tcflow, iphc_ptr + 1, 3); - tmp = *iphc_ptr; - iphc_ptr += 4; - /* IPHC format of tc is ECN | DSCP , original is DSCP | ECN */ - /* set version, pick highest DSCP bits and set in vtc */ - SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((tmp >> 2) & 0x0f); - /* ECN rolled down two steps + lowest DSCP bits at top two bits */ - SICSLOWPAN_IP_BUF(buf)->tcflow = ((tmp >> 2) & 0x30) | (tmp << 6) | - (SICSLOWPAN_IP_BUF(buf)->tcflow & 0x0f); - } else { - /* Traffic class is compressed (set version and no TC)*/ - SICSLOWPAN_IP_BUF(buf)->vtc = 0x60; - /* highest flow label bits + ECN bits */ - SICSLOWPAN_IP_BUF(buf)->tcflow = (*iphc_ptr & 0x0F) | - ((*iphc_ptr >> 2) & 0x30); - memcpy(&SICSLOWPAN_IP_BUF(buf)->flow, iphc_ptr + 1, 2); - iphc_ptr += 3; - } - } else { - /* Version is always 6! */ - /* Version and flow label are compressed */ - if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) { - /* Traffic class is inline */ - SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((*iphc_ptr >> 2) & 0x0f); - SICSLOWPAN_IP_BUF(buf)->tcflow = ((*iphc_ptr << 6) & 0xC0) | ((*iphc_ptr >> 2) & 0x30); - SICSLOWPAN_IP_BUF(buf)->flow = 0; - iphc_ptr += 1; - } else { - /* Traffic class is compressed */ - SICSLOWPAN_IP_BUF(buf)->vtc = 0x60; - SICSLOWPAN_IP_BUF(buf)->tcflow = 0; - SICSLOWPAN_IP_BUF(buf)->flow = 0; - } - } - - /* Next Header */ - if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) { - /* Next header is carried inline */ - SICSLOWPAN_IP_BUF(buf)->proto = *iphc_ptr; - PRINTF("IPHC: next header inline: %d\n", SICSLOWPAN_IP_BUF(buf)->proto); - iphc_ptr += 1; - } - - /* Hop limit */ - if((iphc0 & 0x03) != SICSLOWPAN_IPHC_TTL_I) { - SICSLOWPAN_IP_BUF(buf)->ttl = ttl_values[iphc0 & 0x03]; - } else { - SICSLOWPAN_IP_BUF(buf)->ttl = *iphc_ptr; - iphc_ptr += 1; - } - - /* put the source address compression mode SAM in the tmp var */ - tmp = ((iphc1 & SICSLOWPAN_IPHC_SAM_11) >> SICSLOWPAN_IPHC_SAM_BIT) & 0x03; - - /* context based compression */ - if(iphc1 & SICSLOWPAN_IPHC_SAC) { - uint8_t sci = (iphc1 & SICSLOWPAN_IPHC_CID) ? - PACKETBUF_IPHC_BUF(mbuf)[2] >> 4 : 0; - - /* Source address - check context != NULL only if SAM bits are != 0*/ - if (tmp != 0) { - context = addr_context_lookup_by_number(sci); - if(context == NULL) { - PRINTF("sicslowpan uncompress_hdr: error context not found\n"); - return 0; - } - } - /* if tmp == 0 we do not have a context and therefore no prefix */ - uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr, - tmp != 0 ? context->prefix : NULL, unc_ctxconf[tmp], - (uip_lladdr_t *)&ip_buf_ll_src(ibuf)); - } else { - /* no compression and link local */ - uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr, llprefix, - unc_llconf[tmp], - (uip_lladdr_t *)&ip_buf_ll_src(ibuf)); - } - - /* Destination address */ - /* put the destination address compression mode into tmp */ - tmp = ((iphc1 & SICSLOWPAN_IPHC_DAM_11) >> SICSLOWPAN_IPHC_DAM_BIT) & 0x03; - - /* multicast compression */ - if(iphc1 & SICSLOWPAN_IPHC_M) { - /* context based multicast compression */ - if(iphc1 & SICSLOWPAN_IPHC_DAC) { - /* TODO: implement this */ - } else { - /* non-context based multicast compression - */ - /* DAM_00: 128 bits */ - /* DAM_01: 48 bits FFXX::00XX:XXXX:XXXX */ - /* DAM_10: 32 bits FFXX::00XX:XXXX */ - /* DAM_11: 8 bits FF02::00XX */ - uint8_t prefix[] = {0xff, 0x02}; - if(tmp > 0 && tmp < 3) { - prefix[1] = *iphc_ptr; - iphc_ptr++; - } - - uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, prefix, - unc_mxconf[tmp], NULL); - } - } else { - /* no multicast */ - /* Context based */ - if(iphc1 & SICSLOWPAN_IPHC_DAC) { - uint8_t dci = (iphc1 & SICSLOWPAN_IPHC_CID) ? - PACKETBUF_IPHC_BUF(mbuf)[2] & 0x0f : 0; - context = addr_context_lookup_by_number(dci); - - /* all valid cases below need the context! */ - if(context == NULL) { - PRINTF("sicslowpan uncompress_hdr: error context not found\n"); - return 0; - } - uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, context->prefix, - unc_ctxconf[tmp], (uip_lladdr_t *)&ip_buf_ll_dest(ibuf)); - } else { - /* not context based => link local M = 0, DAC = 0 - same as SAC */ - uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, llprefix, - unc_llconf[tmp], - (uip_lladdr_t *)&ip_buf_ll_dest(ibuf)); - } - } - uip_uncomp_hdr_len(mbuf) += UIP_IPH_LEN; - - /* Next header processing - continued */ - if((iphc0 & SICSLOWPAN_IPHC_NH_C)) { - /* The next header is compressed, NHC is following */ - if((*iphc_ptr & SICSLOWPAN_NHC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) { - uint8_t checksum_compressed; - SICSLOWPAN_IP_BUF(buf)->proto = UIP_PROTO_UDP; - checksum_compressed = *iphc_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC; - PRINTF("IPHC: Incoming header value: %x\n", *iphc_ptr); - switch(*iphc_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) { - case SICSLOWPAN_NHC_UDP_CS_P_00: - /* 1 byte for NHC, 4 byte for ports, 2 bytes chksum */ - memcpy(&SICSLOWPAN_UDP_BUF(buf)->srcport, iphc_ptr + 1, 2); - memcpy(&SICSLOWPAN_UDP_BUF(buf)->destport, iphc_ptr + 3, 2); - PRINTF("IPHC: Uncompressed UDP ports (ptr+5): %x, %x\n", - UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport)); - iphc_ptr += 5; - break; - - case SICSLOWPAN_NHC_UDP_CS_P_01: - /* 1 byte for NHC + source 16bit inline, dest = 0xF0 + 8 bit inline */ - PRINTF("IPHC: Decompressing destination\n"); - memcpy(&SICSLOWPAN_UDP_BUF(buf)->srcport, iphc_ptr + 1, 2); - SICSLOWPAN_UDP_BUF(buf)->destport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(iphc_ptr + 3))); - PRINTF("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n", - UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport)); - iphc_ptr += 4; - break; - - case SICSLOWPAN_NHC_UDP_CS_P_10: - /* 1 byte for NHC + source = 0xF0 + 8bit inline, dest = 16 bit inline*/ - PRINTF("IPHC: Decompressing source\n"); - SICSLOWPAN_UDP_BUF(buf)->srcport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + - (*(iphc_ptr + 1))); - memcpy(&SICSLOWPAN_UDP_BUF(buf)->destport, iphc_ptr + 2, 2); - PRINTF("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n", - UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport)); - iphc_ptr += 4; - break; - - case SICSLOWPAN_NHC_UDP_CS_P_11: - /* 1 byte for NHC, 1 byte for ports */ - SICSLOWPAN_UDP_BUF(buf)->srcport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN + - (*(iphc_ptr + 1) >> 4)); - SICSLOWPAN_UDP_BUF(buf)->destport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN + - ((*(iphc_ptr + 1)) & 0x0F)); - PRINTF("IPHC: Uncompressed UDP ports (ptr+2): %x, %x\n", - UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport)); - iphc_ptr += 2; - break; - - default: - PRINTF("sicslowpan uncompress_hdr: error unsupported UDP compression\n"); - return 0; - } - if(!checksum_compressed) { /* has_checksum, default */ - memcpy(&SICSLOWPAN_UDP_BUF(buf)->udpchksum, iphc_ptr, 2); - iphc_ptr += 2; - PRINTF("IPHC: sicslowpan uncompress_hdr: checksum included\n"); - } else { - PRINTF("IPHC: sicslowpan uncompress_hdr: checksum *NOT* included\n"); - } - uip_uncomp_hdr_len(mbuf) += UIP_UDPH_LEN; - } - } - - uip_packetbuf_hdr_len(mbuf) = iphc_ptr - uip_packetbuf_ptr(mbuf); - - if(uip_first_frag_len(ibuf) > 0) { - ip_len = uip_len(ibuf) - UIP_IPH_LEN; - } else { - ip_len = uip_len(ibuf) + uip_uncomp_hdr_len(mbuf) - - uip_packetbuf_hdr_len(mbuf) - UIP_IPH_LEN; - } - - SICSLOWPAN_IP_BUF(buf)->len[0] = ip_len >> 8; - SICSLOWPAN_IP_BUF(buf)->len[1] = ip_len & 0x00FF; - - /* length field in UDP header */ - if(SICSLOWPAN_IP_BUF(buf)->proto == UIP_PROTO_UDP) { - memcpy(&SICSLOWPAN_UDP_BUF(buf)->udplen, &SICSLOWPAN_IP_BUF(buf)->len[0], 2); - } - - packetbuf_copyfrom(mbuf, buf, sizeof(buf)); - - return 1; -} -/** @} */ -#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPHC */ - -/*--------------------------------------------------------------------*/ -/** \name IPv6 dispatch "compression" function - * @{ */ -/*--------------------------------------------------------------------*/ -/* \brief Packets "Compression" when only IPv6 dispatch is used - * - * There is no compression in this case, all fields are sent - * inline. We just add the IPv6 dispatch byte before the packet. - * \verbatim - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | IPv6 Dsp | IPv6 header and payload ... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * \endverbatim - */ -static int -compress_hdr_ipv6(struct net_buf *buf) -{ - memmove(uip_buf(buf) + SICSLOWPAN_IPV6_HDR_LEN, uip_buf(buf), uip_len(buf)); - *uip_buf(buf) = SICSLOWPAN_DISPATCH_IPV6; - uip_len(buf)++; - ip_buf_len(buf)++; - uip_compressed_hdr_len(buf) = UIP_IPH_LEN + SICSLOWPAN_IPV6_HDR_LEN; - uip_uncompressed_hdr_len(buf) = UIP_IPH_LEN; - return 1; -} -/** @} */ - -/* Just remove the IPv6 Dispatch */ -static int -uncompress_hdr_ipv6(struct net_buf *buf) -{ - uip_len(buf)--; - ip_buf_len(buf)--; - memmove(uip_buf(buf), uip_buf(buf) + SICSLOWPAN_IPV6_HDR_LEN, uip_len(buf)); - return 1; -} - -/*--------------------------------------------------------------------*/ -/** \name Input/output functions common to all compression schemes - * @{ */ -/*--------------------------------------------------------------------*/ - -static int compress(struct net_buf *buf) -{ - uint8_t hdr_diff; - struct net_buf *mbuf; - int ret; - -#if UIP_TCP - if(UIP_IP_BUF(buf)->proto == UIP_PROTO_TCP) { - /* Right now do not touch TCP packets. Because we modify the IPv6 header - * then the packet cannot be re-sent properly later. To be fixed later. - */ - return 1; - } -#endif - - if(uip_len(buf) >= COMPRESSION_THRESHOLD) { -#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 - return compress_hdr_ipv6(buf); -#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 */ - } else { - return compress_hdr_ipv6(buf); - } - - mbuf = l2_buf_get_reserve(0); - if (!mbuf) { - return 0; - } - - /* init */ - uip_uncomp_hdr_len(mbuf) = 0; - uip_packetbuf_hdr_len(mbuf) = 0; - /* reset packetbuf buffer */ - packetbuf_clear(mbuf); - uip_packetbuf_ptr(mbuf) = packetbuf_dataptr(mbuf); - - /* Compress the headers */ -#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPHC - ret = compress_hdr_iphc(mbuf, buf, &ip_buf_ll_dest(buf)); -#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPHC */ - - /* if IPHC compression fails then send uncompressed ipv6 packet */ - if (!ret) { - l2_buf_unref(mbuf); - PRINTF("sending uncompressed IPv6 packet\n"); - return compress_hdr_ipv6(buf); - return 0; - } - - PRINTF("compress: compressed hdr len %d, uncompressed hdr len %d\n", - uip_packetbuf_hdr_len(mbuf), uip_uncomp_hdr_len(mbuf)); - hdr_diff = uip_uncomp_hdr_len(mbuf) - uip_packetbuf_hdr_len(mbuf); - memcpy(uip_buf(buf), uip_packetbuf_ptr(mbuf), uip_packetbuf_hdr_len(mbuf)); - memmove(uip_buf(buf) + uip_packetbuf_hdr_len(mbuf), - uip_buf(buf) + uip_uncomp_hdr_len(mbuf), uip_len(buf) - uip_uncomp_hdr_len(mbuf)); - uip_len(buf) -= hdr_diff; - ip_buf_len(buf) -= hdr_diff; - uip_compressed_hdr_len(buf) = uip_packetbuf_hdr_len(mbuf); - uip_uncompressed_hdr_len(buf) = uip_uncomp_hdr_len(mbuf); - packetbuf_clear(mbuf); - l2_buf_unref(mbuf); - return 1; -} - -static int uncompress(struct net_buf *buf) -{ - struct net_buf *mbuf; - - if (*uip_buf(buf) == SICSLOWPAN_DISPATCH_IPV6) { - return uncompress_hdr_ipv6(buf); - } - - mbuf = l2_buf_get_reserve(0); - if (!mbuf) { - return 0; - } - - /* init */ - uip_uncomp_hdr_len(mbuf) = 0; - uip_packetbuf_hdr_len(mbuf) = 0; - packetbuf_copyfrom(mbuf, uip_buf(buf), UIP_IPUDPH_LEN); /* Size of (IP + UDP) header*/ - uip_packetbuf_ptr(mbuf) = packetbuf_dataptr(mbuf); - -#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPHC - if((PACKETBUF_HC1_PTR(mbuf)[PACKETBUF_HC1_DISPATCH] & 0xe0) == SICSLOWPAN_DISPATCH_IPHC) { - PRINTF("uncompress: IPHC\n"); - if(!uncompress_hdr_iphc(mbuf, buf)) { - goto fail; - } - } else -#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPHC */ - { - /* unknown header */ - PRINTF("uncompress: unknown dispatch: %x--%x\n", - PACKETBUF_HC1_PTR(mbuf)[PACKETBUF_HC1_DISPATCH], *uip_buf(buf)); - goto fail; - } - -#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPHC - /* Check if memmove would go past the end of the buffer */ - if ((uip_uncomp_hdr_len(mbuf) - uip_packetbuf_hdr_len(mbuf)) > - net_buf_tailroom(buf)) { - PRINTF("uncompress: not enough space to store uncompressed headers\n"); - goto fail; - } - - /* If the packet contains some garbage, then it is possible that - * the frame checker and fragmenter might still have accepted it. - * We need to check here that the memmove() will contain sane length - * value. - */ - if (uip_len(buf) <= uip_packetbuf_hdr_len(mbuf)) { - PRINTF("uncompress: buf len (%d) <= hdr len (%d), packet discarded.\n", - uip_len(buf), uip_packetbuf_hdr_len(mbuf)); - goto fail; - } - -#if defined(CONFIG_NETWORKING_WITH_15_4) - if (uip_first_frag_len(buf) > 0) { - memmove(uip_buf(buf) + uip_uncomp_hdr_len(mbuf), - uip_buf(buf) + uip_packetbuf_hdr_len(mbuf), - uip_first_frag_len(buf) - uip_packetbuf_hdr_len(mbuf)); - memcpy(uip_buf(buf), uip_packetbuf_ptr(mbuf), uip_uncomp_hdr_len(mbuf)); - ip_buf_len(buf) = uip_len(buf); - } else { - memmove(uip_buf(buf) + uip_uncomp_hdr_len(mbuf), - uip_buf(buf) + uip_packetbuf_hdr_len(mbuf), - uip_len(buf) - uip_packetbuf_hdr_len(mbuf)); - memcpy(uip_buf(buf), uip_packetbuf_ptr(mbuf), uip_uncomp_hdr_len(mbuf)); - uip_len(buf) += (uip_uncomp_hdr_len(mbuf) - uip_packetbuf_hdr_len(mbuf)); - ip_buf_len(buf) += (uip_uncomp_hdr_len(mbuf) - uip_packetbuf_hdr_len(mbuf)); - } -#elif defined(CONFIG_NETWORKING_WITH_BT) - memmove(uip_buf(buf) + uip_uncomp_hdr_len(mbuf), - uip_buf(buf) + uip_packetbuf_hdr_len(mbuf), - uip_len(buf) - uip_packetbuf_hdr_len(mbuf)); - memcpy(uip_buf(buf), uip_packetbuf_ptr(mbuf), uip_uncomp_hdr_len(mbuf)); - uip_len(buf) += (uip_uncomp_hdr_len(mbuf) - uip_packetbuf_hdr_len(mbuf)); - ip_buf_len(buf) += (uip_uncomp_hdr_len(mbuf) - uip_packetbuf_hdr_len(mbuf)); -#endif -#endif - - l2_buf_unref(mbuf); - return 1; - -fail: - l2_buf_unref(mbuf); - return 0; -} - -static void init(void) -{ -#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPHC -/* Preinitialize any address contexts for better header compression - * (Saves up to 13 bytes per 6lowpan packet) - * The platform contiki-conf.h file can override this using e.g. - * #define SICSLOWPAN_CONF_ADDR_CONTEXT_0 {addr_contexts[0].prefix[0]=0xbb;addr_contexts[0].prefix[1]=0xbb;} - */ -#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 - addr_contexts[0].used = 1; - addr_contexts[0].number = 0; -#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_0 - SICSLOWPAN_CONF_ADDR_CONTEXT_0; -#else - addr_contexts[0].prefix[0] = 0xaa; - addr_contexts[0].prefix[1] = 0xaa; -#endif -#endif /* SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 */ - -#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 1 - { - int i; - for(i = 1; i < SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; i++) { -#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_1 - if (i==1) { - addr_contexts[1].used = 1; - addr_contexts[1].number = 1; - SICSLOWPAN_CONF_ADDR_CONTEXT_1; -#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_2 - } else if (i==2) { - addr_contexts[2].used = 1; - addr_contexts[2].number = 2; - SICSLOWPAN_CONF_ADDR_CONTEXT_2; -#endif - } else { - addr_contexts[i].used = 0; - } -#else - addr_contexts[i].used = 0; -#endif /* SICSLOWPAN_CONF_ADDR_CONTEXT_1 */ - - } - } -#endif /* SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 1 */ - -#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 */ - -} - -const struct compression sicslowpan_compression = { - .init = init, - .compress = compress, - .uncompress = uncompress -}; diff --git a/net/ip/contiki/sicslowpan/sicslowpan_compression.h b/net/ip/contiki/sicslowpan/sicslowpan_compression.h deleted file mode 100644 index d616228b2be16a67e5a0643490eb0a74d4aa6a4c..0000000000000000000000000000000000000000 --- a/net/ip/contiki/sicslowpan/sicslowpan_compression.h +++ /dev/null @@ -1,268 +0,0 @@ -/* sicslowpan_compression.h - IPv6 header Compression */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Copyright (c) 2008, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * 6lowpan implementation (RFC4944 and draft-ietf-6lowpan-hc-06) - * - * \author Adam Dunkels - * \author Nicolas Tsiftes - * \author Niclas Finne - * \author Mathilde Durvy - * \author Julien Abeille - * \author Joakim Eriksson - * \author Joel Hoglund - */ - -#ifndef SICSLOWPAN_COMPRESSION_H_ -#define SICSLOWPAN_COMPRESSION_H_ - -#include "contiki/sicslowpan/compression.h" - -extern const struct compression sicslowpan_compression; - -/** - * \name General sicslowpan defines - * @{ - */ -/* Min and Max compressible UDP ports - IPHC */ -#define SICSLOWPAN_UDP_4_BIT_PORT_MIN 0xF0B0 -#define SICSLOWPAN_UDP_4_BIT_PORT_MAX 0xF0BF /* F0B0 + 15 */ -#define SICSLOWPAN_UDP_8_BIT_PORT_MIN 0xF000 -#define SICSLOWPAN_UDP_8_BIT_PORT_MAX 0xF0FF /* F000 + 255 */ - -/** @} */ - -/** - * \name 6lowpan compressions - * @{ - */ -#define SICSLOWPAN_COMPRESSION_IPV6 0 -#define SICSLOWPAN_COMPRESSION_HC1 1 -#define SICSLOWPAN_COMPRESSION_IPHC 2 -/** @} */ - -/** - * \name 6lowpan dispatches - * @{ - */ -#define SICSLOWPAN_DISPATCH_IPV6 0x41 /* 01000001 = 65 */ -#define SICSLOWPAN_DISPATCH_HC1 0x42 /* 01000010 = 66 */ -#define SICSLOWPAN_DISPATCH_IPHC 0x60 /* 011xxxxx = ... */ -#define SICSLOWPAN_DISPATCH_FRAG1 0xc0 /* 11000xxx */ -#define SICSLOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx */ -/** @} */ - -/** - * \name IPHC encoding - * @{ - */ -/* - * Values of fields within the IPHC encoding first byte - * (C stands for compressed and I for inline) - */ -#define SICSLOWPAN_IPHC_FL_C 0x10 -#define SICSLOWPAN_IPHC_TC_C 0x08 -#define SICSLOWPAN_IPHC_NH_C 0x04 -#define SICSLOWPAN_IPHC_TTL_1 0x01 -#define SICSLOWPAN_IPHC_TTL_64 0x02 -#define SICSLOWPAN_IPHC_TTL_255 0x03 -#define SICSLOWPAN_IPHC_TTL_I 0x00 - - -/* Values of fields within the IPHC encoding second byte */ -#define SICSLOWPAN_IPHC_CID 0x80 - -#define SICSLOWPAN_IPHC_SAC 0x40 -#define SICSLOWPAN_IPHC_SAM_00 0x00 -#define SICSLOWPAN_IPHC_SAM_01 0x10 -#define SICSLOWPAN_IPHC_SAM_10 0x20 -#define SICSLOWPAN_IPHC_SAM_11 0x30 - -#define SICSLOWPAN_IPHC_SAM_BIT 4 - -#define SICSLOWPAN_IPHC_M 0x08 -#define SICSLOWPAN_IPHC_DAC 0x04 -#define SICSLOWPAN_IPHC_DAM_00 0x00 -#define SICSLOWPAN_IPHC_DAM_01 0x01 -#define SICSLOWPAN_IPHC_DAM_10 0x02 -#define SICSLOWPAN_IPHC_DAM_11 0x03 - -#define SICSLOWPAN_IPHC_DAM_BIT 0 - -/* Link local context number */ -#define SICSLOWPAN_IPHC_ADDR_CONTEXT_LL 0 -/* 16-bit multicast addresses compression */ -#define SICSLOWPAN_IPHC_MCAST_RANGE 0xA0 -/** @} */ - -/* NHC_EXT_HDR */ -#define SICSLOWPAN_NHC_MASK 0xF0 -#define SICSLOWPAN_NHC_EXT_HDR 0xE0 - -/** - * \name LOWPAN_UDP encoding (works together with IPHC) - * @{ - */ -/** - * \name LOWPAN_UDP encoding (works together with IPHC) - * @{ - */ -#define SICSLOWPAN_NHC_UDP_MASK 0xF8 -#define SICSLOWPAN_NHC_UDP_ID 0xF0 -#define SICSLOWPAN_NHC_UDP_CHECKSUMC 0x04 -#define SICSLOWPAN_NHC_UDP_CHECKSUMI 0x00 -/* values for port compression, _with checksum_ ie bit 5 set to 0 */ -#define SICSLOWPAN_NHC_UDP_CS_P_00 0xF0 /* all inline */ -#define SICSLOWPAN_NHC_UDP_CS_P_01 0xF1 /* source 16bit inline, dest = 0xF0 + 8 bit inline */ -#define SICSLOWPAN_NHC_UDP_CS_P_10 0xF2 /* source = 0xF0 + 8bit inline, dest = 16 bit inline */ -#define SICSLOWPAN_NHC_UDP_CS_P_11 0xF3 /* source & dest = 0xF0B + 4bit inline */ -/** @} */ - - -/** - * \name The 6lowpan "headers" length - * @{ - */ - -#define SICSLOWPAN_IPV6_HDR_LEN 1 /*one byte*/ -#define SICSLOWPAN_HC1_HDR_LEN 3 -#define SICSLOWPAN_HC1_HC_UDP_HDR_LEN 7 -#define SICSLOWPAN_FRAG1_HDR_LEN 4 -#define SICSLOWPAN_FRAGN_HDR_LEN 5 -/** @} */ - -/** - * \brief An address context for IPHC address compression - * each context can have upto 8 bytes - */ -struct sicslowpan_addr_context { - uint8_t used; /* possibly use as prefix-length */ - uint8_t number; - uint8_t prefix[8]; -}; - -/** - * \name Address compressibility test functions - * @{ - */ - -/** - * \brief check whether we can compress the IID in - * address 'a' to 16 bits. - * This is used for unicast addresses only, and is true - * if the address is on the format \::0000:00ff:fe00:XXXX - * NOTE: we currently assume 64-bits prefixes - */ -#define sicslowpan_is_iid_16_bit_compressable(a) \ - ((((a)->u16[4]) == 0) && \ - (((a)->u8[10]) == 0)&& \ - (((a)->u8[11]) == 0xff)&& \ - (((a)->u8[12]) == 0xfe)&& \ - (((a)->u8[13]) == 0)) - -/** - * \brief check whether the 9-bit group-id of the - * compressed multicast address is known. It is true - * if the 9-bit group is the all nodes or all routers - * group. - * \param a is typed uint8_t * - */ -#define sicslowpan_is_mcast_addr_decompressable(a) \ - (((*a & 0x01) == 0) && \ - ((*(a + 1) == 0x01) || (*(a + 1) == 0x02))) - -/** - * \brief check whether the 112-bit group-id of the - * multicast address is mappable to a 9-bit group-id - * It is true if the group is the all nodes or all - * routers group. - */ -#define sicslowpan_is_mcast_addr_compressable(a) \ - ((((a)->u16[1]) == 0) && \ - (((a)->u16[2]) == 0) && \ - (((a)->u16[3]) == 0) && \ - (((a)->u16[4]) == 0) && \ - (((a)->u16[5]) == 0) && \ - (((a)->u16[6]) == 0) && \ - (((a)->u8[14]) == 0) && \ - ((((a)->u8[15]) == 1) || (((a)->u8[15]) == 2))) - -/* FFXX::00XX:XXXX:XXXX */ -#define sicslowpan_is_mcast_addr_compressable48(a) \ - ((((a)->u16[1]) == 0) && \ - (((a)->u16[2]) == 0) && \ - (((a)->u16[3]) == 0) && \ - (((a)->u16[4]) == 0) && \ - (((a)->u8[10]) == 0)) - -/* FFXX::00XX:XXXX */ -#define sicslowpan_is_mcast_addr_compressable32(a) \ - ((((a)->u16[1]) == 0) && \ - (((a)->u16[2]) == 0) && \ - (((a)->u16[3]) == 0) && \ - (((a)->u16[4]) == 0) && \ - (((a)->u16[5]) == 0) && \ - (((a)->u8[12]) == 0)) - -/* FF02::00XX */ -#define sicslowpan_is_mcast_addr_compressable8(a) \ - ((((a)->u8[1]) == 2) && \ - (((a)->u16[1]) == 0) && \ - (((a)->u16[2]) == 0) && \ - (((a)->u16[3]) == 0) && \ - (((a)->u16[4]) == 0) && \ - (((a)->u16[5]) == 0) && \ - (((a)->u16[6]) == 0) && \ - (((a)->u8[14]) == 0)) - -/** @} */ - -#endif /* SICSLOWPAN_COMPRESSION_H_ */ diff --git a/net/ip/contiki/sicslowpan/sicslowpan_fragmentation.c b/net/ip/contiki/sicslowpan/sicslowpan_fragmentation.c deleted file mode 100644 index 07d7cb476aa41e4e71223259bf186ec3f45dfee8..0000000000000000000000000000000000000000 --- a/net/ip/contiki/sicslowpan/sicslowpan_fragmentation.c +++ /dev/null @@ -1,792 +0,0 @@ -/* sicslowpan_fragmentation.c - 802.15.4 6lowpan packet fragmentation */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Copyright (c) 2008, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * 6lowpan implementation (RFC4944 and draft-ietf-6lowpan-hc-06) - * - * \author Adam Dunkels - * \author Nicolas Tsiftes - * \author Niclas Finne - * \author Mathilde Durvy - * \author Julien Abeille - * \author Joakim Eriksson - * \author Joel Hoglund - */ - -#include -#include - -#include -#include -#include "contiki/sicslowpan/sicslowpan_fragmentation.h" -#include "contiki/netstack.h" -#include "contiki/packetbuf.h" -#include "contiki/queuebuf.h" -#include "contiki/ip/uip.h" -#include "contiki/ip/tcpip.h" -#include "dev/watchdog.h" - -#include "contiki/ipv6/uip-ds6-nbr.h" - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_15_4_6LOWPAN_FRAG -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#if DEBUG -#define PRINTPACKETBUF() do { uint8_t p; PRINTF("packetbuf buffer: "); for(p = 0; p < packetbuf_datalen(); p++){PRINTF("%.2X", *(packetbuf_ptr + p));} PRINTF("\n"); } while(0) -#define PRINTUIPBUF() do { uint8_t p; PRINTF("UIP buffer: "); for(p = 0; p < uip_len; p++){PRINTF("%.2X", uip_buf[p]);}PRINTF("\n"); } while(0) -#define PRINTSICSLOWPANBUF() do { uint8_t p; PRINTF("SICSLOWPAN buffer: "); for(p = 0; p < sicslowpan_len; p++){PRINTF("%.2X", sicslowpan_buf[p]);}PRINTF("\n"); } while(0) -#else -#define PRINTPACKETBUF() -#define PRINTUIPBUF() -#define PRINTSICSLOWPANBUF() -#endif /* DEBUG == 1*/ - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif /* UIP_LOGGING == 1 */ - -#define GET16(ptr,index) (((uint16_t)((ptr)[index] << 8)) | ((ptr)[(index) + 1])) -#define SET16(ptr,index,value) do { \ - (ptr)[index] = ((value) >> 8) & 0xff; \ - (ptr)[index + 1] = (value) & 0xff; \ -} while(0) - -/** \name Pointers in the packetbuf buffer - * @{ - */ -//#define PACKETBUF_FRAG_PTR (packetbuf_ptr) -#define PACKETBUF_FRAG_DISPATCH_SIZE 0 /* 16 bit */ -#define PACKETBUF_FRAG_TAG 2 /* 16 bit */ -#define PACKETBUF_FRAG_OFFSET 4 /* 8 bit */ - -/** \name Pointers in the sicslowpan and uip buffer - * @{ - */ - -/* NOTE: In the multiple-reassembly context there is only room for the header / first fragment */ -#define SICSLOWPAN_IP_BUF(buf) ((struct uip_ip_hdr *)&sicslowpan_buf(buf)[UIP_LLH_LEN]) -#define SICSLOWPAN_UDP_BUF(buf) ((struct uip_udp_hdr *)&sicslowpan_buf(buf)[UIP_LLIPH_LEN]) - -#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) -#define UIP_UDP_BUF(buf) ((struct uip_udp_hdr *)&uip_buf(buf)[UIP_LLIPH_LEN]) -#define UIP_TCP_BUF(buf) ((struct uip_tcp_hdr *)&uip_buf(buf)[UIP_LLIPH_LEN]) -#define UIP_ICMP_BUF(buf) ((struct uip_icmp_hdr *)&uip_buf(buf)[UIP_LLIPH_LEN]) -/** @} */ - -#define sicslowpan_buf uip_buf -#define sicslowpan_len uip_len - -#ifdef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_MAX_MAC_TRANSMISSIONS SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#else -#define SICSLOWPAN_MAX_MAC_TRANSMISSIONS 4 -#endif - -/** \brief Maximum available size for frame headers, - link layer security-related overhead, as well as - 6LoWPAN payload. */ -#ifdef SICSLOWPAN_CONF_MAC_MAX_PAYLOAD -#define MAC_MAX_PAYLOAD SICSLOWPAN_CONF_MAC_MAX_PAYLOAD -#else /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */ -#define MAC_MAX_PAYLOAD (127 - 2) -#endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */ - -#define SICSLOWPAN_DISPATCH_IPV6 0x41 /* 01000001 = 65 */ - -static int last_rssi; - -/** Datagram tag to be put in the fragments I send. */ -static uint16_t my_tag; - -/* This needs to be defined in NBR / Nodes depending on available RAM */ -/* and expected reassembly requirements */ -#ifdef SICSLOWPAN_CONF_FRAGMENT_BUFFERS -#define SICSLOWPAN_FRAGMENT_BUFFERS SICSLOWPAN_CONF_FRAGMENT_BUFFERS -#else -#define SICSLOWPAN_FRAGMENT_BUFFERS 16 -#endif - -/* REASS_CONTEXTS corresponds to the number of simultaneous */ -/* reassemblys that can be made. */ -#ifdef SICSLOWPAN_CONF_REASS_CONTEXTS -#define SICSLOWPAN_REASS_CONTEXTS SICSLOWPAN_CONF_REASS_CONTEXTS -#else -#define SICSLOWPAN_REASS_CONTEXTS 2 -#endif - -/* The size of each fragment (IP payload) for the 6lowpan fragmentation */ -#ifdef SICSLOWPAN_CONF_FRAGMENT_SIZE -#define SICSLOWPAN_FRAGMENT_SIZE SICSLOWPAN_CONF_FRAGMENT_SIZE -#else -#define SICSLOWPAN_FRAGMENT_SIZE 110 -#endif - -/* Assuming that the worst growth for uncompression is 38 bytes */ -#define SICSLOWPAN_FIRST_FRAGMENT_SIZE (SICSLOWPAN_FRAGMENT_SIZE + 38) - -/* all information needed for reassembly */ -struct sicslowpan_frag_info { - /** When reassembling, the source address of the fragments being merged */ - linkaddr_t sender; - /** The destination address of the fragments being merged */ - linkaddr_t receiver; - /** When reassembling, the tag in the fragments being merged. */ - uint16_t tag; - /** Total length of the fragmented packet */ - uint16_t len; - /** Current length of reassembled fragments */ - uint16_t reassembled_len; - /** Last fragment */ - uint8_t last_fragment; - /** Reassembly %process %timer. */ - struct timer reass_timer; -}; - -static struct sicslowpan_frag_info frag_info[SICSLOWPAN_REASS_CONTEXTS]; - -struct sicslowpan_frag_buf { - /* the index of the frag_info */ - uint8_t index; - /* Fragment offset */ - uint8_t offset; - /* Length of this fragment (if zero this buffer is not allocated) */ - uint8_t len; - uint8_t data[SICSLOWPAN_FRAGMENT_SIZE]; -}; - -static struct sicslowpan_frag_buf frag_buf[SICSLOWPAN_FRAGMENT_BUFFERS]; - -/*---------------------------------------------------------------------------*/ -static int -clear_fragments(uint8_t frag_info_index) -{ - int i, clear_count; - clear_count = 0; - frag_info[frag_info_index].len = 0; - for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) { - if(frag_buf[i].len > 0 && frag_buf[i].index == frag_info_index) { - /* deallocate the buffer */ - frag_buf[i].len = 0; - clear_count++; - } - } - return clear_count; -} -/*---------------------------------------------------------------------------*/ -static int -store_fragment(struct net_buf *mbuf, uint8_t index, uint8_t offset) -{ - int i; - for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) { - if(frag_buf[i].len == 0) { - /* copy over the data from packetbuf into the fragment buffer - * and store offset and len */ - frag_buf[i].offset = offset; /* frag offset */ - frag_buf[i].len = packetbuf_datalen(mbuf) - uip_packetbuf_hdr_len(mbuf); - frag_buf[i].index = index; - memcpy(frag_buf[i].data, uip_packetbuf_ptr(mbuf) + uip_packetbuf_hdr_len(mbuf), - packetbuf_datalen(mbuf) - uip_packetbuf_hdr_len(mbuf)); - - PRINTF("Fragment payload length: %d\n", frag_buf[i].len); - /* return the length of the stored fragment */ - return frag_buf[i].len; - } - } - /* failed */ - return -1; -} -/*---------------------------------------------------------------------------*/ -/* add a new fragment to the buffer */ -static int8_t -add_fragment(struct net_buf *mbuf, uint16_t tag, uint16_t frag_size, uint8_t offset) -{ - int i; - int len; - int8_t found = -1; - - if(offset == 0) { - /* This is a first fragment - check if we can add this */ - for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) { - /* clear all fragment info with expired timer to free all fragment buffers */ - if(frag_info[i].len > 0 && timer_expired(&frag_info[i].reass_timer)) { - clear_fragments(i); - } - - /* We use len as indication on used or not used */ - if(found < 0 && frag_info[i].len == 0) { - /* We remember the first free fragment info but must continue - the loop to free any other expired fragment buffers. */ - found = i; - } - } - - if(found < 0) { - PRINTF("*** Failed to store new fragment session - tag: %d\n", tag); - return -1; - } - - /* Found a free fragment info to store data in */ - frag_info[found].len = frag_size; - frag_info[found].tag = tag; - linkaddr_copy(&frag_info[found].sender, - packetbuf_addr(mbuf, PACKETBUF_ADDR_SENDER)); - linkaddr_copy(&frag_info[found].receiver, - packetbuf_addr(mbuf, PACKETBUF_ADDR_RECEIVER)); - - timer_set(&frag_info[found].reass_timer, SICSLOWPAN_REASS_MAXAGE * CLOCK_SECOND / 16); - i = found; - goto store; - } - - /* This is a N-fragment - should find the info */ - for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) { - if(frag_info[i].tag == tag && frag_info[i].len > 0 && - linkaddr_cmp(&frag_info[i].sender, packetbuf_addr(mbuf, PACKETBUF_ADDR_SENDER))) { - /* Tag and Sender match - this must be the correct info to store in */ - found = i; - break; - } - } - - if(found < 0) { - /* no entry found for storing the new fragment */ - PRINTF("*** Failed to store N-fragment - could not find session - tag: %d offset: %d\n", tag, offset); - return -1; - } - -store: - /* i is the index of the reassembly context */ - len = store_fragment(mbuf, i, offset); - if(len > 0) { - frag_info[i].reassembled_len += len; - if((offset << 3)+ len >= frag_size) { - frag_info[i].last_fragment = 1; - } else { - frag_info[i].last_fragment = 0; - } - return i; - } else { - /* should we also clear all fragments since we failed to store this fragment? */ - PRINTF("*** Failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag); - return -1; - } -} - -/*---------------------------------------------------------------------------*/ -/* Copy all the fragments that are associated with a specific context into uip */ -static struct net_buf *copy_frags2uip(int context) -{ - int i, total_len = 0; - struct net_buf *buf; - - buf = ip_buf_get_reserve_rx(0); - if(!buf) { - return NULL; - } - - /* Copy from the fragment context info buffer first */ - linkaddr_copy(&ip_buf_ll_dest(buf), &frag_info[context].receiver); - linkaddr_copy(&ip_buf_ll_src(buf), &frag_info[context].sender); - - for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) { - if(i == 0) { - uip_first_frag_len(buf) = frag_buf[i].len; - if(frag_buf[i].data[0] == SICSLOWPAN_DISPATCH_IPV6) { - memmove(frag_buf[i].data, frag_buf[i].data + 1, frag_buf[i].len - 1); - frag_buf[i].len -= 1; - uip_uncompressed(buf) = 1; - } else { - uip_uncompressed(buf) = 0; - } - } - /* And also copy all matching fragments */ - if(frag_buf[i].len > 0 && frag_buf[i].index == context) { - memcpy(uip_buf(buf) + (uint16_t)(frag_buf[i].offset << 3), - (uint8_t *)frag_buf[i].data, frag_buf[i].len); - total_len += frag_buf[i].len; - } - } - net_buf_add(buf, total_len); - uip_len(buf) = total_len; - - /* deallocate all the fragments for this context */ - clear_fragments(context); - - return buf; -} - -static struct net_buf *copy_buf(struct net_buf *mbuf) -{ - struct net_buf *buf; - - buf = ip_buf_get_reserve_rx(0); - if(!buf) { - return NULL; - } - - /* Copy from the fragment context info buffer first */ - linkaddr_copy(&ip_buf_ll_dest(buf), - packetbuf_addr(mbuf, PACKETBUF_ADDR_RECEIVER)); - linkaddr_copy(&ip_buf_ll_src(buf), - packetbuf_addr(mbuf, PACKETBUF_ADDR_SENDER)); - - PRINTF("%s: mbuf datalen %d dataptr %p buf %p\n", __FUNCTION__, - packetbuf_datalen(mbuf), packetbuf_dataptr(mbuf), uip_buf(buf)); - if(packetbuf_datalen(mbuf) > 0 && - packetbuf_datalen(mbuf) <= UIP_BUFSIZE - UIP_LLH_LEN) { - memcpy(uip_buf(buf), packetbuf_dataptr(mbuf), packetbuf_datalen(mbuf)); - uip_len(buf) = packetbuf_datalen(mbuf); - net_buf_add(buf, uip_len(buf)); - } else { - ip_buf_unref(buf); - buf = NULL; - } - - uip_first_frag_len(buf) = 0; - uip_uncompressed(buf) = 0; - return buf; -} - -static void -packet_sent(struct net_buf *buf, void *ptr, int status, int transmissions) -{ - const linkaddr_t *dest = packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER); - uip_ds6_link_neighbor_callback(dest, status, transmissions); - uip_last_tx_status(buf) = status; - l2_buf_unref(buf); -} - -/*--------------------------------------------------------------------*/ -/** - * \brief This function is called by the 6lowpan code to send out a - * packet. - * \param dest the link layer destination address of the packet - */ -static void -send_packet(struct net_buf *buf, linkaddr_t *dest, bool last_fragment, void *ptr) -{ - /* Set the link layer destination address for the packet as a - * packetbuf attribute. The MAC layer can access the destination - * address with the function packetbuf_addr(PACKETBUF_ADDR_RECEIVER). - */ - packetbuf_set_addr(buf, PACKETBUF_ADDR_RECEIVER, dest); - -#if NETSTACK_CONF_BRIDGE_MODE - /* This needs to be explicitly set here for bridge mode to work */ - packetbuf_set_addr(buf, PACKETBUF_ADDR_SENDER,(void*)&uip_lladdr); -#endif - - /* Force acknowledge from sender (test hardware autoacks) */ -#if SICSLOWPAN_CONF_ACK_ALL - packetbuf_set_attr(buf, PACKETBUF_ATTR_RELIABLE, 1); -#endif - - /* Provide a callback function to receive the result of - a packet transmission. */ - NETSTACK_LLSEC.send(buf, &packet_sent, last_fragment, ptr); - - /* If we are sending multiple packets in a row, we need to let the - watchdog know that we are still alive. */ - watchdog_periodic(); -} - -static int fragment(struct net_buf *buf, void *ptr) -{ - struct queuebuf *q; - int max_payload; - int framer_hdrlen; - uint16_t frag_tag; - uint16_t frag_offset; - int hdr_diff; - /* Number of bytes processed. */ - uint16_t processed_ip_out_len; - struct net_buf *mbuf; - bool last_fragment = false; - -#define USE_FRAMER_HDRLEN 0 -#if USE_FRAMER_HDRLEN - framer_hdrlen = NETSTACK_FRAMER.length(); - if(framer_hdrlen < 0) { - /* Framing failed, we assume the maximum header length */ - framer_hdrlen = 21; - } -#else /* USE_FRAMER_HDRLEN */ - framer_hdrlen = 21; -#endif /* USE_FRAMER_HDRLEN */ - max_payload = MAC_MAX_PAYLOAD - framer_hdrlen - NETSTACK_LLSEC.get_overhead(); - - PRINTF("max_payload: %d, framer_hdrlen: %d \n",max_payload, framer_hdrlen); - - mbuf = l2_buf_get_reserve(0); - if (!mbuf) { - goto fail; - } - uip_last_tx_status(mbuf) = MAC_TX_OK; - - /* - * The destination address will be tagged to each outbound - * packet. If the argument localdest is NULL, we are sending a - * broadcast packet. - */ - - if((int)uip_len(buf) <= max_payload) { - /* The packet does not need to be fragmented, send buf */ - packetbuf_copyfrom(mbuf, uip_buf(buf), uip_len(buf)); - send_packet(mbuf, &ip_buf_ll_dest(buf), true, ptr); - ip_buf_unref(buf); - return 1; - } - - uip_uncomp_hdr_len(mbuf) = 0; - uip_packetbuf_hdr_len(mbuf) = 0; - packetbuf_clear(mbuf); - uip_packetbuf_ptr(mbuf) = packetbuf_dataptr(mbuf); - - packetbuf_set_attr(mbuf, PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, - SICSLOWPAN_MAX_MAC_TRANSMISSIONS); - - PRINTF("fragmentation: total packet len %d\n", uip_len(buf)); - - /* - * The outbound IPv6 packet is too large to fit into a single 15.4 - * packet, so we fragment it into multiple packets and send them. - * The first fragment contains frag1 dispatch, then - * IPv6/HC1/HC06/HC_UDP dispatchs/headers. - * The following fragments contain only the fragn dispatch. - */ - int estimated_fragments = ((int)uip_len(buf)) / (max_payload - SICSLOWPAN_FRAGN_HDR_LEN) + 1; - int freebuf = queuebuf_numfree(mbuf) - 1; - PRINTF("uip_len: %d, fragments: %d, free bufs: %d\n", uip_len(buf), estimated_fragments, freebuf); - if(freebuf < estimated_fragments) { - PRINTF("Dropping packet, not enough free bufs\n"); - goto fail; - } - - hdr_diff = uip_uncompressed_hdr_len(buf) - uip_compressed_hdr_len(buf); - PRINTF("fragment: hdr difference %d\n", hdr_diff); - /* Create 1st Fragment */ - SET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_DISPATCH_SIZE, - ((SICSLOWPAN_DISPATCH_FRAG1 << 8) | (uip_len(buf) + hdr_diff))); - - frag_tag = my_tag++; - SET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_TAG, frag_tag); - PRINTF("fragment: tag %d \n", frag_tag); - - /* Copy payload and send */ - uip_packetbuf_hdr_len(mbuf) = uip_compressed_hdr_len(buf); - uip_packetbuf_hdr_len(mbuf) += SICSLOWPAN_FRAG1_HDR_LEN; - uip_packetbuf_payload_len(mbuf) = (max_payload - uip_packetbuf_hdr_len(mbuf)) & 0xf8; - PRINTF("fragment: payload len %d, hdr len %d, tag %d\n", - uip_packetbuf_payload_len(mbuf), uip_packetbuf_hdr_len(mbuf), frag_tag); - - memcpy(uip_packetbuf_ptr(mbuf) + SICSLOWPAN_FRAG1_HDR_LEN, - uip_buf(buf), uip_packetbuf_payload_len(mbuf) + - uip_packetbuf_hdr_len(mbuf)); - packetbuf_set_datalen(mbuf, uip_packetbuf_payload_len(mbuf) + uip_packetbuf_hdr_len(mbuf)); - PRINTF("fragment: packetbuf_datalen %d\n", packetbuf_datalen(mbuf)); - q = queuebuf_new_from_packetbuf(mbuf); - if(q == NULL) { - PRINTF("could not allocate queuebuf for first fragment, dropping packet\n"); - goto fail; - } - net_buf_ref(mbuf); - send_packet(mbuf, &ip_buf_ll_dest(buf), last_fragment, ptr); - queuebuf_to_packetbuf(mbuf, q); - queuebuf_free(q); - q = NULL; - - /* Check tx result. */ - if((uip_last_tx_status(mbuf) == MAC_TX_COLLISION) || - (uip_last_tx_status(mbuf) == MAC_TX_ERR) || - (uip_last_tx_status(mbuf) == MAC_TX_ERR_FATAL)) { - PRINTF("error in fragment tx, dropping subsequent fragments.\n"); - goto fail; - } - - /* set processed_ip_out_len to what we already sent from the IP payload*/ - processed_ip_out_len = uip_packetbuf_payload_len(mbuf) + uip_compressed_hdr_len(buf); - /* - * Create following fragments - * Datagram tag is already in the buffer, we need to set the - * FRAGN dispatch and for each fragment, the offset - */ - uip_packetbuf_hdr_len(mbuf) = SICSLOWPAN_FRAGN_HDR_LEN; - SET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_DISPATCH_SIZE, - ((SICSLOWPAN_DISPATCH_FRAGN << 8) | (uip_len(buf) + hdr_diff))); - uip_packetbuf_payload_len(mbuf) = (max_payload - uip_packetbuf_hdr_len(mbuf)) & 0xf8; - - while(processed_ip_out_len < uip_len(buf)) { - PRINTF("fragment: tag:%d, processed_ip_out_len:%d \n", frag_tag, processed_ip_out_len); - frag_offset = processed_ip_out_len + hdr_diff; - uip_packetbuf_ptr(mbuf)[PACKETBUF_FRAG_OFFSET] = frag_offset >> 3; - /* Copy payload and send */ - if(uip_len(buf) - processed_ip_out_len < uip_packetbuf_payload_len(mbuf)) { - /* last fragment */ - last_fragment = true; - uip_packetbuf_payload_len(mbuf) = uip_len(buf) - processed_ip_out_len; - } - PRINTF("fragment: offset %d, len %d, tag %d\n", - frag_offset, uip_packetbuf_payload_len(mbuf), frag_tag); - memcpy(uip_packetbuf_ptr(mbuf) + uip_packetbuf_hdr_len(mbuf), - (uint8_t *)UIP_IP_BUF(buf) + processed_ip_out_len, uip_packetbuf_payload_len(mbuf)); - packetbuf_set_datalen(mbuf, uip_packetbuf_payload_len(mbuf) + uip_packetbuf_hdr_len(mbuf)); - PRINTF("fragment: packetbuf_datalen %d\n", packetbuf_datalen(mbuf)); - q = queuebuf_new_from_packetbuf(mbuf); - if(q == NULL) { - PRINTF("could not allocate queuebuf, dropping fragment\n"); - goto fail; - } - net_buf_ref(mbuf); - send_packet(mbuf, &ip_buf_ll_dest(buf), last_fragment, ptr); - queuebuf_to_packetbuf(mbuf, q); - queuebuf_free(q); - q = NULL; - processed_ip_out_len += uip_packetbuf_payload_len(mbuf); - - /* Check tx result. */ - if((uip_last_tx_status(mbuf) == MAC_TX_COLLISION) || - (uip_last_tx_status(mbuf) == MAC_TX_ERR) || - (uip_last_tx_status(mbuf) == MAC_TX_ERR_FATAL)) { - PRINTF("error in fragment tx, dropping subsequent fragments.\n"); - goto fail; - } - } - - ip_buf_unref(buf); - l2_buf_unref(mbuf); - return 1; - -fail: - if (mbuf) { - l2_buf_unref(mbuf); - } - return 0; -} - -static int reassemble(struct net_buf *mbuf) -{ - /* size of the IP packet (read from fragment) */ - uint16_t frag_size = 0; - int8_t frag_context = 0; - /* offset of the fragment in the IP packet */ - uint8_t frag_offset = 0; - uint8_t is_fragment = 0; - /* tag of the fragment */ - uint16_t frag_tag = 0; - uint8_t first_fragment = 0, last_fragment = 0; - struct net_buf *buf = NULL; - - /* init */ - uip_uncomp_hdr_len(mbuf) = 0; - uip_packetbuf_hdr_len(mbuf) = 0; - - /* The MAC puts the 15.4 payload inside the packetbuf data buffer */ - uip_packetbuf_ptr(mbuf) = packetbuf_dataptr(mbuf); - - /* Save the RSSI of the incoming packet in case the upper layer will - want to query us for it later. */ - last_rssi = (signed short)packetbuf_attr(mbuf, PACKETBUF_ATTR_RSSI); - - /* - * Since we don't support the mesh and broadcast header, the first header - * we look for is the fragmentation header - */ - switch((GET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_DISPATCH_SIZE) & 0xf800) >> 8) { - case SICSLOWPAN_DISPATCH_FRAG1: - PRINTF("reassemble: FRAG1 "); - frag_offset = 0; - frag_size = GET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff; - frag_tag = GET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_TAG); - - PRINTF("size %d, tag %d, offset %d\n", frag_size, frag_tag, frag_offset); - - if (frag_size > IP_BUF_MAX_DATA) { - PRINTF("Too big packet %d bytes (max %d), fragment discarded\n", - frag_size, IP_BUF_MAX_DATA); - goto fail; - } - - uip_packetbuf_hdr_len(mbuf) += SICSLOWPAN_FRAG1_HDR_LEN; - first_fragment = 1; - is_fragment = 1; - - /* Add the fragment to the fragmentation context (this will also copy the payload)*/ - frag_context = add_fragment(mbuf, frag_tag, frag_size, frag_offset); - if(frag_context == -1) { - goto fail; - } - - break; - - case SICSLOWPAN_DISPATCH_FRAGN: - /* - * set offset, tag, size - * Offset is in units of 8 bytes - */ - PRINTF("reassemble: FRAGN "); - frag_offset = uip_packetbuf_ptr(mbuf)[PACKETBUF_FRAG_OFFSET]; - frag_tag = GET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_TAG); - frag_size = GET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff; - - PRINTF("reassemble: size %d, tag %d, offset %d\n", frag_size, frag_tag, frag_offset); - - uip_packetbuf_hdr_len(mbuf) += SICSLOWPAN_FRAGN_HDR_LEN; - - /* If this is the last fragment, we may shave off any extrenous - bytes at the end. We must be liberal in what we accept. */ - /* Add the fragment to the fragmentation context (this will also copy the payload) */ - frag_context = add_fragment(mbuf, frag_tag, frag_size, frag_offset); - if(frag_context == -1) { - goto fail; - } - - if(frag_info[frag_context].reassembled_len >= frag_size - || frag_info[frag_context].last_fragment) { - last_fragment = 1; - } - is_fragment = 1; - break; - - default: - /* If there is no fragmentation header, then assume that the packet - * is not fragmented and pass it as is to IP stack. - */ - buf = copy_buf(mbuf); - if(!buf || net_driver_15_4_recv(buf) < 0) { - goto fail; - } - goto out; - } - - /* - * copy "payload" from the packetbuf buffer to the sicslowpan_buf - * if this is a first fragment or not fragmented packet, - * we have already copied the compressed headers, uncomp_hdr_len - * and packetbuf_hdr_len are non 0, frag_offset is. - * If this is a subsequent fragment, this is the contrary. - */ - if(packetbuf_datalen(mbuf) < uip_packetbuf_hdr_len(mbuf)) { - PRINTF("reassemble: packet dropped due to header > total packet\n"); - goto fail; - } - - uip_packetbuf_payload_len(mbuf) = packetbuf_datalen(mbuf) - uip_packetbuf_hdr_len(mbuf); - - /* Sanity-check size of incoming packet to avoid buffer overflow */ - { - int req_size = UIP_LLH_LEN + (uint16_t)(frag_offset << 3) - + uip_packetbuf_payload_len(mbuf); - - if(req_size > UIP_BUFSIZE) { - PRINTF("reassemble: packet dropped, minimum required IP_BUF size: %d+%d+%d=%d (current size: %d)\n", UIP_LLH_LEN, (uint16_t)(frag_offset << 3), - uip_packetbuf_payload_len(mbuf), req_size, UIP_BUFSIZE); - goto fail; - } - } - - if(frag_size > 0) { - /* Add the size of the header only for the first fragment. */ - if(first_fragment != 0) { - frag_info[frag_context].reassembled_len = uip_uncomp_hdr_len(mbuf) + uip_packetbuf_payload_len(mbuf); - } - - /* For the last fragment, we are OK if there is extrenous bytes at - the end of the packet. */ - if(last_fragment != 0) { - frag_info[frag_context].reassembled_len = frag_size; - /* copy to uip(net_buf) */ - buf = copy_frags2uip(frag_context); - if(!buf) - goto fail; - } - } - - /* - * If we have a full IP packet in sicslowpan_buf, deliver it to - * the IP stack - */ - if(!is_fragment || last_fragment) { - /* packet is in uip already - just set length */ - if(is_fragment != 0 && last_fragment != 0) { - uip_len(buf) = frag_size; - } else { - uip_len(buf) = uip_packetbuf_payload_len(mbuf) + uip_uncomp_hdr_len(mbuf); - } - - PRINTF("reassemble: IP packet ready (length %d)\n", uip_len(buf)); - - if(net_driver_15_4_recv(buf) < 0) { - goto fail; - } - } - -out: - /* free MAC buffer */ - l2_buf_unref(mbuf); - return 1; - -fail: - if(buf) { - ip_buf_unref(buf); - } - return 0; -} - -const struct fragmentation sicslowpan_fragmentation = { - fragment, - reassemble -}; diff --git a/net/ip/contiki/sicslowpan/sicslowpan_fragmentation.h b/net/ip/contiki/sicslowpan/sicslowpan_fragmentation.h deleted file mode 100644 index 7770f4c1f1b7258fecc47a6c29cdafaeecba46d9..0000000000000000000000000000000000000000 --- a/net/ip/contiki/sicslowpan/sicslowpan_fragmentation.h +++ /dev/null @@ -1,43 +0,0 @@ -/* sicslowpan_fragmentation.h - 802.15.4 6lowpan fragmentation */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SICSLOWPAN_FRAGMENTATION_H_ -#define SICSLOWPAN_FRAGMENTATION_H_ - -#include "contiki/sicslowpan/fragmentation.h" - -extern const struct fragmentation sicslowpan_fragmentation; - -/** - * \name 6lowpan dispatches - * @{ - */ -#define SICSLOWPAN_DISPATCH_FRAG1 0xc0 /* 11000xxx */ -#define SICSLOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx */ -/** @} */ - -/** - * \name The 6lowpan "headers" length - * @{ - */ - -#define SICSLOWPAN_FRAG1_HDR_LEN 4 -#define SICSLOWPAN_FRAGN_HDR_LEN 5 -/** @} */ - -#endif /* SICSLOWPAN_FRGAMENTATION_H_ */ diff --git a/net/ip/contiki/trickle/trickle-timer.c b/net/ip/contiki/trickle/trickle-timer.c deleted file mode 100644 index b7e9129cb9d15a6bb06f445f02898ad88f66f89c..0000000000000000000000000000000000000000 --- a/net/ip/contiki/trickle/trickle-timer.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright (c) 2012, George Oikonomou - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file - * Trickle timer library implementation. - * \author - * George Oikonomou - - */ - -/** - * \addtogroup trickle-timer - * @{ - */ - -#include - -#include "contiki-conf.h" -#include "trickle-timer.h" -#include "sys/ctimer.h" -#include "sys/cc.h" -#include "lib/random.h" -/*---------------------------------------------------------------------------*/ -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_TRICKLE -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -/*---------------------------------------------------------------------------*/ -/** - * \brief Wide randoms for platforms using a 4-byte wide clock - * (see ::TRICKLE_TIMER_WIDE_RAND) - */ -#if TRICKLE_TIMER_WIDE_RAND -#define tt_rand() wide_rand() -#else -#define tt_rand() random_rand() -#endif -/*---------------------------------------------------------------------------*/ -/* Declarations of variables of local interest */ -/*---------------------------------------------------------------------------*/ -static struct trickle_timer *loctt; /* Pointer to a struct for local use */ -static clock_time_t loc_clock; /* A local, general-purpose placeholder */ - -static void fire(struct net_buf *buf, void *ptr); -static void double_interval(struct net_buf *buf, void *ptr); -/*---------------------------------------------------------------------------*/ -/* Local utilities and functions to be used as ctimer callbacks */ -/*---------------------------------------------------------------------------*/ -#if TRICKLE_TIMER_WIDE_RAND -/* Returns a 4-byte wide, unsigned random number */ -static uint32_t -wide_rand(void) -{ - return ((uint32_t)random_rand() << 16 | random_rand()); -} -#endif -/*---------------------------------------------------------------------------*/ -/* - * Returns the maximum sane Imax value for a given Imin - * - * This function is a variant of a fairly standard 'Count Leading Zeros'. It - * has three flavours. The most suitable one for a specific platform can be - * configured by changing the value of TRICKLE_TIMER_CONF_MAX_IMAX_WIDTH - * in the platform's contiki-conf.h - */ -#if TRICKLE_TIMER_ERROR_CHECKING -static uint8_t -max_imax(clock_time_t value) -{ - uint8_t zeros = 0; -#if (TRICKLE_TIMER_MAX_IMAX_WIDTH==TRICKLE_TIMER_MAX_IMAX_GENERIC) - uint8_t i; - clock_time_t mask = 0xFFFF; - - value--; - - for(i = sizeof(clock_time_t) << 2; i > 0; i >>= 1) { - if((value & (mask <<= i)) == 0) { - zeros += i; - value <<= i; - } - } - -#elif (TRICKLE_TIMER_MAX_IMAX_WIDTH==TRICKLE_TIMER_MAX_IMAX_16_BIT) - if((value & 0xFF00) == 0) { - zeros += 8; - value <<= 8; - } - if((value & 0xF000) == 0) { - zeros += 4; - value <<= 4; - } - if((value & 0xC000) == 0) { - zeros += 2; - value <<= 2; - } - if((value & 0x8000) == 0) { - zeros++; - } -#elif (TRICKLE_TIMER_MAX_IMAX_WIDTH==TRICKLE_TIMER_MAX_IMAX_32_BIT) - if((value & 0xFFFF0000) == 0) { - zeros += 16; - value <<= 16; - } - if((value & 0xFF000000) == 0) { - zeros += 8; - value <<= 8; - } - if((value & 0xF0000000) == 0) { - zeros += 4; - value <<= 4; - } - if((value & 0xC0000000) == 0) { - zeros += 2; - value <<= 2; - } - if((value & 0x80000000) == 0) { - zeros += 1; - } -#endif - - return zeros - 1; /* Always non-negative due to the range of 'value' */ -} -#endif /* TRICKLE_TIMER_ERROR_CHECKING */ -/*---------------------------------------------------------------------------*/ -/* Returns a random time point t in [I/2 , I) */ -static clock_time_t -get_t(clock_time_t i_cur) -{ - i_cur >>= 1; - - PRINTF("trickle_timer get t: [%lu, %lu)\n", (unsigned long)i_cur, - (unsigned long)(i_cur << 1)); - - return i_cur + (tt_rand() % i_cur); -} -/*---------------------------------------------------------------------------*/ -static void -schedule_for_end(struct trickle_timer *tt) -{ - /* Reset our ctimer, schedule interval_end to run at time I */ - clock_time_t now = clock_time(); - - loc_clock = TRICKLE_TIMER_INTERVAL_END(tt) - now; - - PRINTF("trickle_timer sched for end: at %lu, end in %ld\n", - (unsigned long)clock_time(), (signed long)loc_clock); - - /* Interval's end will happen in loc_clock ticks. Make sure this isn't in - * the past... */ - if(loc_clock > (TRICKLE_TIMER_CLOCK_MAX >> 1)) { - loc_clock = 0; /* Interval ended in the past, schedule for in 0 */ - PRINTF("trickle_timer doubling: Was in the past. Compensating\n"); - } - - ctimer_set(NULL, &tt->ct, loc_clock, double_interval, tt); -} -/*---------------------------------------------------------------------------*/ -/* This is used as a ctimer callback, thus its argument must be void *. ptr is - * a pointer to the struct trickle_timer that fired */ -static void -double_interval(struct net_buf *buf, void *ptr) -{ - clock_time_t last_end; - - /* 'cast' ptr to a struct trickle_timer */ - loctt = (struct trickle_timer *)ptr; - - loctt->c = 0; - - PRINTF("trickle_timer doubling: at %lu, (was for %lu), ", - (unsigned long)clock_time(), - (unsigned long)TRICKLE_TIMER_INTERVAL_END(loctt)); - - /* Remember the previous interval's end (absolute time), before we double */ - last_end = TRICKLE_TIMER_INTERVAL_END(loctt); - - /* Double the interval if we have to */ - if(loctt->i_cur <= TRICKLE_TIMER_INTERVAL_MAX(loctt) >> 1) { - /* If I <= Imax/2, we double */ - loctt->i_cur <<= 1; - PRINTF("I << 1 = %lu\n", (unsigned long)loctt->i_cur); - } else { - /* We may have I > Imax/2 but I <> Imax, in which case we set to Imax - * This will happen when I didn't start as Imin (before the first reset) */ - loctt->i_cur = TRICKLE_TIMER_INTERVAL_MAX(loctt); - PRINTF("I = Imax = %lu\n", (unsigned long)loctt->i_cur); - } - - /* Random t in [I/2, I) */ - loc_clock = get_t(loctt->i_cur); - - PRINTF("trickle_timer doubling: t=%lu\n", (unsigned long)loc_clock); - -#if TRICKLE_TIMER_COMPENSATE_DRIFT - /* Schedule for t ticks after the previous interval's end, not after now. If - * that is in the past, schedule in 0 */ - loc_clock = (last_end + loc_clock) - clock_time(); - PRINTF("trickle_timer doubling: at %lu, in %ld ticks\n", - (unsigned long)clock_time(), (signed long)loc_clock); - if(loc_clock > (TRICKLE_TIMER_CLOCK_MAX >> 1)) { - /* Oops, that's in the past */ - loc_clock = 0; - PRINTF("trickle_timer doubling: Was in the past. Compensating\n"); - } - ctimer_set(NULL, &loctt->ct, loc_clock, fire, loctt); - - /* Store the actual interval start (absolute time), we need it later. - * We pretend that it started at the same time when the last one ended */ - loctt->i_start = last_end; -#else - /* Assumed that the previous interval's end is 'now' and schedule in t ticks - * after 'now', ignoring potential offsets */ - ctimer_set(NULL, &loctt->ct, loc_clock, fire, loctt); - /* Store the actual interval start (absolute time), we need it later */ - loctt->i_start = loctt->ct.etimer.timer.start; -#endif - - PRINTF("trickle_timer doubling: Last end %lu, new end %lu, for %lu, I=%lu\n", - (unsigned long)last_end, - (unsigned long)TRICKLE_TIMER_INTERVAL_END(loctt), - (unsigned long)(loctt->ct.etimer.timer.start + - loctt->ct.etimer.timer.interval), - (unsigned long)(loctt->i_cur)); -} -/*---------------------------------------------------------------------------*/ -/* Called by the ctimer module at time t within the current interval. ptr is - * a pointer to the struct trickle_timer of interest */ -static void -fire(struct net_buf *buf, void *ptr) -{ - /* 'cast' c to a struct trickle_timer */ - loctt = (struct trickle_timer *)ptr; - - PRINTF("trickle_timer fire: at %lu (was for %lu)\n", - (unsigned long)clock_time(), - (unsigned long)(loctt->ct.etimer.timer.start + - loctt->ct.etimer.timer.interval)); - - if(loctt->cb) { - /* - * Call the protocol's TX callback, with the suppression status as an - * argument. - */ - PRINTF("trickle_timer fire: Suppression Status %u (%u < %u)\n", - TRICKLE_TIMER_PROTO_TX_ALLOW(loctt), loctt->c, loctt->k); - loctt->cb(loctt->cb_arg, TRICKLE_TIMER_PROTO_TX_ALLOW(loctt)); - } - - if(trickle_timer_is_running(loctt)) { - schedule_for_end(loctt); - } -} -/*---------------------------------------------------------------------------*/ -/* New trickle interval, either due to a newly set trickle timer or due to an - * inconsistency. Schedule 'fire' to be called in t ticks. */ -static void -new_interval(struct trickle_timer *tt) -{ - tt->c = 0; - - /* Random t in [I/2, I) */ - loc_clock = get_t(tt->i_cur); - - ctimer_set(NULL, &tt->ct, loc_clock, fire, tt); - - /* Store the actual interval start (absolute time), we need it later */ - tt->i_start = tt->ct.etimer.timer.start; - PRINTF("trickle_timer new interval: at %lu, ends %lu, ", - (unsigned long)clock_time(), - (unsigned long)TRICKLE_TIMER_INTERVAL_END(tt)); - PRINTF("t=%lu, I=%lu\n", (unsigned long)loc_clock, (unsigned long)tt->i_cur); -} -/*---------------------------------------------------------------------------*/ -/* Functions to be called by the protocol implementation */ -/*---------------------------------------------------------------------------*/ -void -trickle_timer_consistency(struct trickle_timer *tt) -{ - if(tt->c < 0xFF) { - tt->c++; - } - PRINTF("trickle_timer consistency: c=%u\n", tt->c); -} -/*---------------------------------------------------------------------------*/ -void -trickle_timer_inconsistency(struct trickle_timer *tt) -{ - /* "If I is equal to Imin when Trickle hears an "inconsistent" transmission, - * Trickle does nothing." */ - if(tt->i_cur != tt->i_min) { - PRINTF("trickle_timer inconsistency\n"); - tt->i_cur = tt->i_min; - - new_interval(tt); - } -} -/*---------------------------------------------------------------------------*/ -uint8_t -trickle_timer_config(struct trickle_timer *tt, clock_time_t i_min, - uint8_t i_max, uint8_t k) -{ -#if TRICKLE_TIMER_ERROR_CHECKING - /* - * Although in theory Imin=1 is a valid value, it would break get_t() and - * doesn't make sense anyway. Thus Valid Imin values are in the range: - * 1 < Imin <= (TRICKLE_TIMER_CLOCK_MAX >> 1) + 1 - */ - if(TRICKLE_TIMER_IMIN_IS_BAD(i_min)) { - PRINTF("trickle_timer config: Bad Imin value\n"); - return TRICKLE_TIMER_ERROR; - } - - if(tt == NULL || i_max == 0 || k == 0) { - PRINTF("trickle_timer config: Bad arguments\n"); - return TRICKLE_TIMER_ERROR; - } - - /* - * If clock_time_t is not wide enough to store Imin << Imax, we adjust Imax - * - * This means that 'we' are likely to have a different Imax than 'them' - * See RFC 6206, sec 6.3 for the consequences of this situation - */ - if(TRICKLE_TIMER_IPAIR_IS_BAD(i_min, i_max)) { - PRINTF("trickle_timer config: %lu << %u would exceed clock boundaries. ", - (unsigned long)i_min, i_max); - - /* For this Imin, get the maximum sane Imax */ - i_max = max_imax(i_min); - PRINTF("trickle_timer config: Using Imax=%u\n", i_max); - } -#endif - - tt->i_min = i_min; - tt->i_max = i_max; - tt->i_max_abs = i_min << i_max; - tt->k = k; - - PRINTF("trickle_timer config: Imin=%lu, Imax=%u, k=%u\n", - (unsigned long)tt->i_min, tt->i_max, tt->k); - - return TRICKLE_TIMER_SUCCESS; -} -/*---------------------------------------------------------------------------*/ -uint8_t -trickle_timer_set(struct trickle_timer *tt, trickle_timer_cb_t proto_cb, - void *ptr) -{ -#if TRICKLE_TIMER_ERROR_CHECKING - /* Sanity checks */ - if(tt == NULL || proto_cb == NULL) { - PRINTF("trickle_timer set: Bad arguments\n"); - return TRICKLE_TIMER_ERROR; - } -#endif - - tt->cb = proto_cb; - tt->cb_arg = ptr; - - /* Random I in [Imin , Imax] */ - tt->i_cur = tt->i_min + - (tt_rand() % (TRICKLE_TIMER_INTERVAL_MAX(tt) - tt->i_min + 1)); - - PRINTF("trickle_timer set: I=%lu in [%lu , %lu]\n", (unsigned long)tt->i_cur, - (unsigned long)tt->i_min, - (unsigned long)TRICKLE_TIMER_INTERVAL_MAX(tt)); - - new_interval(tt); - - PRINTF("trickle_timer set: at %lu, ends %lu, t=%lu in [%lu , %lu)\n", - (unsigned long)tt->i_start, - (unsigned long)TRICKLE_TIMER_INTERVAL_END(tt), - (unsigned long)tt->ct.etimer.timer.interval, - (unsigned long)tt->i_cur >> 1, (unsigned long)tt->i_cur); - - return TRICKLE_TIMER_SUCCESS; -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/net/ip/contiki/trickle/trickle-timer.h b/net/ip/contiki/trickle/trickle-timer.h deleted file mode 100644 index bf56cea530ea6b4cea57ba8e18915e98072b6f3b..0000000000000000000000000000000000000000 --- a/net/ip/contiki/trickle/trickle-timer.h +++ /dev/null @@ -1,514 +0,0 @@ -/* - * Copyright (c) 2012, George Oikonomou - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file - * Trickle timer library header file. - * - * \author - * George Oikonomou - - */ - -/** \addtogroup lib - * @{ */ - -/** - * \defgroup trickle-timer Trickle timers - * - * This library implements timers which behave in accordance with RFC 6206 - * "The Trickle Algorithm" (http://tools.ietf.org/html/rfc6206) - * - * Protocols wishing to use trickle timers, may use this library instead of - * implementing the trickle algorithm internally. - * - * The protocol implementation will declare one (or more) variable(s) of type - * struct ::trickle_timer and will then populate its fields by calling - * trickle_timer_config(). trickle_timer_set() will start the timer. - * - * When the timer reaches time t within the current trickle interval, the - * library will call a protocol-provided callback, which will signal to the - * protocol that it is time to TX (see algorithm step 4 in the RFC). - * - * The proto does not need to check the suppression conditions. This is done by - * the library and if TX must be suppressed, the callback won't be called at - * all. - * - * The library also provides functions to be called when the protocol hears a - * 'consistent' or 'inconsistent' message and when an 'external event' occurs - * (in this context, those terms have the exact same meaning as in the RFC). - * - * @{ - */ - -#ifndef TRICKLE_TIMER_H_ -#define TRICKLE_TIMER_H_ - -#include "contiki-conf.h" -#include "sys/ctimer.h" -/*---------------------------------------------------------------------------*/ -/* Trickle Timer Library Constants */ -/*---------------------------------------------------------------------------*/ -/** - * \name Trickle Timer Library: Constants - * @{ - */ -/*---------------------------------------------------------------------------*/ -/** - * \brief Set as value of k to disable suppression - */ -#define TRICKLE_TIMER_INFINITE_REDUNDANCY 0x00 - -#define TRICKLE_TIMER_ERROR 0 -#define TRICKLE_TIMER_SUCCESS 1 - -/** - * \brief Use as the value of TRICKLE_TIMER_MAX_IMAX_WIDTH to enable the - * generic 'Find max Imax' routine - */ -#define TRICKLE_TIMER_MAX_IMAX_GENERIC 0 -/** - * \brief Use as the value of TRICKLE_TIMER_MAX_IMAX_WIDTH to enable the 16-bit - * 'Find max Imax' routine - */ -#define TRICKLE_TIMER_MAX_IMAX_16_BIT 1 -/** - * \brief Use as the value of TRICKLE_TIMER_MAX_IMAX_WIDTH to enable the 32-bit - * 'Find max Imax' routine - */ -#define TRICKLE_TIMER_MAX_IMAX_32_BIT 2 - -/** - * \brief Constants used as values for the \e suppress param of - * trickle_timer_cb_t - */ -#define TRICKLE_TIMER_TX_SUPPRESS 0 -#define TRICKLE_TIMER_TX_OK 1 - -/** - * \brief A trickle timer is considered 'stopped' when - * i_cur == TRICKLE_TIMER_IS_STOPPED. - * - * trickle_timer_stop() must be used to correctly disable a trickle timer. - * Do NOT set the value of i_cur to 0 directly, as this will fail to stop the - * timer. - */ -#define TRICKLE_TIMER_IS_STOPPED 0 -/** @} */ -/*---------------------------------------------------------------------------*/ -/** - * \brief Controls whether the library will try to compensate for time drifts - * caused by getting called later than scheduled. - * - * 1: Enabled (default). 0: Disabled - * - * To override the default, define TRICKLE_TIMER_CONF_COMPENSATE_DRIFT in - * contiki-conf.h - * - * Bear in mind that this controls the behaviour of the entire library (i.e. - * all trickle timers) and not of an individual timer - */ -#ifdef TRICKLE_TIMER_CONF_COMPENSATE_DRIFT -#define TRICKLE_TIMER_COMPENSATE_DRIFT TRICKLE_TIMER_CONF_COMPENSATE_DRIFT -#else -#define TRICKLE_TIMER_COMPENSATE_DRIFT 1 -#endif -/*---------------------------------------------------------------------------*/ -/** - * \brief Turns on support for 4-byte wide, unsigned random numbers - * - * We need this for platforms which have a 4-byte wide clock_time_t. For those - * platforms and if Imin << Imax is GT 0xFFFF, random_rand alone is not always - * enough to generate a correct t in [I/2, I). Specifically, we need wide - * randoms when I > 0x1FFFF. - * - * For platforms with a 2-byte wide clock_time_t, this can be defined as 0 - * to reduce code footprint and increase speed. - */ -#ifdef TRICKLE_TIMER_CONF_WIDE_RAND -#define TRICKLE_TIMER_WIDE_RAND TRICKLE_TIMER_CONF_WIDE_RAND -#else -#define TRICKLE_TIMER_WIDE_RAND 1 -#endif -/*---------------------------------------------------------------------------*/ -/** - * \brief Selects a flavor for the 'Find maximum Imax' (max_imax) function. - * - * When configuring a new trickle timer, the library verifies that the (Imin , - * Imax) pair will fit in the platform's clock_time_t boundaries. If this is - * not the case, Imax will be adjusted down. In order to achieve this, we use - * an internal function which is a slight variant of a standard 'Count Leading - * Zeros'. - * - * This functionality is disabled when ::TRICKLE_TIMER_ERROR_CHECKING is 0 - * - * This define helps us generate, at the pre-processing stage, the desired - * version of this function. We start with a generic version by default. The - * platform's contiki-conf.h can change this to use the 16- or 32-bit specific - * flavor by defining TRICKLE_TIMER_CONF_MAX_IMAX_WIDTH. - * - * Depending on the toolchain, the generic variant may actually result in a - * smaller code size. Do your own experiments. - * - * TRICKLE_TIMER_MAX_IMAX_GENERIC (0): Generic function which will work - * regardless whether the platform uses a 16 or 32 bit wide clock type - * - * TRICKLE_TIMER_MAX_IMAX_16_BIT (1): You can select this in your - * contiki-conf.h if your platform's clock_time_t is 16 bits wide - * - * TRICKLE_TIMER_MAX_IMAX_32_BIT (2): You can select this in your - * contiki-conf.h if your platform's clock_time_t is 32 bits wide - */ -#ifdef TRICKLE_TIMER_CONF_MAX_IMAX_WIDTH -#define TRICKLE_TIMER_MAX_IMAX_WIDTH TRICKLE_TIMER_CONF_MAX_IMAX_WIDTH -#else -#define TRICKLE_TIMER_MAX_IMAX_WIDTH TRICKLE_TIMER_MAX_IMAX_GENERIC -#endif - -/** - * \brief Enables/Disables error checking - * - * 1: Enabled (default). The library checks the validity of Imin and Imax - * 0: Disabled. All error checking is turned off. This reduces code size. - */ -#ifdef TRICKLE_TIMER_CONF_ERROR_CHECKING -#define TRICKLE_TIMER_ERROR_CHECKING TRICKLE_TIMER_CONF_ERROR_CHECKING -#else -#define TRICKLE_TIMER_ERROR_CHECKING 1 -#endif -/*---------------------------------------------------------------------------*/ -/* Trickle Timer Library Macros */ -/*---------------------------------------------------------------------------*/ -/** - * \name Trickle Timer Library: Macros - * @{ - */ -/** - * \brief cross-platform method to get the maximum clock_time_t value - */ -#define TRICKLE_TIMER_CLOCK_MAX ((clock_time_t)~0) - - -/** - * \brief Checks if the trickle timer's suppression feature is enabled - * - * \param tt A pointer to a ::trickle_timer structure - * - * \retval non-zero Suppression is enabled - * \retval 0 Suppression is disabled - */ -#define TRICKLE_TIMER_SUPPRESSION_ENABLED(tt) \ - ((tt)->k != TRICKLE_TIMER_INFINITE_REDUNDANCY) - -/** - * \brief Checks if the trickle timer's suppression feature is disabled - * - * \param tt A pointer to a ::trickle_timer structure - * - * \retval non-zero Suppression is disabled - * \retval 0 Suppression is enabled - */ -#define TRICKLE_TIMER_SUPPRESSION_DISABLED(tt) \ - ((tt)->k == TRICKLE_TIMER_INFINITE_REDUNDANCY) - -/** - * \brief Determines whether the protocol must go ahead with a transmission - * - * \param tt A pointer to a ::trickle_timer structure - * - * \retval non-zero Go ahead with TX - * \retval 0 Suppress - */ -#define TRICKLE_TIMER_PROTO_TX_ALLOW(tt) \ - (TRICKLE_TIMER_SUPPRESSION_DISABLED(tt) || ((tt)->c < (tt)->k)) - -/** - * \brief Determines whether the protocol must suppress a transmission - * - * \param tt A pointer to a ::trickle_timer structure - * - * \retval non-zero Suppress - * \retval 0 Go ahead with TX - */ -#define TRICKLE_TIMER_PROTO_TX_SUPPRESS(tt) \ - (TRICKLE_TIMER_SUPPRESSION_ENABLED(tt) && ((tt)->c >= (tt)->k)) - -/** - * \brief Returns a timer's maximum interval size (Imin << Imax) as a number of - * clock ticks - * - * \param tt A pointer to a ::trickle_timer structure - * - * \return Maximum trickle interval length in clock ticks - */ -#define TRICKLE_TIMER_INTERVAL_MAX(tt) ((tt)->i_max_abs) - -/** - * \brief Returns the current trickle interval's end (absolute time in ticks) - * - * \param tt A pointer to a ::trickle_timer structure - * - * \return The absolute number of clock ticks when the current trickle interval - * will expire - */ -#define TRICKLE_TIMER_INTERVAL_END(tt) ((tt)->i_start + (tt)->i_cur) - -/** - * \brief Checks whether an Imin value is suitable considering the various - * restrictions imposed by our platform's clock as well as by the library itself - * - * \param imin An Imin value in clock ticks - * - * \retval 1 The Imin value is valid - * \retval 0 The Imin value is invalid - */ -#define TRICKLE_TIMER_IMIN_IS_OK(imin) \ - ((imin > 1) && (i_min <= (TRICKLE_TIMER_CLOCK_MAX >> 1))) - -/** - * \brief Checks whether an Imin value is invalid considering the various - * restrictions imposed by our platform's clock as well as by the library itself - * - * \param imin An Imin value in clock ticks - * - * \retval 1 The Imin value is invalid - * \retval 0 The Imin value is valid - */ -#define TRICKLE_TIMER_IMIN_IS_BAD(imin) \ - ((imin < 2) || (i_min > (TRICKLE_TIMER_CLOCK_MAX >> 1))) - -/** - * \brief Checks whether Imin << Imax is unsuitable considering the boundaries - * of our platform's clock_time_t - * - * \param i_min Imin value - * \param i_max Maximum number of doublings - * - * \retval non-zero The pair would exceed clock boundaries - * \retval 0 The pair is suitable for the platform - * - * Timers scheduled far in the future can be perceived as being scheduled in - * the past. - * Thus, we limit Imin << Imax to be LEQ(TRICKLE_TIMER_CLOCK_MAX >> 1) + 1 - */ -#define TRICKLE_TIMER_IPAIR_IS_BAD(i_min, i_max) \ - ((TRICKLE_TIMER_CLOCK_MAX >> (i_max + 1)) < i_min - 1) -/** @} */ -/*---------------------------------------------------------------------------*/ -/* Trickle Timer Library Data Representation */ -/*---------------------------------------------------------------------------*/ -/** - * \name Trickle Timer Library: Data Representation - * @{ - */ - -/** - * \brief typedef for a callback function to be defined in the protocol's - * implementation. - * - * Those callbaks are stored as a function pointer inside a ::trickle_timer - * structure and are called by the library at time t within the current trickle - * interval. - * - * Some protocols may rely on multiple trickle timers. For this reason, this - * function's argument will be an opaque pointer, aiming to help the protocol - * determine which timer triggered the call. - * - * The \e suppress argument is used so that the library can signal the protocol - * whether it should TX or suppress - */ -typedef void (* trickle_timer_cb_t)(void *ptr, uint8_t suppress); - -/** - * \struct trickle_timer - * - * A trickle timer. - * - * This structure is used for declaring a trickle timer. In order for the timer - * to start running, the protocol must first populate the structure's fields - * by calling trickle_timer_set(). Protocol implementations must NOT modify the - * contents of this structure directly. - * - * Protocol developers must also be careful to specify the values of Imin and - * Imax in such a way that the maximum interval size does not exceed the - * boundaries of clock_time_t - */ -struct trickle_timer { - clock_time_t i_min; /**< Imin: Clock ticks */ - clock_time_t i_cur; /**< I: Current interval in clock_ticks */ - clock_time_t i_start; /**< Start of this interval (absolute clock_time) */ - clock_time_t i_max_abs; /**< Maximum interval size in clock ticks (and not in - number of doublings). This is a cached value of - Imin << Imax used internally, so that we can - have direct access to the maximum interval size - without having to calculate it all the time */ - struct ctimer ct; /**< A \ref ctimer used internally */ - trickle_timer_cb_t cb; /**< Protocol's own callback, invoked at time t - within the current interval */ - void *cb_arg; /**< Opaque pointer to be used as the argument of the - protocol's callback */ - uint8_t i_max; /**< Imax: Max number of doublings */ - uint8_t k; /**< k: Redundancy Constant */ - uint8_t c; /**< c: Consistency Counter */ -}; -/** @} */ -/*---------------------------------------------------------------------------*/ -/* Trickle Timer Library Functions */ -/*---------------------------------------------------------------------------*/ -/** - * \name Trickle Timer Library: Functions called by protocol implementations - * @{ - */ - -/** - * \brief Configure a trickle timer - * \param tt A pointer to a ::trickle_timer structure - * \param i_min The timer's Imin configuration parameter, in units of - * clock_time_t - * \param i_max The timer's Imax configuration parameter (maximum number of - * doublings), specified as number of doublings - * \param k The timer's K (redundancy constant). If the value of K - * equals #TRICKLE_TIMER_INFINITE_REDUNDANCY, message - * suppression will be disabled - * \retval 0 Error (Bad argument) - * \retval non-zero Success. - * - * This function is used to set the initial configuration for a trickle timer. - * A trickle timer MUST be configured before the protocol calls - * trickle_timer_set(). - * - * If Imin<ct)); \ - (tt)->i_cur = TRICKLE_TIMER_IS_STOPPED; \ -} while(0) - -/** - * \brief To be called by the protocol when it hears a consistent - * transmission - * \param tt A pointer to a ::trickle_timer structure - * - * When the trickle-based protocol hears a consistent transmission it must call - * this function to increment trickle's consistency counter, which is later - * used to determine whether the protocol must suppress or go ahead with its - * own transmissions. - * - * As the trickle timer library implementation may change in the future to - * perform further tasks upon reception of a consistent transmission, the - * protocol's implementation MUST use this call to increment the consistency - * counter instead of directly writing to the structure's field. - */ -void trickle_timer_consistency(struct trickle_timer *tt); - -/** - * \brief To be called by the protocol when it hears an inconsistent - * transmission - * \param tt A pointer to a ::trickle_timer structure - * - * When the protocol hears an inconsistent transmission, it must call this - * function to notify the library that the timer must be reset. - * - * Before resetting the timer, the library will perform a set of checks. - * Therefore, it is important that the protocol calls this function instead of - * trying to reset the timer by itself. - */ -void trickle_timer_inconsistency(struct trickle_timer *tt); - -/** - * \brief To be called by the protocol when an external event occurs that - * should trigger a timer reset - * \param tt A pointer to a ::trickle_timer structure - * - * When an external event occurs that should result in a timer reset, the - * protocol implementation must call this function to notify the library. - * - * Before resetting the timer, the library will perform a set of checks. - * Therefore, it is important that the protocol calls this function instead of - * trying to reset the timer by itself. - */ -#define trickle_timer_reset_event(tt) trickle_timer_inconsistency(tt) - -/** - * \brief To be called in order to determine whether a trickle timer is - * running - * \param tt A pointer to a ::trickle_timer structure - * \retval 0 The timer is stopped - * \retval non-zero The timer is running - * - */ -#define trickle_timer_is_running(tt) ((tt)->i_cur != TRICKLE_TIMER_IS_STOPPED) - -/** @} */ - -#endif /* TRICKLE_TIMER_H_ */ -/** @} */ -/** @} */ diff --git a/net/ip/contiki/uip-log.c b/net/ip/contiki/uip-log.c deleted file mode 100644 index 107401d13722b446e59e7309b8c9f032bc076710..0000000000000000000000000000000000000000 --- a/net/ip/contiki/uip-log.c +++ /dev/null @@ -1,47 +0,0 @@ -/* uip-log.c - Logging support */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#if defined(CONFIG_STDOUT_CONSOLE) -#include -#define PRINT printf -#else -#include -#define PRINT printk -#endif - -#include "ip/uipopt.h" -#include "sys/log.h" - -#if UIP_LOGGING -void uip_log(char *message) -{ - PRINT(message); - PRINT("\n"); -} -#endif /* UIP_LOGGING */ - -#if LOG_CONF_ENABLED -void log_message(const char *part1, const char *part2) -{ - PRINT(part1); - PRINT(part2); - PRINT("\n"); -} -#endif /* LOG_CONF_ENABLED */ diff --git a/net/ip/dummy_15_4_radio.c b/net/ip/dummy_15_4_radio.c deleted file mode 100644 index 3f9c7ec96d40815f4bee007b8708ba9ea719aaa1..0000000000000000000000000000000000000000 --- a/net/ip/dummy_15_4_radio.c +++ /dev/null @@ -1,329 +0,0 @@ -/* dummy_15_4_radio.c - 802.15.4 radio driver loopbacks Tx frames back to us */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "contiki.h" - -#include -#include - -#include "contiki/packetbuf.h" -#include "contiki/netstack.h" -#include "dummy_15_4_radio.h" -#include "net_driver_15_4.h" - -#include - -#if UIP_CONF_LOGGING -#define DEBUG DEBUG_FULL -#else -#define DEBUG DEBUG_NONE -#endif -#include "contiki/ip/uip-debug.h" - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif - -#define FOOTER_LEN 2 -#define NETWORK_TEST_MAX_PACKET_LEN PACKETBUF_SIZE - -static volatile uint16_t last_packet_timestamp; - -/* Data sending and receiving is done in TLV way. */ -#if defined CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART -#define DUMMY_RADIO_15_4_FRAME_TYPE 0xF0 -static uint8_t input[NETWORK_TEST_MAX_PACKET_LEN]; -static uint8_t input_len, input_offset, input_type; -static bool starting = true; -#define PRINT_DATA 1 -#undef PRINT_DATA /* comment this to print transferred bytes */ -#else -static uint8_t loopback[NETWORK_TEST_MAX_PACKET_LEN]; -#endif - -/*---------------------------------------------------------------------------*/ -#if defined CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART -static uint8_t *recv_cb(uint8_t *buf, size_t *off) -{ -#if PRINT_DATA - PRINTF("dummy154radio: %s(): input[] %d data 0x%x uart offset %d\n", - __FUNCTION__, input_offset, buf[0], *off); -#endif - - if (starting) { - if (buf[0] == 0) { - goto done; - } else { - starting = false; - } - } - if (input_len == 0 && input_offset == 0 && - buf[0] == DUMMY_RADIO_15_4_FRAME_TYPE) { - input_type = buf[0]; - goto done; - } - - if (input_len == 0 && input_offset == 0 && - input_type == DUMMY_RADIO_15_4_FRAME_TYPE) { - input_len = buf[0]; - - if (input_len >= NETWORK_TEST_MAX_PACKET_LEN) { - PRINTF("dummy154radio: too long message %d max is %d, " - "discarding packet\n", input_len, NETWORK_TEST_MAX_PACKET_LEN); - } else { - PRINTF("dummy154radio: will receive %d bytes\n", input_len); - } - goto done; - } - - if (input_len) { - static bool printed; - if (input_offset >= NETWORK_TEST_MAX_PACKET_LEN) { - if (!printed) { - PRINTF("dummy154radio: too long message (offset %d), " - "discarding packet\n", input_offset); - printed = true; - } - goto fail; - } else { - printed = false; - input[input_offset++] = buf[0]; - } - } - - if (input_len && input_len == input_offset) { - if (input_len < NETWORK_TEST_MAX_PACKET_LEN) { - struct net_buf *mbuf; - - mbuf = l2_buf_get_reserve(0); - if (mbuf) { - packetbuf_copyfrom(mbuf, input, input_len); - packetbuf_set_datalen(mbuf, input_len); - packetbuf_set_attr(mbuf, PACKETBUF_ATTR_TIMESTAMP, - last_packet_timestamp); - PRINTF("dummy154radio: received %d bytes\n", input_len); - - if (net_driver_15_4_recv_from_hw(mbuf) < 0) { - PRINTF("dummy154radio: rdc input failed, packet discarded\n"); - l2_buf_unref(mbuf); - } - } - } - - fail: - input_len = input_offset = input_type = 0; - memset(input, 0, sizeof(input)); - } - -done: - *off = 0; - return buf; -} -#endif - -#if defined CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART -static void uart_send(unsigned char c) -{ - uint8_t buf[1] = { c }; - -#if PRINT_DATA - PRINTF("dummy154radio: %s(): writing 0x%x\n", - __FUNCTION__, buf[0]); -#endif - - uart_pipe_send(&buf[0], 1); -} -#endif - -/*---------------------------------------------------------------------------*/ -static int -init(void) -{ -#if defined CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART - /* Use small temp buffer for receiving data */ - static uint8_t buf[1]; - - uart_pipe_register(buf, sizeof(buf), recv_cb); - - /* It seems that some of the start bytes are lost so - * send some null bytes in the start in order to sync - * the link. - */ - uart_send(0); - uart_send(0); - uart_send(0); - uart_send(0); - uart_send(0); -#endif - - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -prepare(const void *payload, unsigned short payload_len) -{ - return 1; -} -/*---------------------------------------------------------------------------*/ -static int -transmit(struct net_buf *buf, unsigned short transmit_len) -{ - return RADIO_TX_OK; -} - -#ifndef CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART -static void route_buf(struct net_buf *buf) -{ - int len; - struct net_buf *mbuf; - - len = packetbuf_copyto(buf, loopback); - /* Receiver buffer that is passed to 15.4 Rx fiber */ - PRINTF("dummy154radio: got %d bytes\n", len); - - mbuf = l2_buf_get_reserve(0); - if (mbuf) { - packetbuf_copyfrom(mbuf, loopback, len); - packetbuf_set_datalen(mbuf, len); - packetbuf_set_attr(mbuf, PACKETBUF_ATTR_TIMESTAMP, - last_packet_timestamp); - PRINTF("dummy154radio: 15.4 Rx input %d bytes\n", len); - - if (net_driver_15_4_recv_from_hw(mbuf) < 0) { - PRINTF("dummy154radio: rdc input failed, " - "packet discarded\n"); - l2_buf_unref(mbuf); - } - - NET_BUF_CHECK_IF_NOT_IN_USE(mbuf); - } -} -#endif - -/*---------------------------------------------------------------------------*/ -static int -send(struct net_buf *buf, const void *payload, unsigned short payload_len) -{ -#if defined CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART - static uint8_t output[NETWORK_TEST_MAX_PACKET_LEN]; - uint8_t len, i; - - len = packetbuf_copyto(buf, output); - if (len != payload_len) { - PRINTF("dummy154radio: sending %d bytes, payload %d bytes\n", - len, payload_len); - } else { - PRINTF("dummy154radio: sending %d bytes\n", len); - } - - uart_send(DUMMY_RADIO_15_4_FRAME_TYPE); /* Type */ - uart_send(len); /* Length */ - - for (i = 0; i < len; i++) { - uart_send(output[i]); - } - - return RADIO_TX_OK; -#else - route_buf(buf); - return transmit(buf, payload_len); -#endif -} -/*---------------------------------------------------------------------------*/ -static int -radio_read(void *buf, unsigned short buf_len) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -channel_clear(void) -{ - return 1; -} -/*---------------------------------------------------------------------------*/ -static int -receiving_packet(void) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -pending_packet(void) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -on(void) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -off(void) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -static radio_result_t -get_value(radio_param_t param, radio_value_t *value) -{ - return RADIO_RESULT_NOT_SUPPORTED; -} -/*---------------------------------------------------------------------------*/ -static radio_result_t -set_value(radio_param_t param, radio_value_t value) -{ - return RADIO_RESULT_NOT_SUPPORTED; -} -/*---------------------------------------------------------------------------*/ -static radio_result_t -get_object(radio_param_t param, void *dest, size_t size) -{ - return RADIO_RESULT_NOT_SUPPORTED; -} -/*---------------------------------------------------------------------------*/ -static radio_result_t -set_object(radio_param_t param, const void *src, size_t size) -{ - return RADIO_RESULT_NOT_SUPPORTED; -} -/*---------------------------------------------------------------------------*/ -const struct radio_driver dummy154radio_driver = - { - .init = init, - .prepare = prepare, - .transmit = transmit, - .send = send, - .read = radio_read, - .channel_clear = channel_clear, - .receiving_packet = receiving_packet, - .pending_packet = pending_packet, - .on = on, - .off = off, - .get_value = get_value, - .set_value = set_value, - .get_object = get_object, - .set_object = set_object - }; -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/dummy_15_4_radio.h b/net/ip/dummy_15_4_radio.h deleted file mode 100644 index 2a3bbc3f302546c3f546f421534407189939cc92..0000000000000000000000000000000000000000 --- a/net/ip/dummy_15_4_radio.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef DUMMY154RADIO_H -#define DUMMY154RADIO_H - -#include "dev/radio.h" - -extern const struct radio_driver dummy_15_4_driver; - -#endif /* DUMMY154RADIO_H */ diff --git a/net/ip/er-coap/er-coap-block1.c b/net/ip/er-coap/er-coap-block1.c deleted file mode 100644 index 9f73fd3b2e2b81132b47aed7ceb04e2a8bd02f4b..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-block1.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2014, Lars Schmertmann . - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for block 1 handling - * \author - * Lars Schmertmann - */ - -#include -#include - -#include "er-coap.h" -#include "er-coap-block1.h" - -#define DEBUG 0 -#include "contiki/ip/uip-debug.h" - -/*----------------------------------------------------------------------------*/ - -/** - * \brief Block 1 support within a coap-ressource - * - * This function will help you to use block 1. If target is null - * error handling and response configuration is active. On return - * value 0, the last block was recived, while on return value 1 - * more blocks will follow. With target, len and maxlen this - * function will assemble the blocks. - * - * You can find an example in: - * examples/er-rest-example/resources/res-b1-sep-b2.c - * - * \param request Request pointer from the handler - * \param response Response pointer from the handler - * \param target Pointer to the buffer where the request payload can be assembled - * \param len Pointer to the variable, where the function stores the actual length - * \param max_len Length of the "target"-Buffer - * - * \return 0 if initialisation was successful - * -1 if initialisation failed - */ -int -coap_block1_handler(void *request, void *response, uint8_t *target, size_t *len, size_t max_len) -{ - const uint8_t *payload = 0; - int pay_len = REST.get_request_payload(request, &payload); - - if(!pay_len || !payload) { - erbium_status_code = REST.status.BAD_REQUEST; - coap_error_message = "NoPayload"; - return -1; - } - - coap_packet_t *packet = (coap_packet_t *)request; - - if(packet->block1_offset + pay_len > max_len) { - erbium_status_code = REST.status.REQUEST_ENTITY_TOO_LARGE; - coap_error_message = "Message to big"; - return -1; - } - - if(target && len) { - memcpy(target + packet->block1_offset, payload, pay_len); - *len = packet->block1_offset + pay_len; - } - - if(IS_OPTION(packet, COAP_OPTION_BLOCK1)) { - PRINTF("Blockwise: block 1 request: Num: %u, More: %u, Size: %u, Offset: %u\n", - packet->block1_num, - packet->block1_more, - packet->block1_size, - packet->block1_offset); - - coap_set_header_block1(response, packet->block1_num, packet->block1_more, packet->block1_size); - if(packet->block1_more) { - coap_set_status_code(response, CONTINUE_2_31); - return 1; - } - } - - return 0; -} diff --git a/net/ip/er-coap/er-coap-block1.h b/net/ip/er-coap/er-coap-block1.h deleted file mode 100644 index a6b1de5ab17761fd2d896a1d242f4d2d42d1bf01..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-block1.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2014, Lars Schmertmann . - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for block 1 handling - * \author - * Lars Schmertmann - */ - -#ifndef COAP_BLOCK1_H_ -#define COAP_BLOCK1_H_ - -#include -#include - -int coap_block1_handler(void *request, void *response, uint8_t *target, size_t *len, size_t max_len); - -#endif /* COAP_BLOCK1_H_ */ diff --git a/net/ip/er-coap/er-coap-conf.h b/net/ip/er-coap/er-coap-conf.h deleted file mode 100644 index 67956106adbbfac0e43da071df2100875ff450a4..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-conf.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Collection of default configuration values. - * \author - * Matthias Kovatsch - */ - -#ifndef ER_COAP_CONF_H_ -#define ER_COAP_CONF_H_ - -/* Features that can be disabled to achieve smaller memory footprint */ -#define COAP_LINK_FORMAT_FILTERING CONFIG_ER_COAP_LINK_FORMAT_FILTERING -#define COAP_PROXY_OPTION_PROCESSING 0 - -/* Listening port for the CoAP REST Engine */ -#ifndef COAP_SERVER_PORT -#define COAP_SERVER_PORT COAP_DEFAULT_PORT -#endif - -/* The number of concurrent messages that can be stored for retransmission in the transaction layer. */ -#ifndef COAP_MAX_OPEN_TRANSACTIONS -#define COAP_MAX_OPEN_TRANSACTIONS 4 -#endif /* COAP_MAX_OPEN_TRANSACTIONS */ - -/* Maximum number of failed request attempts before action */ -#ifndef COAP_MAX_ATTEMPTS -#define COAP_MAX_ATTEMPTS 4 -#endif /* COAP_MAX_ATTEMPTS */ - -/* Conservative size limit, as not all options have to be set at the same time. Check when Proxy-Uri option is used */ -#ifndef COAP_MAX_HEADER_SIZE /* Hdr CoF If-Match Obs Blo strings */ -#define COAP_MAX_HEADER_SIZE (4 + COAP_TOKEN_LEN + 3 + 1 + COAP_ETAG_LEN + 4 + 4 + 30) /* 65 */ -#endif /* COAP_MAX_HEADER_SIZE */ - -/* Number of observer slots (each takes abot xxx bytes) */ -#ifndef COAP_MAX_OBSERVERS -#define COAP_MAX_OBSERVERS COAP_MAX_OPEN_TRANSACTIONS - 1 -#endif /* COAP_MAX_OBSERVERS */ - -/* Interval in notifies in which NON notifies are changed to CON notifies to check client. */ -#define COAP_OBSERVE_REFRESH_INTERVAL 20 - -#endif /* ER_COAP_CONF_H_ */ diff --git a/net/ip/er-coap/er-coap-constants.h b/net/ip/er-coap/er-coap-constants.h deleted file mode 100644 index 780cca9f6a827b6feb4f187d2f684a6b22832c39..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-constants.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Collection of constants specified in the CoAP standard. - * \author - * Matthias Kovatsch - */ - -#ifndef ER_COAP_CONSTANTS_H_ -#define ER_COAP_CONSTANTS_H_ - -#define COAP_DEFAULT_PORT 5683 -#define COAP_DEFAULT_SECURE_PORT 5684 - -#define COAP_DEFAULT_MAX_AGE 60 -#define COAP_RESPONSE_TIMEOUT 3 -#define COAP_RESPONSE_RANDOM_FACTOR 1.5 -#define COAP_RESPONSE_RANDOM_FACTOR_INT 15 -#define COAP_MAX_RETRANSMIT 4 - -#define COAP_HEADER_LEN 4 /* | version:0x03 type:0x0C tkl:0xF0 | code | mid:0x00FF | mid:0xFF00 | */ -#define COAP_TOKEN_LEN 8 /* The maximum number of bytes for the Token */ -#define COAP_ETAG_LEN 8 /* The maximum number of bytes for the ETag */ - -#define COAP_HEADER_VERSION_MASK 0xC0 -#define COAP_HEADER_VERSION_POSITION 6 -#define COAP_HEADER_TYPE_MASK 0x30 -#define COAP_HEADER_TYPE_POSITION 4 -#define COAP_HEADER_TOKEN_LEN_MASK 0x0F -#define COAP_HEADER_TOKEN_LEN_POSITION 0 - -#define COAP_HEADER_OPTION_DELTA_MASK 0xF0 -#define COAP_HEADER_OPTION_SHORT_LENGTH_MASK 0x0F - -/* CoAP message types */ -typedef enum { - COAP_TYPE_CON, /* confirmables */ - COAP_TYPE_NON, /* non-confirmables */ - COAP_TYPE_ACK, /* acknowledgements */ - COAP_TYPE_RST /* reset */ -} coap_message_type_t; - -/* CoAP request method codes */ -typedef enum { - COAP_GET = 1, - COAP_POST, - COAP_PUT, - COAP_DELETE -} coap_method_t; - -/* CoAP response codes */ -typedef enum { - NO_ERROR = 0, - - CREATED_2_01 = 65, /* CREATED */ - DELETED_2_02 = 66, /* DELETED */ - VALID_2_03 = 67, /* NOT_MODIFIED */ - CHANGED_2_04 = 68, /* CHANGED */ - CONTENT_2_05 = 69, /* OK */ - CONTINUE_2_31 = 95, /* CONTINUE */ - - BAD_REQUEST_4_00 = 128, /* BAD_REQUEST */ - UNAUTHORIZED_4_01 = 129, /* UNAUTHORIZED */ - BAD_OPTION_4_02 = 130, /* BAD_OPTION */ - FORBIDDEN_4_03 = 131, /* FORBIDDEN */ - NOT_FOUND_4_04 = 132, /* NOT_FOUND */ - METHOD_NOT_ALLOWED_4_05 = 133, /* METHOD_NOT_ALLOWED */ - NOT_ACCEPTABLE_4_06 = 134, /* NOT_ACCEPTABLE */ - PRECONDITION_FAILED_4_12 = 140, /* BAD_REQUEST */ - REQUEST_ENTITY_TOO_LARGE_4_13 = 141, /* REQUEST_ENTITY_TOO_LARGE */ - UNSUPPORTED_MEDIA_TYPE_4_15 = 143, /* UNSUPPORTED_MEDIA_TYPE */ - - INTERNAL_SERVER_ERROR_5_00 = 160, /* INTERNAL_SERVER_ERROR */ - NOT_IMPLEMENTED_5_01 = 161, /* NOT_IMPLEMENTED */ - BAD_GATEWAY_5_02 = 162, /* BAD_GATEWAY */ - SERVICE_UNAVAILABLE_5_03 = 163, /* SERVICE_UNAVAILABLE */ - GATEWAY_TIMEOUT_5_04 = 164, /* GATEWAY_TIMEOUT */ - PROXYING_NOT_SUPPORTED_5_05 = 165, /* PROXYING_NOT_SUPPORTED */ - - /* Erbium errors */ - MEMORY_ALLOCATION_ERROR = 192, - PACKET_SERIALIZATION_ERROR, - - /* Erbium hooks */ - MANUAL_RESPONSE, - PING_RESPONSE -} coap_status_t; - -/* CoAP header option numbers */ -typedef enum { - COAP_OPTION_IF_MATCH = 1, /* 0-8 B */ - COAP_OPTION_URI_HOST = 3, /* 1-255 B */ - COAP_OPTION_ETAG = 4, /* 1-8 B */ - COAP_OPTION_IF_NONE_MATCH = 5, /* 0 B */ - COAP_OPTION_OBSERVE = 6, /* 0-3 B */ - COAP_OPTION_URI_PORT = 7, /* 0-2 B */ - COAP_OPTION_LOCATION_PATH = 8, /* 0-255 B */ - COAP_OPTION_URI_PATH = 11, /* 0-255 B */ - COAP_OPTION_CONTENT_FORMAT = 12, /* 0-2 B */ - COAP_OPTION_MAX_AGE = 14, /* 0-4 B */ - COAP_OPTION_URI_QUERY = 15, /* 0-255 B */ - COAP_OPTION_ACCEPT = 17, /* 0-2 B */ - COAP_OPTION_LOCATION_QUERY = 20, /* 0-255 B */ - COAP_OPTION_BLOCK2 = 23, /* 1-3 B */ - COAP_OPTION_BLOCK1 = 27, /* 1-3 B */ - COAP_OPTION_SIZE2 = 28, /* 0-4 B */ - COAP_OPTION_PROXY_URI = 35, /* 1-1034 B */ - COAP_OPTION_PROXY_SCHEME = 39, /* 1-255 B */ - COAP_OPTION_SIZE1 = 60, /* 0-4 B */ -} coap_option_t; - -/* CoAP Content-Formats */ -typedef enum { - TEXT_PLAIN = 0, - TEXT_XML = 1, - TEXT_CSV = 2, - TEXT_HTML = 3, - IMAGE_GIF = 21, - IMAGE_JPEG = 22, - IMAGE_PNG = 23, - IMAGE_TIFF = 24, - AUDIO_RAW = 25, - VIDEO_RAW = 26, - APPLICATION_LINK_FORMAT = 40, - APPLICATION_XML = 41, - APPLICATION_OCTET_STREAM = 42, - APPLICATION_RDF_XML = 43, - APPLICATION_SOAP_XML = 44, - APPLICATION_ATOM_XML = 45, - APPLICATION_XMPP_XML = 46, - APPLICATION_EXI = 47, - APPLICATION_FASTINFOSET = 48, - APPLICATION_SOAP_FASTINFOSET = 49, - APPLICATION_JSON = 50, - APPLICATION_X_OBIX_BINARY = 51 -} coap_content_format_t; - -#endif /* ER_COAP_CONSTANTS_H_ */ diff --git a/net/ip/er-coap/er-coap-context.c b/net/ip/er-coap/er-coap-context.c deleted file mode 100644 index 370c1da917466100915f524f8555dfcd1c96890b..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-context.c +++ /dev/null @@ -1,687 +0,0 @@ -/* - * Copyright (c) 2015, SICS, Swedish ICT AB. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/** - * \file - * CoAP context handling - * \author - * Niclas Finne - * Joakim Eriksson - */ - -#include "er-coap.h" -#include "er-coap-engine.h" -#include -#include - -#if CONFIG_NETWORK_IP_STACK_DEBUG_COAP_CONTEXT -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#ifndef COAP_CONTEXT_CONF_MAX_CONTEXTS -#define MAX_CONTEXTS 1 -#else -#define MAX_CONTEXTS COAP_CONTEXT_CONF_MAX_CONTEXTS -#endif /* COAP_CONTEXT_CONF_MAX_CONTEXTS */ - -static coap_context_t coap_contexts[MAX_CONTEXTS]; - -#ifdef WITH_DTLS - -process_event_t coap_context_event; - -#define STATUS_CONNECTING 1 -#define STATUS_CONNECTED 2 -#define STATUS_ALERT 4 - -PROCESS(coap_context_process, "CoAP Context Engine"); - -/*---------------------------------------------------------------------------*/ -static int -get_from_peer(struct dtls_context_t *ctx, session_t *session, - uint8 *data, size_t len) -{ - coap_context_t *coap_ctx; - coap_ctx = dtls_get_app_data(ctx); - - if(coap_ctx != COAP_CONTEXT_NONE && coap_ctx->is_used) { - uip_len(coap_ctx->buf) = len; - memmove(uip_appdata(coap_ctx->buf), data, len); - coap_engine_receive(coap_ctx); - } - return 0; -} -/*---------------------------------------------------------------------------*/ -static int prepare_and_send_buf(coap_context_t *ctx, session_t *session, - uint8_t *data, size_t len) -{ - struct net_buf *buf; - int max_data_len; - - /* This net_buf gets sent to network, so it is not released - * by this function unless there was an error and buf was - * not actually sent. - */ - buf = ip_buf_get_tx(ctx->net_ctx); - if (!buf) { - len = -ENOBUFS; - goto out; - } - - max_data_len = IP_BUF_MAX_DATA - UIP_IPUDPH_LEN; - - PRINTF("%s: reply to peer data %p len %d\n", __FUNCTION__, data, len); - - if (len > max_data_len) { - PRINTF("%s: too much (%d bytes) data to send (max %d bytes)\n", - __FUNCTION__, len, max_data_len); - ip_buf_unref(buf); - len = -EINVAL; - goto out; - } - - /* Note that we have reversed the addresses here - * because net_reply() will reverse them again. - */ -#ifdef CONFIG_NETWORKING_WITH_IPV6 - uip_ip6addr_copy(&NET_BUF_IP(buf)->destipaddr, (uip_ip6addr_t *)&ctx->my_addr.in6_addr); - uip_ip6addr_copy(&NET_BUF_IP(buf)->srcipaddr, - (uip_ip6addr_t *)&session->addr.ipaddr); -#else - uip_ip4addr_copy(&NET_BUF_IP(buf)->destipaddr, - (uip_ip4addr_t *)&ctx->my_addr.in_addr); - uip_ip4addr_copy(&NET_BUF_IP(buf)->srcipaddr, - (uip_ip4addr_t *)&session->addr.ipaddr); -#endif - NET_BUF_UDP(buf)->destport = uip_ntohs(ctx->my_port); - NET_BUF_UDP(buf)->srcport = session->addr.port; - - uip_set_udp_conn(buf) = net_context_get_udp_connection(ctx->net_ctx); - - memcpy(net_buf_add(buf, len), data, len); - ip_buf_appdatalen(buf) = len; - ip_buf_appdata(buf) = buf->data + ip_buf_reserve(buf); - - if (net_reply(ctx->net_ctx, buf)) { - ip_buf_unref(buf); - } -out: - return len; -} -/*---------------------------------------------------------------------------*/ -static int -send_to_peer(struct dtls_context_t *ctx, session_t *session, - uint8 *data, size_t len) -{ - int ret = 0; - coap_context_t *coap_ctx; - coap_ctx = dtls_get_app_data(ctx); - - PRINTF("%s(): ctx %p session %p data %p len %d\n", __FUNCTION__, ctx, - session, data, len); - if(coap_ctx != COAP_CONTEXT_NONE && coap_ctx->is_used && session != NULL) { - ret = prepare_and_send_buf(coap_ctx, session, data, len); - if (ret < 0) { - PRINTF("%s(): cannot send data, msg discarded\n", __FUNCTION__); - } - } else { - PRINTF("%s(): msg discarded ctx %p is_used %d buf %p udp %p session %p\n", - __FUNCTION__, coap_ctx, coap_ctx ? coap_ctx->is_used : 0, - coap_ctx->buf, coap_ctx ? (coap_ctx->buf ? - uip_udp_conn(coap_ctx->buf) : NULL) : NULL, - session); - ret = -EINVAL; - } - - return ret; -} -/*---------------------------------------------------------------------------*/ -int coap_context_wait_data(coap_context_t *coap_ctx, int32_t ticks) -{ - struct net_buf *buf; - - buf = net_receive(coap_ctx->net_ctx, ticks); - if (buf) { - session_t session; - int ret; - - uip_ipaddr_copy(&session.addr.ipaddr, &UIP_IP_BUF(buf)->srcipaddr); - session.addr.port = UIP_UDP_BUF(buf)->srcport; - session.size = sizeof(session.addr); - session.ifindex = 1; - - PRINTF("coap-context: got dtls message from "); - PRINT6ADDR(&session.addr.ipaddr); - PRINTF(":%d %u bytes\n", uip_ntohs(session.addr.port), uip_appdatalen(buf)); - - PRINTF("Received appdata %p appdatalen %d\n", - ip_buf_appdata(buf), ip_buf_appdatalen(buf)); - - coap_ctx->buf = buf; - - ret = dtls_handle_message(coap_ctx->dtls_context, &session, - ip_buf_appdata(buf), ip_buf_appdatalen(buf)); - - /* We always release the buffer here as this buffer is never sent - * to network anyway. - */ - if (coap_ctx->buf) { - ip_buf_unref(coap_ctx->buf); - coap_ctx->buf = NULL; - } - - return ret; - } - - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -event(struct dtls_context_t *ctx, session_t *session, - dtls_alert_level_t level, unsigned short code) -{ - coap_context_t *coap_ctx; - coap_ctx = dtls_get_app_data(ctx); - - if(coap_ctx == COAP_CONTEXT_NONE || coap_ctx->is_used == 0) { - /* The context is no longer in use */ - } else if(code == DTLS_EVENT_CONNECTED) { - coap_ctx->status = STATUS_CONNECTED; - PRINTF("coap-context: DTLS CLIENT CONNECTED!\n"); - process_post(coap_ctx->process, coap_context_event, coap_ctx); - } else if(code == DTLS_EVENT_CONNECT || code == DTLS_EVENT_RENEGOTIATE) { - coap_ctx->status = STATUS_CONNECTING; - PRINTF("coap-context: DTLS CLIENT NOT CONNECTED!\n"); - process_post(coap_ctx->process, coap_context_event, coap_ctx); - } else if(level == DTLS_ALERT_LEVEL_FATAL && code < 256) { - /* Fatal alert */ - if (coap_ctx && coap_ctx->buf) { - ip_buf_unref(coap_ctx->buf); - coap_ctx->buf = NULL; - } - coap_ctx->status = STATUS_ALERT; - PRINTF("coap-context: DTLS CLIENT ALERT %u!\n", code); - process_post(coap_ctx->process, coap_context_event, coap_ctx); - } - return 0; -} -/*---------------------------------------------------------------------------*/ -int -coap_context_is_secure(const coap_context_t *coap_ctx) -{ - /* Assume all contexts are secure except for the no context */ - if(coap_ctx != COAP_CONTEXT_NONE) { - return coap_ctx->is_used; - } - return 0; -} -/*---------------------------------------------------------------------------*/ -int -coap_context_is_connecting(const coap_context_t *coap_ctx) -{ - /* Assume all non secure contexts are connected by default */ - if(coap_ctx == COAP_CONTEXT_NONE || !coap_ctx->is_used) { - return 0; - } - return coap_ctx->status == STATUS_CONNECTING; -} -/*---------------------------------------------------------------------------*/ -int -coap_context_is_connected(const coap_context_t *coap_ctx) -{ - /* Assume all non secure contexts are connected by default */ - if(coap_ctx == COAP_CONTEXT_NONE || !coap_ctx->is_used) { - return 1; - } - return coap_ctx->status == STATUS_CONNECTED; -} -/*---------------------------------------------------------------------------*/ -int -coap_context_has_errors(const coap_context_t *coap_ctx) -{ - /* Assume all non secure contexts are connected by default */ - if(coap_ctx == COAP_CONTEXT_NONE || !coap_ctx->is_used) { - return 0; - } - return coap_ctx->status == STATUS_ALERT; -} -/*---------------------------------------------------------------------------*/ -coap_context_t * -coap_context_new(uip_ipaddr_t *my_addr, uint16_t port) -{ - coap_context_t *ctx = NULL; - int i; - for(i = 0; i < MAX_CONTEXTS; i++) { - if(!coap_contexts[i].is_used) { - ctx = &coap_contexts[i]; - break; - } - } - - if(ctx == NULL) { - PRINTF("coap-context: no free contexts\n"); - return NULL; - } - - memset(ctx, 0, sizeof(coap_context_t)); - - /* initialize context */ - ctx->dtls_context = dtls_new_context(ctx); - if(ctx->dtls_context == NULL) { - PRINTF("coap-context: failed to get DTLS context\n"); - uip_udp_remove(uip_udp_conn(ctx->buf)); - return NULL; - } - - ctx->dtls_handler.write = send_to_peer; - ctx->dtls_handler.read = get_from_peer; - ctx->dtls_handler.event = event; - - dtls_set_handler(ctx->dtls_context, &ctx->dtls_handler); - -#ifdef NETSTACK_CONF_WITH_IPV6 - memcpy(&ctx->my_addr.in6_addr, my_addr, sizeof(ctx->my_addr.in6_addr)); -#else - memcpy(&ctx->my_addr.in_addr, my_addr, sizeof(ctx->my_addr.in_addr)); -#endif - ctx->my_port = port; - - ctx->process = PROCESS_CURRENT(); - ctx->is_used = 1; - PRINTF("Secure listening on port %u\n", port); - - return ctx; -} -/*---------------------------------------------------------------------------*/ -void -coap_context_set_key_handlers(coap_context_t *ctx, - dtls_get_psk_info_t get_psk_info, - dtls_get_ecdsa_key_t get_ecdsa_key, - dtls_verify_ecdsa_key_t verify_ecdsa_key) -{ - if (!ctx) { - return; - } - -#ifdef DTLS_PSK - ctx->dtls_handler.get_psk_info = get_psk_info; -#endif /* DTLS_PSK */ -#ifdef DTLS_ECC - ctx->dtls_handler.get_ecdsa_key = get_ecdsa_key; - ctx->dtls_handler.verify_ecdsa_key = verify_ecdsa_key; -#endif /* DTLS_ECC */ -} -/*---------------------------------------------------------------------------*/ -void -coap_context_close(coap_context_t *coap_ctx) -{ - if(coap_ctx == NULL || coap_ctx->is_used == 0) { - /* Not opened */ - return; - } - if(coap_ctx->dtls_context != NULL) { - dtls_free_context(coap_ctx->dtls_context); - } - if(coap_ctx->buf && uip_udp_conn(coap_ctx->buf) != NULL) { - uip_udp_remove(uip_udp_conn(coap_ctx->buf)); - } - coap_ctx->is_used = 0; -} -/*---------------------------------------------------------------------------*/ -int -coap_context_connect(coap_context_t *coap_ctx, uip_ipaddr_t *addr, uint16_t port) -{ - session_t session; - - if(coap_ctx == NULL || coap_ctx->is_used == 0) { - return 0; - } - -#ifdef NETSTACK_CONF_WITH_IPV6 - memcpy(&coap_ctx->addr.in6_addr, addr, sizeof(coap_ctx->addr.in6_addr)); - coap_ctx->addr.family = AF_INET6; -#else - memcpy(&coap_ctx->addr.in_addr, addr, sizeof(coap_ctx->addr.in_addr)); - coap_ctx->addr.family = AF_INET; -#endif - coap_ctx->port = port; - - coap_ctx->net_ctx = net_context_get(IPPROTO_UDP, - (const struct net_addr *)&coap_ctx->addr, - coap_ctx->port, - (const struct net_addr *)&coap_ctx->my_addr, - coap_ctx->my_port); - if (!coap_ctx->net_ctx) { - PRINTF("%s: Cannot get network context\n", __FUNCTION__); - return 0; - } - - uip_ipaddr_copy(&session.addr.ipaddr, addr); - session.addr.port = UIP_HTONS(port); - session.size = sizeof(session.addr); - session.ifindex = 1; - coap_ctx->status = STATUS_CONNECTING; - PRINTF("coap-context: DTLS CONNECT TO ["); - PRINT6ADDR(addr); - PRINTF("]:%u\n", uip_ntohs(port)); - if(dtls_connect(coap_ctx->dtls_context, &session) >= 0) { - return 1; - } - - /* Failed to initiate connection */ - coap_ctx->status = STATUS_ALERT; - return 0; -} -/*---------------------------------------------------------------------------*/ -int -coap_context_send_message(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port, - const uint8_t *data, uint16_t length) -{ - int res; - session_t sn; - - if(coap_ctx == NULL || coap_ctx->is_used == 0) { - PRINTF("coap-context: can not send on non-used context\n"); - return 0; - } - - uip_ipaddr_copy(&sn.addr.ipaddr, addr); - sn.addr.port = port; - sn.size = sizeof(sn.addr); - sn.ifindex = 1; - - res = dtls_write(coap_ctx->dtls_context, &sn, (uint8 *)data, length); - if(res < 0) { - PRINTF("coap-context: Failed to send with dtls (%d)\n", res); - } else if (res == 0) { - PRINTF("coap-context: No data sent with DTLS but connection made.\n"); - } - return res; -} -/*---------------------------------------------------------------------------*/ -void -coap_context_init(void) -{ - dtls_init(); - - coap_context_event = process_alloc_event(); - - process_start(&coap_context_process, NULL, NULL); -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(coap_context_process, ev, data, buf, user_data) -{ - PROCESS_BEGIN(); - - PROCESS_PAUSE(); - - while(1) { - PROCESS_WAIT_EVENT(); - - if(ev == tcpip_event) { - /* The data reading in Zephyr is done in coap_context_wait_data() or - * equiv. so this code block is no-op atm. - */ - } - } /* while (1) */ - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ - -#else /* WITH_DTLS */ - -/*---------------------------------------------------------------------------*/ -coap_context_t * -coap_context_new(uip_ipaddr_t *my_addr, uint16_t port) -{ - coap_context_t *ctx = NULL; - int i; - for(i = 0; i < MAX_CONTEXTS; i++) { - if(!coap_contexts[i].is_used) { - ctx = &coap_contexts[i]; - break; - } - } - - if(ctx == NULL) { - PRINTF("coap-context: no free contexts\n"); - return NULL; - } - - memset(ctx, 0, sizeof(coap_context_t)); - -#ifdef NETSTACK_CONF_WITH_IPV6 - memcpy(&ctx->my_addr.in6_addr, my_addr, sizeof(ctx->my_addr.in6_addr)); -#else - memcpy(&ctx->my_addr.in_addr, my_addr, sizeof(ctx->my_addr.in_addr)); -#endif - ctx->my_port = port; - - ctx->is_used = 1; - PRINTF("Listening on port %u\n", port); - - return ctx; -} -/*---------------------------------------------------------------------------*/ -void -coap_context_close(coap_context_t *coap_ctx) -{ - if(coap_ctx == NULL || coap_ctx->is_used == 0) { - /* Not opened */ - return; - } - if(coap_ctx->buf && uip_udp_conn(coap_ctx->buf) != NULL) { - uip_udp_remove(uip_udp_conn(coap_ctx->buf)); - } - - net_context_put(coap_ctx->net_ctx); - - coap_ctx->is_used = 0; -} -/*---------------------------------------------------------------------------*/ -int coap_context_reply(coap_context_t *ctx, struct net_buf *buf) -{ - int max_data_len, ret; - - max_data_len = IP_BUF_MAX_DATA - UIP_IPUDPH_LEN; - - PRINTF("%s: reply to peer data %p len %d\n", __FUNCTION__, - ip_buf_appdata(buf), ip_buf_appdatalen(buf)); - - if (ip_buf_appdatalen(buf) > max_data_len) { - PRINTF("%s: too much (%d bytes) data to send (max %d bytes)\n", - __FUNCTION__, ip_buf_appdatalen(buf), max_data_len); - ip_buf_unref(buf); - ret = -EINVAL; - goto out; - } - - if (net_reply(ctx->net_ctx, buf)) { - ip_buf_unref(buf); - } -out: - return ret; -} -/*---------------------------------------------------------------------------*/ -int coap_context_wait_data(coap_context_t *coap_ctx, int32_t ticks) -{ - struct net_buf *buf; - - buf = net_receive(coap_ctx->net_ctx, ticks); - if (buf) { - PRINTF("coap-context: got message from "); - PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr); - PRINTF(":%d %u bytes\n", uip_ntohs(UIP_UDP_BUF(buf)->srcport), - uip_appdatalen(buf)); - - PRINTF("Received data appdata %p appdatalen %d\n", - ip_buf_appdata(buf), ip_buf_appdatalen(buf)); - - coap_ctx->buf = buf; - - coap_engine_receive(coap_ctx); - - return 1; - } - - return 0; -} -/*---------------------------------------------------------------------------*/ -static int coap_context_send(coap_context_t *ctx, struct net_buf *buf) -{ - int max_data_len, ret; - - max_data_len = IP_BUF_MAX_DATA - UIP_IPUDPH_LEN; - - PRINTF("%s: send to peer data %p len %d\n", __FUNCTION__, - ip_buf_appdata(buf), ip_buf_appdatalen(buf)); - - if (ip_buf_appdatalen(buf) > max_data_len) { - PRINTF("%s: too much (%d bytes) data to send (max %d bytes)\n", - __FUNCTION__, ip_buf_appdatalen(buf), max_data_len); - ip_buf_unref(buf); - ret = -EINVAL; - goto out; - } - - ret = net_send(buf); - if (ret < 0) { - PRINT("%s: sending %d bytes failed\n", __FUNCTION__, - ip_buf_appdatalen(buf)); - ip_buf_unref(buf); - } - -out: - return ret; -} -/*---------------------------------------------------------------------------*/ -int -coap_context_send_message(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port, - const uint8_t *data, uint16_t length) -{ - int ret; - - if(coap_ctx == NULL || coap_ctx->is_used == 0) { - PRINTF("coap-context: can not send on non-used context\n"); - return 0; - } - - ip_buf_appdatalen(coap_ctx->buf) = length; - - if (!uip_udp_conn(coap_ctx->buf)) { - /* Normal send, not a reply */ - ret = coap_context_send(coap_ctx, coap_ctx->buf); - - } else { - - /* We need to set the uIP buffer lengths in net_buf properly as - * otherwise the final buffer length in - * net_init.c:udp_prepare_and_send() will be usually incorrect - * (uip_len() will be length of the received packet). So by setting - * uip_len() to 0 here, we let the sending in net_init.c to - * set the send buffer length correctly. - */ - uip_len(coap_ctx->buf) = 0; - memcpy(ip_buf_appdata(coap_ctx->buf), data, length); - - ret = coap_context_reply(coap_ctx, coap_ctx->buf); - } - - coap_ctx->buf = NULL; - return ret; -} -/*---------------------------------------------------------------------------*/ -int -coap_context_connect(coap_context_t *coap_ctx, uip_ipaddr_t *addr, uint16_t port) -{ - if(coap_ctx == NULL || coap_ctx->is_used == 0) { - return 0; - } - -#ifdef NETSTACK_CONF_WITH_IPV6 - memcpy(&coap_ctx->addr.in6_addr, addr, sizeof(coap_ctx->addr.in6_addr)); - coap_ctx->addr.family = AF_INET6; -#else - memcpy(&coap_ctx->addr.in_addr, addr, sizeof(coap_ctx->addr.in_addr)); - coap_ctx->addr.family = AF_INET; -#endif - coap_ctx->port = port; - - coap_ctx->net_ctx = net_context_get(IPPROTO_UDP, - (const struct net_addr *)&coap_ctx->addr, - coap_ctx->port, - (struct net_addr *)&coap_ctx->my_addr, - coap_ctx->my_port); - if (!coap_ctx->net_ctx) { - PRINTF("%s: Cannot get network context\n", __FUNCTION__); - return 0; - } - - PRINTF("coap-context: normal connect to ["); - PRINT6ADDR(addr); - PRINTF("]:%u\n", port); - - return 1; -} - -#endif /* WITH_DTLS */ - -/*---------------------------------------------------------------------------*/ -int coap_context_listen(coap_context_t *coap_ctx, uip_ipaddr_t *peer_addr, - uint16_t peer_port) -{ - if(coap_ctx == NULL || coap_ctx->is_used == 0) { - return 0; - } - -#ifdef NETSTACK_CONF_WITH_IPV6 - memcpy(&coap_ctx->addr.in6_addr, peer_addr, sizeof(coap_ctx->addr.in6_addr)); - coap_ctx->addr.family = AF_INET6; -#else - memcpy(&coap_ctx->addr.in_addr, peer_addr, sizeof(coap_ctx->addr.in_addr)); - coap_ctx->addr.family = AF_INET; -#endif - coap_ctx->port = peer_port; - - coap_ctx->net_ctx = net_context_get(IPPROTO_UDP, - (const struct net_addr *)&coap_ctx->addr, - coap_ctx->port, - (struct net_addr *)&coap_ctx->my_addr, - coap_ctx->my_port); - if (!coap_ctx->net_ctx) { - PRINTF("%s: Cannot get network context\n", __FUNCTION__); - return 0; - } - - return 1; -} diff --git a/net/ip/er-coap/er-coap-context.h b/net/ip/er-coap/er-coap-context.h deleted file mode 100644 index 2ad6b5603dc6592dd64e365cd59eed61dd290da5..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-context.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2015, SICS, Swedish ICT AB. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/** - * \file - * CoAP context handling - * \author - * Niclas Finne - * Joakim Eriksson - */ - -#ifndef COAP_CONTEXT_H_ -#define COAP_CONTEXT_H_ - -#include -#include - -#include "contiki-conf.h" -#include "sys/process.h" -#include "contiki/ip/uip.h" - -#if ER_COAP_WITH_DTLS -#define WITH_DTLS 1 -#else -#undef WITH_DTLS -#endif - -#ifdef WITH_DTLS -#include "dtls.h" -#endif /* WITH_DTLS */ - -typedef struct coap_context { - struct net_buf *buf; - struct net_context *net_ctx; - struct net_addr my_addr; - uint16_t my_port; - //struct uip_udp_conn *conn; This is found in net_buf - struct net_addr addr; - uint16_t port; -#ifdef WITH_DTLS - struct dtls_context_t *dtls_context; - dtls_handler_t dtls_handler; - struct process *process; -#endif /* WITH_DTLS */ - uint8_t status; - uint8_t is_used; -} coap_context_t; - -#define COAP_CONTEXT_NONE NULL - -int coap_context_listen(coap_context_t *coap_ctx, uip_ipaddr_t *peer_addr, - uint16_t peer_port); -coap_context_t *coap_context_new(uip_ipaddr_t *my_addr, uint16_t port); -void coap_context_close(coap_context_t *coap_ctx); -int coap_context_send_message(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port, - const uint8_t *data, uint16_t length); -int coap_context_wait_data(coap_context_t *coap_ctx, int32_t ticks); -int coap_context_connect(coap_context_t *coap_ctx, uip_ipaddr_t *addr, - uint16_t port); - -#if WITH_DTLS - -extern process_event_t coap_context_event; - -int coap_context_is_secure(const coap_context_t *coap_ctx); -int coap_context_is_connected(const coap_context_t *coap_ctx); -int coap_context_is_connecting(const coap_context_t *coap_ctx); -int coap_context_has_errors(const coap_context_t *coap_ctx); -int coap_context_connect(coap_context_t *coap_ctx, uip_ipaddr_t *addr, uint16_t port); - -typedef int (*dtls_get_psk_info_t)(struct dtls_context_t *ctx, - const session_t *session, - dtls_credentials_type_t type, - const unsigned char *id, size_t id_len, - unsigned char *result, size_t result_length); -typedef int (*dtls_get_ecdsa_key_t)(struct dtls_context_t *ctx, - const session_t *session, - const dtls_ecdsa_key_t **result); -typedef int (*dtls_verify_ecdsa_key_t)(struct dtls_context_t *ctx, - const session_t *session, - const unsigned char *other_pub_x, - const unsigned char *other_pub_y, - size_t key_size); -void coap_context_set_key_handlers(coap_context_t *ctx, - dtls_get_psk_info_t get_psk_info, - dtls_get_ecdsa_key_t get_ecdsa_key, - dtls_verify_ecdsa_key_t verify_ecdsa_key); - -void coap_context_init(void); - -#define COAP_CONTEXT_CONNECT(coap_ctx, server_addr, server_port) \ - do { \ - if(coap_context_connect(coap_ctx, server_addr, server_port)) { \ - PROCESS_WAIT_EVENT_UNTIL(!coap_context_is_connecting(coap_ctx); \ - } \ - } while(0) - -#else /* WITH_DTLS */ - -#define coap_context_event 0 - -static inline int -coap_context_is_secure(const coap_context_t *coap_ctx) -{ - return 0; -} -static inline int -coap_context_is_connected(const coap_context_t *coap_ctx) -{ - return 1; -} -static inline int -coap_context_is_connecting(const coap_context_t *coap_ctx) -{ - return 0; -} -static inline int -coap_context_has_errors(const coap_context_t *coap_ctx) -{ - return 0; -} -static inline void -coap_context_init(void) -{ -} -int coap_context_reply(coap_context_t *ctx, struct net_buf *buf); - -#define COAP_CONTEXT_CONNECT(coap_ctx, server_addr, server_port) \ - do { } while(0) - -#define coap_context_set_key_handlers(...) - -#endif /* WITH_DTLS */ - -#define COAP_CONTEXT_BLOCKING_REQUEST(coap_ctx, server_addr, server_port, request, chunk_handler) \ - { \ - static struct request_state_t request_state; \ - PT_SPAWN(process_pt, &request_state.pt, \ - coap_blocking_request(&request_state, ev, coap_ctx, \ - server_addr, server_port, \ - request, chunk_handler) \ - ); \ - } - -#endif /* COAP_CONTEXT_H_ */ diff --git a/net/ip/er-coap/er-coap-engine.c b/net/ip/er-coap/er-coap-engine.c deleted file mode 100644 index 9f43be4166365023bac374bed5ac14a4ba743c45..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-engine.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP implementation for the REST Engine. - * \author - * Matthias Kovatsch - */ - -#include "sys/cc.h" -#include -#include -#include -#include "er-coap-engine.h" -#include "er-coap-context.h" - -#if CONFIG_NETWORK_IP_STACK_DEBUG_COAP_ENGINE -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -PROCESS(coap_engine, "CoAP Engine"); - -/*---------------------------------------------------------------------------*/ -/*- Variables ---------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -static service_callback_t service_cbk = NULL; - -#if NET_COAP_CONF_STATS -net_coap_stats_t net_coap_stats; -#endif /* NET_COAP_CONF_STATS */ - -/*---------------------------------------------------------------------------*/ -/*- Internal API ------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -int -coap_engine_receive(coap_context_t *coap_ctx) -{ - erbium_status_code = NO_ERROR; - coap_packet_t message[1]; /* this way the packet can be treated as pointer as usual */ - coap_packet_t response[1]; - coap_transaction_t *transaction = NULL; - - PRINTF("%s(): received data len %u\n", __FUNCTION__, - (uint16_t)uip_appdatalen(coap_ctx->buf)); - - if(uip_newdata(coap_ctx->buf)) { - - PRINTF("receiving UDP datagram from: "); - PRINT6ADDR(&UIP_IP_BUF(coap_ctx->buf)->srcipaddr); - PRINTF(":%u\n Length: %u\n", - uip_ntohs(UIP_UDP_BUF(coap_ctx->buf)->srcport), - uip_appdatalen(coap_ctx->buf)); - - erbium_status_code = - coap_parse_message(message, uip_appdata(coap_ctx->buf), uip_appdatalen(coap_ctx->buf)); - coap_set_context(message, coap_ctx); - - if(erbium_status_code == NO_ERROR) { - - NET_COAP_STAT(recv++); - - /*TODO duplicates suppression, if required by application */ - - PRINTF(" Parsed: v %u, t %u, tkl %u, c %u, mid %u\n", message->version, - message->type, message->token_len, message->code, message->mid); - PRINTF(" URL[%d]: %.*s\n", message->uri_path_len, message->uri_path_len, message->uri_path); - PRINTF(" Payload[%d]: %.*s\n", message->payload_len, message->payload_len, message->payload); - - /* handle requests */ - if(message->code >= COAP_GET && message->code <= COAP_DELETE) { - - /* use transaction buffer for response to confirmable request */ - if((transaction = coap_new_transaction(message->mid, coap_ctx, - &UIP_IP_BUF(coap_ctx->buf)->srcipaddr, - UIP_UDP_BUF(coap_ctx->buf)->srcport))) { - uint32_t block_num = 0; - uint16_t block_size = REST_MAX_CHUNK_SIZE; - uint32_t block_offset = 0; - int32_t new_offset = 0; - - /* prepare response */ - if(message->type == COAP_TYPE_CON) { - /* reliable CON requests are answered with an ACK */ - coap_init_message(response, COAP_TYPE_ACK, CONTENT_2_05, - message->mid); - } else { - /* unreliable NON requests are answered with a NON as well */ - coap_init_message(response, COAP_TYPE_NON, CONTENT_2_05, - coap_get_mid()); - /* mirror token */ - } if(message->token_len) { - coap_set_token(response, message->token, message->token_len); - /* get offset for blockwise transfers */ - } - if(coap_get_header_block2 - (message, &block_num, NULL, &block_size, &block_offset)) { - PRINTF("Blockwise: block request %lu (%u/%u) @ %lu bytes\n", - (unsigned long)block_num, block_size, REST_MAX_CHUNK_SIZE, (unsigned long)block_offset); - block_size = MIN(block_size, REST_MAX_CHUNK_SIZE); - new_offset = block_offset; - } - - /* invoke resource handler */ - if(service_cbk) { - - /* call REST framework and check if found and allowed */ - if(service_cbk - (message, response, transaction->packet + COAP_MAX_HEADER_SIZE, - block_size, &new_offset)) { - - if(erbium_status_code == NO_ERROR) { - - /* TODO coap_handle_blockwise(request, response, start_offset, end_offset); */ - - /* resource is unaware of Block1 */ - if(IS_OPTION(message, COAP_OPTION_BLOCK1) - && response->code < BAD_REQUEST_4_00 - && !IS_OPTION(response, COAP_OPTION_BLOCK1)) { - PRINTF("Block1 NOT IMPLEMENTED\n"); - - erbium_status_code = NOT_IMPLEMENTED_5_01; - coap_error_message = "NoBlock1Support"; - - /* client requested Block2 transfer */ - } else if(IS_OPTION(message, COAP_OPTION_BLOCK2)) { - - /* unchanged new_offset indicates that resource is unaware of blockwise transfer */ - if(new_offset == block_offset) { - PRINTF - ("Blockwise: unaware resource with payload length %u/%u\n", - response->payload_len, block_size); - if(block_offset >= response->payload_len) { - PRINTF - ("handle_incoming_data(): block_offset >= response->payload_len\n"); - - response->code = BAD_OPTION_4_02; - coap_set_payload(response, "BlockOutOfScope", 15); /* a const char str[] and sizeof(str) produces larger code size */ - } else { - coap_set_header_block2(response, block_num, - response->payload_len - - block_offset > block_size, - block_size); - coap_set_payload(response, - response->payload + block_offset, - MIN(response->payload_len - - block_offset, block_size)); - } /* if(valid offset) */ - - /* resource provides chunk-wise data */ - } else { - PRINTF("Blockwise: blockwise resource, new offset %ld\n", - (long)new_offset); - coap_set_header_block2(response, block_num, - new_offset != -1 - || response->payload_len > - block_size, block_size); - - if(response->payload_len > block_size) { - coap_set_payload(response, response->payload, - block_size); - } - } /* if(resource aware of blockwise) */ - - /* Resource requested Block2 transfer */ - } else if(new_offset != 0) { - PRINTF - ("Blockwise: no block option for blockwise resource, using block size %u\n", - COAP_MAX_BLOCK_SIZE); - - coap_set_header_block2(response, 0, new_offset != -1, - COAP_MAX_BLOCK_SIZE); - coap_set_payload(response, response->payload, - MIN(response->payload_len, - COAP_MAX_BLOCK_SIZE)); - } /* blockwise transfer handling */ - } /* no errors/hooks */ - /* successful service callback */ - /* serialize response */ - } - if(erbium_status_code == NO_ERROR) { - if((transaction->packet_len = coap_serialize_message(response, - transaction-> - packet)) == - 0) { - erbium_status_code = PACKET_SERIALIZATION_ERROR; - } - } - } else { - erbium_status_code = NOT_IMPLEMENTED_5_01; - coap_error_message = "NoServiceCallbck"; /* no 'a' to fit into 16 bytes */ - } /* if(service callback) */ - } else { - erbium_status_code = SERVICE_UNAVAILABLE_5_03; - coap_error_message = "NoFreeTraBuffer"; - } /* if(transaction buffer) */ - - /* handle responses */ - } else { - - if(message->type == COAP_TYPE_CON && message->code == 0) { - PRINTF("Received Ping\n"); - erbium_status_code = PING_RESPONSE; - } else if(message->type == COAP_TYPE_ACK) { - /* transactions are closed through lookup below */ - PRINTF("Received ACK\n"); - } else if(message->type == COAP_TYPE_RST) { - PRINTF("Received RST\n"); - /* cancel possible subscriptions */ - coap_remove_observer_by_mid(coap_ctx, &UIP_IP_BUF(coap_ctx->buf)->srcipaddr, - UIP_UDP_BUF(coap_ctx->buf)->srcport, message->mid); - } - - if((transaction = coap_get_transaction_by_mid(message->mid))) { - /* free transaction memory before callback, as it may create a new transaction */ - restful_response_handler callback = transaction->callback; - void *callback_data = transaction->callback_data; - - coap_clear_transaction(transaction); - - /* check if someone registered for the response */ - if(callback) { - callback(callback_data, message); - } - } - /* if(ACKed transaction) */ - transaction = NULL; - -#if COAP_OBSERVE_CLIENT - /* if observe notification */ - if((message->type == COAP_TYPE_CON || message->type == COAP_TYPE_NON) - && IS_OPTION(message, COAP_OPTION_OBSERVE)) { - PRINTF("Observe [%u]\n", message->observe); - coap_handle_notification(coap_ctx, &UIP_IP_BUF(coap_ctx->buf)->srcipaddr, - UIP_UDP_BUF(coap_ctx->buf)->srcport, message); - } -#endif /* COAP_OBSERVE_CLIENT */ - } /* request or response */ - } else { /* parsed correctly */ - NET_COAP_STAT(recv_err++); - } - - /* if(parsed correctly) */ - if(erbium_status_code == NO_ERROR) { - if(transaction) { - coap_send_transaction(transaction); - } - } else if(erbium_status_code == MANUAL_RESPONSE) { - PRINTF("Clearing transaction for manual response"); - coap_clear_transaction(transaction); - } else { - coap_message_type_t reply_type = COAP_TYPE_ACK; - - PRINTF("ERROR %u: %s\n", erbium_status_code, coap_error_message); - coap_clear_transaction(transaction); - - if(erbium_status_code == PING_RESPONSE) { - erbium_status_code = 0; - reply_type = COAP_TYPE_RST; - } else if(erbium_status_code >= 192) { - /* set to sendable error code */ - erbium_status_code = INTERNAL_SERVER_ERROR_5_00; - /* reuse input buffer for error message */ - } - coap_init_message(message, reply_type, erbium_status_code, - message->mid); - coap_set_payload(message, coap_error_message, - strlen(coap_error_message)); - coap_send_message(coap_ctx, &UIP_IP_BUF(coap_ctx->buf)->srcipaddr, - UIP_UDP_BUF(coap_ctx->buf)->srcport, - uip_appdata(coap_ctx->buf), - coap_serialize_message(message, - uip_appdata(coap_ctx->buf))); - } - } - - /* if(new data) */ - return erbium_status_code; -} -/*---------------------------------------------------------------------------*/ -void -coap_init_engine(void) -{ - coap_context_init(); - process_start(&coap_engine, NULL, NULL); -} -/*---------------------------------------------------------------------------*/ -void -coap_set_service_callback(service_callback_t callback) -{ - service_cbk = callback; -} -/*---------------------------------------------------------------------------*/ -rest_resource_flags_t -coap_get_rest_method(void *packet) -{ - return (rest_resource_flags_t)(1 << - (((coap_packet_t *)packet)->code - 1)); -} -/*---------------------------------------------------------------------------*/ -/*- Server Part -------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -/* the discover resource is automatically included for CoAP */ -extern resource_t res_well_known_core; - -coap_context_t *coap_init_server(uip_ipaddr_t *server_addr, - uint16_t server_port, - uip_ipaddr_t *peer_addr, - uint16_t peer_port) -{ - PRINTF("Starting %s receiver...\n", coap_rest_implementation.name); - - rest_activate_resource(&res_well_known_core, ".well-known/core"); - - coap_register_as_transaction_handler(); - return coap_init_connection(server_addr, server_port, peer_addr, peer_port); -} - -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(coap_engine, ev, data, buf, user_data) -{ - PROCESS_BEGIN(); -#if 0 - /* This is not used in Zephyr. */ - PRINTF("Starting %s receiver...\n", coap_rest_implementation.name); - - rest_activate_resource(&res_well_known_core, ".well-known/core"); - - coap_register_as_transaction_handler(); - coap_init_connection(SERVER_LISTEN_PORT); - - while(1) { - PROCESS_YIELD(); - - if(ev == tcpip_event) { - coap_engine_receive(COAP_CONTEXT_NONE); - - } else if(ev == PROCESS_EVENT_TIMER) { - /* retransmissions are handled here */ - coap_check_transactions(); - } - } /* while (1) */ -#endif /* 0 */ - PROCESS_END(); -} - -/*---------------------------------------------------------------------------*/ -/*- Client Part -------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -void -coap_blocking_request_callback(void *callback_data, void *response) -{ - struct request_state_t *state = (struct request_state_t *)callback_data; - - state->response = (coap_packet_t *)response; - process_poll(state->process); -} -/*---------------------------------------------------------------------------*/ -PT_THREAD(coap_blocking_request - (struct request_state_t *state, process_event_t ev, - coap_context_t *coap_ctx, - uip_ipaddr_t *remote_ipaddr, uint16_t remote_port, - coap_packet_t *request, - blocking_response_handler request_callback)) -{ - PT_BEGIN(&state->pt); - - static uint8_t more; - static uint32_t res_block; - static uint8_t block_error; - - state->block_num = 0; - state->response = NULL; - state->process = PROCESS_CURRENT(); - - more = 0; - res_block = 0; - block_error = 0; - - do { - request->mid = coap_get_mid(); - if((state->transaction = coap_new_transaction(request->mid, coap_ctx, - remote_ipaddr, remote_port))) { - state->transaction->callback = coap_blocking_request_callback; - state->transaction->callback_data = state; - - if(state->block_num > 0) { - coap_set_header_block2(request, state->block_num, 0, - REST_MAX_CHUNK_SIZE); - } - state->transaction->packet_len = coap_serialize_message(request, - state-> - transaction-> - packet); - - coap_send_transaction(state->transaction); - PRINTF("Requested #%lu (MID %u)\n", (unsigned long)state->block_num, request->mid); - - PT_YIELD_UNTIL(&state->pt, ev == PROCESS_EVENT_POLL); - - if(!state->response) { - PRINTF("Server not responding\n"); - PT_EXIT(&state->pt); - } - - coap_get_header_block2(state->response, &res_block, &more, NULL, NULL); - - PRINTF("Received #%lu%s (%u bytes)\n", (unsigned long)res_block, more ? "+" : "", - state->response->payload_len); - - if(res_block == state->block_num) { - request_callback(state->response); - ++(state->block_num); - } else { - PRINTF("WRONG BLOCK %lu/%lu\n", (unsigned long)res_block, (unsigned long)state->block_num); - ++block_error; - } - } else { - PRINTF("%s: Could not allocate transaction buffer", __FUNCTION__); - PT_EXIT(&state->pt); - } - } while(more && block_error < COAP_MAX_ATTEMPTS); - - PT_END(&state->pt); -} -/*---------------------------------------------------------------------------*/ -/*- REST Engine Interface ---------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -const struct rest_implementation coap_rest_implementation = { - .name = "CoAP-18", - - .init = coap_init_engine, - .set_service_callback = coap_set_service_callback, - - .get_url = coap_get_header_uri_path, - .get_method_type = coap_get_rest_method, - .set_response_status = coap_set_status_code, - - .get_header_content_type = coap_get_header_content_format, - .set_header_content_type = coap_set_header_content_format, - .get_header_accept = coap_get_header_accept, - .get_header_length = coap_get_header_size2, - .set_header_length = coap_set_header_size2, - .get_header_max_age = coap_get_header_max_age, - .set_header_max_age = coap_set_header_max_age, - .set_header_etag = coap_set_header_etag, - .get_header_if_match = coap_get_header_if_match, - .get_header_if_none_match = coap_get_header_if_none_match, - .get_header_host = coap_get_header_uri_host, - .set_header_location = coap_set_header_location_path, - - .get_request_payload = coap_get_payload, - .set_response_payload = coap_set_payload, - - .get_query = coap_get_header_uri_query, - .get_query_variable = coap_get_query_variable, - .get_post_variable = coap_get_post_variable, - - .notify_subscribers = coap_notify_observers, - .subscription_handler = coap_observe_handler, - - .status = { - CONTENT_2_05, - CREATED_2_01, - CHANGED_2_04, - DELETED_2_02, - VALID_2_03, - BAD_REQUEST_4_00, - UNAUTHORIZED_4_01, - BAD_OPTION_4_02, - FORBIDDEN_4_03, - NOT_FOUND_4_04, - METHOD_NOT_ALLOWED_4_05, - NOT_ACCEPTABLE_4_06, - REQUEST_ENTITY_TOO_LARGE_4_13, - UNSUPPORTED_MEDIA_TYPE_4_15, - INTERNAL_SERVER_ERROR_5_00, - NOT_IMPLEMENTED_5_01, - BAD_GATEWAY_5_02, - SERVICE_UNAVAILABLE_5_03, - GATEWAY_TIMEOUT_5_04, - PROXYING_NOT_SUPPORTED_5_05 - }, - - .type = { - TEXT_PLAIN, - TEXT_XML, - TEXT_CSV, - TEXT_HTML, - IMAGE_GIF, - IMAGE_JPEG, - IMAGE_PNG, - IMAGE_TIFF, - AUDIO_RAW, - VIDEO_RAW, - APPLICATION_LINK_FORMAT, - APPLICATION_XML, - APPLICATION_OCTET_STREAM, - APPLICATION_RDF_XML, - APPLICATION_SOAP_XML, - APPLICATION_ATOM_XML, - APPLICATION_XMPP_XML, - APPLICATION_EXI, - APPLICATION_FASTINFOSET, - APPLICATION_SOAP_FASTINFOSET, - APPLICATION_JSON, - APPLICATION_X_OBIX_BINARY - } -}; -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/er-coap/er-coap-engine.h b/net/ip/er-coap/er-coap-engine.h deleted file mode 100644 index b6bae4a17a39840dc9ea5ed00b72a1ea6df3abf3..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-engine.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP implementation for the REST Engine. - * \author - * Matthias Kovatsch - */ - -#ifndef ER_COAP_ENGINE_H_ -#define ER_COAP_ENGINE_H_ - -#include -#include "er-coap.h" -#include "er-coap-transactions.h" -#include "er-coap-observe.h" -#include "er-coap-separate.h" -#include "er-coap-observe-client.h" -#include "er-coap-context.h" - -#define SERVER_LISTEN_PORT UIP_HTONS(COAP_SERVER_PORT) - -typedef coap_packet_t rest_request_t; -typedef coap_packet_t rest_response_t; - -void coap_init_engine(void); -int coap_engine_receive(coap_context_t *coap_context); -coap_context_t *coap_init_server(uip_ipaddr_t *server_addr, - uint16_t server_port, - uip_ipaddr_t *peer_addr, - uint16_t peer_port); - -/*---------------------------------------------------------------------------*/ -/*- Client Part -------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -struct request_state_t { - struct pt pt; - struct process *process; - coap_transaction_t *transaction; - coap_packet_t *response; - uint32_t block_num; -}; - -typedef void (*blocking_response_handler)(void *response); - -PT_THREAD(coap_blocking_request - (struct request_state_t *state, process_event_t ev, - coap_context_t *coap_ctx, - uip_ipaddr_t *remote_ipaddr, uint16_t remote_port, - coap_packet_t *request, - blocking_response_handler request_callback)); - -#define COAP_BLOCKING_REQUEST(server_addr, server_port, request, chunk_handler) \ - { \ - static struct request_state_t request_state; \ - PT_SPAWN(process_pt, &request_state.pt, \ - coap_blocking_request(&request_state, ev, COAP_CONTEXT_NONE, \ - server_addr, server_port, \ - request, chunk_handler) \ - ); \ - } -/*---------------------------------------------------------------------------*/ - -#endif /* ER_COAP_ENGINE_H_ */ diff --git a/net/ip/er-coap/er-coap-observe-client.c b/net/ip/er-coap/er-coap-observe-client.c deleted file mode 100644 index e3d9f148990ff21b643321d4821212714aad0ac4..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-observe-client.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (c) 2014, Daniele Alessandrelli. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/* - * \file - * Extension to Erbium for enabling CoAP observe clients - * \author - * Daniele Alessandrelli - */ - -#include -#include - -#include "er-coap.h" -#include "er-coap-observe-client.h" - -/* Compile this code only if client-side support for CoAP Observe is required */ -#if COAP_OBSERVE_CLIENT - -#define DEBUG DEBUG_NONE -#include "contiki/ip/uip-debug.h" - -MEMB(obs_subjects_memb, coap_observee_t, COAP_MAX_OBSERVEES); -LIST(obs_subjects_list); - -/*----------------------------------------------------------------------------*/ -static size_t -get_token(void *packet, const uint8_t **token) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - *token = coap_pkt->token; - - return coap_pkt->token_len; -} -/*----------------------------------------------------------------------------*/ -static int -set_token(void *packet, const uint8_t *token, size_t token_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len); - memcpy(coap_pkt->token, token, coap_pkt->token_len); - - return coap_pkt->token_len; -} -/*----------------------------------------------------------------------------*/ -coap_observee_t * -coap_obs_add_observee(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port, - const uint8_t *token, size_t token_len, const char *url, - notification_callback_t notification_callback, - void *data) -{ - coap_observee_t *o; - - /* Remove existing observe relationship, if any. */ - coap_obs_remove_observee_by_url(coap_ctx, addr, port, url); - o = memb_alloc(&obs_subjects_memb); - if(o) { - o->url = url; - o->coap_ctx = coap_ctx; - uip_ipaddr_copy(&o->addr, addr); - o->port = port; - o->token_len = token_len; - memcpy(o->token, token, token_len); - /* o->last_mid = 0; */ - o->notification_callback = notification_callback; - o->data = data; - /* stimer_set(&o->refresh_timer, COAP_OBSERVING_REFRESH_INTERVAL); */ - PRINTF("Adding obs_subject for /%s [0x%02X%02X]\n", o->url, o->token[0], - o->token[1]); - list_add(obs_subjects_list, o); - } - - return o; -} -/*----------------------------------------------------------------------------*/ -void -coap_obs_remove_observee(coap_observee_t *o) -{ - PRINTF("Removing obs_subject for /%s [0x%02X%02X]\n", o->url, o->token[0], - o->token[1]); - memb_free(&obs_subjects_memb, o); - list_remove(obs_subjects_list, o); -} -/*----------------------------------------------------------------------------*/ -coap_observee_t * -coap_get_obs_subject_by_token(const uint8_t *token, size_t token_len) -{ - coap_observee_t *obs = NULL; - - for(obs = (coap_observee_t *)list_head(obs_subjects_list); obs; - obs = obs->next) { - PRINTF("Looking for token 0x%02X%02X\n", token[0], token[1]); - if(obs->token_len == token_len - && memcmp(obs->token, token, token_len) == 0) { - return obs; - } - } - - return NULL; -} -/*----------------------------------------------------------------------------*/ -int -coap_obs_remove_observee_by_token(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port, - uint8_t *token, size_t token_len) -{ - int removed = 0; - coap_observee_t *obs = NULL; - - for(obs = (coap_observee_t *)list_head(obs_subjects_list); obs; - obs = obs->next) { - PRINTF("Remove check Token 0x%02X%02X\n", token[0], token[1]); - if(uip_ipaddr_cmp(&obs->addr, addr) - && obs->port == port - && obs->coap_ctx == coap_ctx - && obs->token_len == token_len - && memcmp(obs->token, token, token_len) == 0) { - coap_obs_remove_observee(obs); - removed++; - } - } - return removed; -} -/*----------------------------------------------------------------------------*/ -int -coap_obs_remove_observee_by_url(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port, - const char *url) -{ - int removed = 0; - coap_observee_t *obs = NULL; - - for(obs = (coap_observee_t *)list_head(obs_subjects_list); obs; - obs = obs->next) { - PRINTF("Remove check URL %s\n", url); - if(uip_ipaddr_cmp(&obs->addr, addr) - && obs->port == port - && obs->coap_ctx == coap_ctx - && (obs->url == url || memcmp(obs->url, url, strlen(obs->url)) == 0)) { - coap_obs_remove_observee(obs); - removed++; - } - } - return removed; -} -/*----------------------------------------------------------------------------*/ -static void -simple_reply(coap_message_type_t type, const coap_context_t *coap_ctx, - uip_ip6addr_t *addr, uint16_t port, - coap_packet_t *notification) -{ - static coap_packet_t response[1]; - size_t len; - - coap_init_message(response, type, NO_ERROR, notification->mid); - len = coap_serialize_message(response, uip_appdata(coap_ctx->buf)); - coap_send_message((coap_context_t *)coap_ctx, addr, port, - uip_appdata(coap_ctx->buf), len); -} -/*----------------------------------------------------------------------------*/ -static coap_notification_flag_t -classify_notification(void *response, int first) -{ - coap_packet_t *pkt; - - pkt = (coap_packet_t *)response; - if(!pkt) { - PRINTF("no response\n"); - return NO_REPLY_FROM_SERVER; - } - PRINTF("server replied\n"); - if(!IS_RESPONSE_CODE_2_XX(pkt)) { - PRINTF("error response code\n"); - return ERROR_RESPONSE_CODE; - } - if(!IS_OPTION(pkt, COAP_OPTION_OBSERVE)) { - PRINTF("server does not support observe\n"); - return OBSERVE_NOT_SUPPORTED; - } - if(first) { - return OBSERVE_OK; - } - return NOTIFICATION_OK; -} -/*----------------------------------------------------------------------------*/ -void -coap_handle_notification(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port, - coap_packet_t *notification) -{ - coap_packet_t *pkt; - const uint8_t *token; - int token_len; - coap_observee_t *obs; - coap_notification_flag_t flag; - uint32_t observe; - - PRINTF("coap_handle_notification()\n"); - pkt = (coap_packet_t *)notification; - token_len = get_token(pkt, &token); - PRINTF("Getting token\n"); - if(0 == token_len) { - PRINTF("Error while handling coap observe notification: " - "no token in message\n"); - return; - } - PRINTF("Getting observee info\n"); - obs = coap_get_obs_subject_by_token(token, token_len); - if(NULL == obs) { - PRINTF("Error while handling coap observe notification: " - "no matching token found\n"); - simple_reply(COAP_TYPE_RST, coap_ctx, addr, port, notification); - return; - } - if(notification->type == COAP_TYPE_CON) { - simple_reply(COAP_TYPE_ACK, coap_ctx, addr, port, notification); - } - if(obs->notification_callback != NULL) { - flag = classify_notification(notification, 0); - /* TODO: the following mechanism for discarding duplicates is too trivial */ - /* refer to Observe RFC for a better solution */ - if(flag == NOTIFICATION_OK) { - coap_get_header_observe(notification, &observe); - if(observe == obs->last_observe) { - PRINTF("Discarding duplicate\n"); - return; - } - obs->last_observe = observe; - } - obs->notification_callback(obs, notification, flag); - } -} -/*----------------------------------------------------------------------------*/ -static void -handle_obs_registration_response(void *data, void *response) -{ - coap_observee_t *obs; - notification_callback_t notification_callback; - coap_notification_flag_t flag; - - PRINTF("handle_obs_registration_response(): "); - obs = (coap_observee_t *)data; - notification_callback = obs->notification_callback; - flag = classify_notification(response, 1); - if(notification_callback) { - notification_callback(obs, response, flag); - } - if(flag != OBSERVE_OK) { - coap_obs_remove_observee(obs); - } -} -/*----------------------------------------------------------------------------*/ -uint8_t -coap_generate_token(uint8_t **token_ptr) -{ - static uint8_t token = 0; - - token++; - /* FIXME: we should check that this token is not already used */ - *token_ptr = (uint8_t *)&token; - return sizeof(token); -} -/*----------------------------------------------------------------------------*/ -coap_observee_t * -coap_obs_request_registration(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port, char *uri, - notification_callback_t notification_callback, - void *data) -{ - coap_packet_t request[1]; - coap_transaction_t *t; - uint8_t *token; - uint8_t token_len; - coap_observee_t *obs; - - obs = NULL; - coap_init_message(request, COAP_TYPE_CON, COAP_GET, coap_get_mid()); - coap_set_header_uri_path(request, uri); - coap_set_header_observe(request, 0); - token_len = coap_generate_token(&token); - set_token(request, token, token_len); - t = coap_new_transaction(request->mid, coap_ctx, addr, port); - if(t) { - uint8_t *ptr; - - if (coap_ctx->buf) { - ip_buf_unref(coap_ctx->buf); - } - - coap_ctx->buf = ip_buf_get_tx(coap_ctx->net_ctx); - if (!coap_ctx->buf) { - coap_clear_transaction(t); - return NULL; - } - - ptr = net_buf_add(coap_ctx->buf, 0); - ip_buf_appdata(coap_ctx->buf) = ptr; - - obs = coap_obs_add_observee(coap_ctx, addr, port, - (uint8_t *)token, token_len, uri, - notification_callback, data); - if(obs) { - t->callback = handle_obs_registration_response; - t->callback_data = obs; - t->packet_len = coap_serialize_message(request, uip_appdata(coap_ctx->buf)); - uip_len(coap_ctx->buf) = t->packet_len; - net_buf_add(coap_ctx->buf, uip_len(coap_ctx->buf)); - coap_send_transaction(t); - } else { - PRINTF("Could not allocate obs_subject resource buffer"); - coap_clear_transaction(t); - ip_buf_unref(coap_ctx->buf); - coap_ctx->buf = NULL; - } - } else { - PRINTF("%s: Could not allocate transaction buffer\n", __FUNCTION__); - } - return obs; -} -#endif /* COAP_OBSERVE_CLIENT */ diff --git a/net/ip/er-coap/er-coap-observe-client.h b/net/ip/er-coap/er-coap-observe-client.h deleted file mode 100644 index b507f0071859b024e8320d056d20c1599f0c79f1..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-observe-client.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2014, Daniele Alessandrelli. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/* - * \file - * Extension to Erbium for enabling CoAP observe clients - * \author - * Daniele Alessandrelli - */ - -#ifndef COAP_OBSERVING_CLIENT_H_ -#define COAP_OBSERVING_CLIENT_H_ - -#include "er-coap.h" -#include "er-coap-transactions.h" - -#ifndef COAP_OBSERVE_CLIENT -#define COAP_OBSERVE_CLIENT 0 -#endif - -#ifdef COAP_CONF_MAX_OBSERVEES -#define COAP_MAX_OBSERVEES COAP_CONF_MAX_OBSERVEES -#else -#define COAP_MAX_OBSERVEES 4 -#endif /* COAP_CONF_MAX_OBSERVEES */ - -#if COAP_MAX_OPEN_TRANSACTIONS < COAP_MAX_OBSERVEES -#warning "COAP_MAX_OPEN_TRANSACTIONS smaller than COAP_MAX_OBSERVEES: " \ - "this may be a problem" -#endif - -#define IS_RESPONSE_CODE_2_XX(message) (64 < message->code \ - && message->code < 128) - -/*----------------------------------------------------------------------------*/ -typedef enum { - OBSERVE_OK, - NOTIFICATION_OK, - OBSERVE_NOT_SUPPORTED, - ERROR_RESPONSE_CODE, - NO_REPLY_FROM_SERVER, -} coap_notification_flag_t; - -/*----------------------------------------------------------------------------*/ -typedef struct coap_observee_s coap_observee_t; - -typedef void (*notification_callback_t)(coap_observee_t *subject, - void *notification, - coap_notification_flag_t); - -struct coap_observee_s { - coap_observee_t *next; /* for LIST */ - coap_context_t *coap_ctx; - uip_ipaddr_t addr; - uint16_t port; - const char *url; - uint8_t token_len; - uint8_t token[COAP_TOKEN_LEN]; - void *data; /* generic pointer for storing user data */ - notification_callback_t notification_callback; - uint32_t last_observe; -}; - -/*----------------------------------------------------------------------------*/ -coap_observee_t *coap_obs_add_observee(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port, - const uint8_t *token, size_t token_len, - const char *url, - notification_callback_t - notification_callback, void *data); - -void coap_obs_remove_observee(coap_observee_t *o); - -coap_observee_t *coap_obs_get_observee_by_token(const uint8_t *token, - size_t token_len); - -int coap_obs_remove_observee_by_token(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port, - uint8_t *token, size_t token_len); - -int coap_obs_remove_observee_by_url(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port, - const char *url); - -void coap_handle_notification(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port, - coap_packet_t *notification); - -coap_observee_t *coap_obs_request_registration(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, - uint16_t port, char *uri, - notification_callback_t - notification_callback, - void *data); -/* TODO: this function may be moved to er-coap.c */ -uint8_t coap_generate_token(uint8_t **token_ptr); - -#endif /* COAP_OBSERVING_CLIENT_H_ */ diff --git a/net/ip/er-coap/er-coap-observe.c b/net/ip/er-coap/er-coap-observe.c deleted file mode 100644 index 9be96d72c6a50814312e83cad59b759103c25594..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-observe.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for observing resources (draft-ietf-core-observe-11). - * \author - * Matthias Kovatsch - */ - -#include -#include -#include "er-coap-observe.h" - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_COAP_OBSERVE -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -/*---------------------------------------------------------------------------*/ -MEMB(observers_memb, coap_observer_t, COAP_MAX_OBSERVERS); -LIST(observers_list); -/*---------------------------------------------------------------------------*/ -/*- Internal API ------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -static coap_observer_t * -coap_add_observer(coap_context_t *coap_ctx, uip_ipaddr_t *addr, uint16_t port, - const uint8_t *token, size_t token_len, - const char *uri, int uri_len) -{ - /* Remove existing observe relationship, if any. */ - coap_remove_observer_by_uri(addr, port, uri); - - coap_observer_t *o = memb_alloc(&observers_memb); - - if(o) { - /* o->url = uri; */ - int max = sizeof(o->url); - if(max > uri_len) { - max = uri_len; - } - memcpy(o->url, uri, max); - o->url[max] = 0; - uip_ipaddr_copy(&o->addr, addr); - o->port = port; - o->coap_ctx = coap_ctx; - o->token_len = token_len; - memcpy(o->token, token, token_len); - o->last_mid = 0; - - PRINTF("Adding observer (%u/%u) for /%s [0x%02X%02X]\n", - list_length(observers_list) + 1, COAP_MAX_OBSERVERS, - o->url, o->token[0], o->token[1]); - list_add(observers_list, o); - } - - return o; -} -/*---------------------------------------------------------------------------*/ -/*- Removal -----------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -void -coap_remove_observer(coap_observer_t *o) -{ - PRINTF("Removing observer for /%s [0x%02X%02X]\n", o->url, o->token[0], - o->token[1]); - - memb_free(&observers_memb, o); - list_remove(observers_list, o); -} -/*---------------------------------------------------------------------------*/ -int -coap_remove_observer_by_client(uip_ipaddr_t *addr, uint16_t port) -{ - int removed = 0; - coap_observer_t *obs = NULL; - - for(obs = (coap_observer_t *)list_head(observers_list); obs; - obs = obs->next) { - PRINTF("Remove check client "); - PRINT6ADDR(addr); - PRINTF(":%u\n", port); - if(uip_ipaddr_cmp(&obs->addr, addr) && obs->port == port) { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} -/*---------------------------------------------------------------------------*/ -int -coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port, - uint8_t *token, size_t token_len) -{ - int removed = 0; - coap_observer_t *obs = NULL; - - for(obs = (coap_observer_t *)list_head(observers_list); obs; - obs = obs->next) { - PRINTF("Remove check Token 0x%02X%02X\n", token[0], token[1]); - if(uip_ipaddr_cmp(&obs->addr, addr) && obs->port == port - && obs->token_len == token_len - && memcmp(obs->token, token, token_len) == 0) { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} -/*---------------------------------------------------------------------------*/ -int -coap_remove_observer_by_uri(const uip_ipaddr_t *addr, uint16_t port, - const char *uri) -{ - int removed = 0; - coap_observer_t *obs = NULL; - - for(obs = (coap_observer_t *)list_head(observers_list); obs; - obs = obs->next) { - PRINTF("Remove check URL %p\n", uri); - if((addr == NULL - || (uip_ipaddr_cmp(&obs->addr, addr) && obs->port == port)) - && (obs->url == uri || memcmp(obs->url, uri, strlen(obs->url)) == 0)) { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} -/*---------------------------------------------------------------------------*/ -int -coap_remove_observer_by_mid(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port, uint16_t mid) -{ - int removed = 0; - coap_observer_t *obs = NULL; - - for(obs = (coap_observer_t *)list_head(observers_list); obs; - obs = obs->next) { - PRINTF("Remove check MID %u\n", mid); - if(uip_ipaddr_cmp(&obs->addr, addr) && obs->port == port - && obs->coap_ctx == coap_ctx - && obs->last_mid == mid) { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} -/*---------------------------------------------------------------------------*/ -/*- Notification ------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -void -coap_notify_observers(resource_t *resource) -{ - coap_notify_observers_sub(resource, NULL); -} -void -coap_notify_observers_sub(resource_t *resource, char *subpath) -{ - /* build notification */ - coap_packet_t notification[1]; /* this way the packet can be treated as pointer as usual */ - coap_packet_t request[1]; /* this way the packet can be treated as pointer as usual */ - coap_observer_t *obs = NULL; - int url_len = 0; - char url[COAP_OBSERVER_URL_LEN]; - - url_len = strlen(resource->url); - strncpy(url, resource->url, COAP_OBSERVER_URL_LEN - 1); - if(strlen(url) < COAP_OBSERVER_URL_LEN && subpath != NULL) { - strncpy(&url[url_len], subpath, COAP_OBSERVER_URL_LEN - url_len - 1); - } - /* Ensure url is null terminated because strncpy does not guarantee this */ - url[COAP_OBSERVER_URL_LEN - 1] = '\0'; - /* url now contains the notify URL that needs to match the observer */ - PRINTF("Observe: Notification from %s\n", url); - - coap_init_message(notification, COAP_TYPE_NON, CONTENT_2_05, 0); - /* create a "fake" request for the URI */ - coap_init_message(request, COAP_TYPE_CON, COAP_GET, 0); - coap_set_header_uri_path(request, url); - - /* iterate over observers */ - for(obs = (coap_observer_t *)list_head(observers_list); obs; - obs = obs->next) { - url_len = strlen(obs->url); - - /* Do a match based on the parent/sub-resource match so that it is - possible to do parent-node observe */ - if((url_len == strlen(url) - || (url_len > strlen(url) - && (resource->flags & HAS_SUB_RESOURCES) - && obs->url[strlen(url)] == '/')) - && strncmp(url, obs->url, strlen(url)) == 0) { - coap_transaction_t *transaction = NULL; - - obs->coap_ctx->buf = ip_buf_get_tx(obs->coap_ctx->net_ctx); - if(!obs->coap_ctx->buf) { - PRINTF("Failed to get buffer, discard observe message\n"); - return; - } - uip_set_udp_conn(obs->coap_ctx->buf) = NULL; - uip_ipaddr_copy(&net_context_get_udp_connection(obs->coap_ctx->net_ctx)->remote_addr, &obs->addr); - net_context_get_udp_connection(obs->coap_ctx->net_ctx)->remote_port = uip_ntohs(obs->port); - - if((transaction = coap_new_transaction(coap_get_mid(), obs->coap_ctx, - &obs->addr, obs->port))) { - if(obs->obs_counter % COAP_OBSERVE_REFRESH_INTERVAL == 0) { - PRINTF(" Force Confirmable for\n"); - notification->type = COAP_TYPE_CON; - } - - PRINTF(" Observer "); - PRINT6ADDR(&obs->addr); - PRINTF(":%u\n", obs->port); - - /* update last MID for RST matching */ - obs->last_mid = transaction->mid; - - /* prepare response */ - notification->mid = transaction->mid; - - resource->get_handler(request, notification, - transaction->packet + COAP_MAX_HEADER_SIZE, - REST_MAX_CHUNK_SIZE, NULL); - - if(notification->code < BAD_REQUEST_4_00) { - coap_set_header_observe(notification, (obs->obs_counter)++); - } - coap_set_token(notification, obs->token, obs->token_len); - - transaction->packet_len = - coap_serialize_message(notification, uip_appdata(obs->coap_ctx->buf)); - - coap_send_transaction(transaction); - } - } - } -} -/*---------------------------------------------------------------------------*/ -void -coap_observe_handler(resource_t *resource, void *request, void *response) -{ - coap_packet_t *const coap_req = (coap_packet_t *)request; - coap_packet_t *const coap_res = (coap_packet_t *)response; - coap_context_t *coap_ctx = coap_get_context(request); - coap_observer_t * obs; - - /* static char content[16]; */ - - if(coap_req->code == COAP_GET && coap_res->code < 128) { /* GET request and response without error code */ - if(IS_OPTION(coap_req, COAP_OPTION_OBSERVE)) { - if(coap_req->observe == 0) { - obs = coap_add_observer(coap_ctx, - &UIP_IP_BUF(coap_ctx->buf)->srcipaddr, - UIP_UDP_BUF(coap_ctx->buf)->srcport, - coap_req->token, coap_req->token_len, - coap_req->uri_path, coap_req->uri_path_len); - if(obs) { - coap_set_header_observe(coap_res, (obs->obs_counter)++); - /* - * Following payload is for demonstration purposes only. - * A subscription should return the same representation as a normal GET. - * Uncomment if you want an information about the avaiable observers. - */ - /* - * coap_set_payload(coap_res, - * content, - * snprintf(content, sizeof(content), "Added %u/%u", - * list_length(observers_list), - * COAP_MAX_OBSERVERS)); - */ - } else { - coap_res->code = SERVICE_UNAVAILABLE_5_03; - coap_set_payload(coap_res, "TooManyObservers", 16); - } - } else if(coap_req->observe == 1) { - - /* remove client if it is currently observe */ - coap_remove_observer_by_token(&UIP_IP_BUF(coap_ctx->buf)->srcipaddr, - UIP_UDP_BUF(coap_ctx->buf)->srcport, coap_req->token, - coap_req->token_len); - } - } - } -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/er-coap/er-coap-observe.h b/net/ip/er-coap/er-coap-observe.h deleted file mode 100644 index c32a18576c292aafc7ddf83694872be552d2c90a..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-observe.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for observing resources (draft-ietf-core-observe-11). - * \author - * Matthias Kovatsch - */ - -#ifndef COAP_OBSERVE_H_ -#define COAP_OBSERVE_H_ - -#include "er-coap.h" -#include "er-coap-transactions.h" -#include - -#define COAP_OBSERVER_URL_LEN 20 - -typedef struct coap_observable { - uint32_t observe_clock; - struct stimer orphan_timer; - list_t observers; - coap_packet_t notification; - uint8_t buffer[COAP_MAX_PACKET_SIZE + 1]; -} coap_observable_t; - -typedef struct coap_observer { - struct coap_observer *next; /* for LIST */ - - char url[COAP_OBSERVER_URL_LEN]; - uip_ipaddr_t addr; - uint16_t port; - coap_context_t *coap_ctx; - uint8_t token_len; - uint8_t token[COAP_TOKEN_LEN]; - uint16_t last_mid; - - int32_t obs_counter; - - struct etimer retrans_timer; - uint8_t retrans_counter; -} coap_observer_t; - -list_t coap_get_observers(void); - -/* coap_observer_t *coap_add_observer(coap_context_t *coap_ctx, */ -/* uip_ipaddr_t *addr, uint16_t port, */ -/* const uint8_t *token, size_t token_len, */ -/* const char *url); */ - -void coap_remove_observer(coap_observer_t *o); -int coap_remove_observer_by_client(uip_ipaddr_t *addr, uint16_t port); -int coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port, - uint8_t *token, size_t token_len); -int coap_remove_observer_by_uri(const uip_ipaddr_t *addr, uint16_t port, - const char *uri); -int coap_remove_observer_by_mid(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port, - uint16_t mid); - -void coap_notify_observers(resource_t *resource); -void coap_notify_observers_sub(resource_t *resource, char *subpath); - -void coap_observe_handler(resource_t *resource, void *request, - void *response); - -#endif /* COAP_OBSERVE_H_ */ diff --git a/net/ip/er-coap/er-coap-res-well-known-core.c b/net/ip/er-coap/er-coap-res-well-known-core.c deleted file mode 100644 index 2b5f8781a9f83f7df29b4c636dec1b5a9cd82813..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-res-well-known-core.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * /.well-known/core resource implementation. - * \author - * Matthias Kovatsch - */ - -#include -#include "er-coap-engine.h" - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_COAP_WELL_KNOWN -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#define ADD_CHAR_IF_POSSIBLE(char) \ - if(strpos >= *offset && bufpos < preferred_size) { \ - buffer[bufpos++] = char; \ - } \ - ++strpos - -#define ADD_STRING_IF_POSSIBLE(string, op) \ - tmplen = strlen(string); \ - if(strpos + tmplen > *offset) { \ - bufpos += snprintf((char *)buffer + bufpos, \ - preferred_size - bufpos + 1, \ - "%s", \ - string \ - + (*offset - (int32_t)strpos > 0 ? \ - *offset - (int32_t)strpos : 0)); \ - if(bufpos op preferred_size) { \ - PRINTF("res: BREAK at %s (%p)\n", string, resource); \ - break; \ - } \ - } \ - strpos += tmplen - -/*---------------------------------------------------------------------------*/ -/*- Resource Handlers -------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -void -well_known_core_get_handler(void *request, void *response, uint8_t *buffer, - uint16_t preferred_size, int32_t *offset) -{ - size_t strpos = 0; /* position in overall string (which is larger than the buffer) */ - size_t bufpos = 0; /* position within buffer (bytes written) */ - size_t tmplen = 0; - resource_t *resource = NULL; - -#if COAP_LINK_FORMAT_FILTERING - /* For filtering. */ - const char *filter = NULL; - const char *attrib = NULL; - const char *found = NULL; - const char *end = NULL; - char *value = NULL; - char lastchar = '\0'; - int len = coap_get_header_uri_query(request, &filter); - - if(len) { - value = strchr(filter, '='); - value[0] = '\0'; - ++value; - len -= strlen(filter) + 1; - - PRINTF("Filter %s = %.*s\n", filter, len, value); - - if(strcmp(filter, "href") == 0 && value[0] == '/') { - ++value; - --len; - } - - lastchar = value[len - 1]; - value[len - 1] = '\0'; - } -#endif - - for(resource = (resource_t *)list_head(rest_get_resources()); resource; - resource = resource->next) { -#if COAP_LINK_FORMAT_FILTERING - /* Filtering */ - if(len) { - if(strcmp(filter, "href") == 0) { - attrib = strstr(resource->url, value); - if(attrib == NULL || (value[-1] == '/' && attrib != resource->url)) { - continue; - } - end = attrib + strlen(attrib); - } else if(resource->attributes != NULL) { - attrib = strstr(resource->attributes, filter); - if(attrib == NULL - || (attrib[strlen(filter)] != '=' - && attrib[strlen(filter)] != '"')) { - continue; - } - attrib += strlen(filter) + 2; - end = strchr(attrib, '"'); - } - - PRINTF("Filter: res has attrib %s (%s)\n", attrib, value); - found = attrib; - while((found = strstr(found, value)) != NULL) { - if(found > end) { - found = NULL; - break; - } - if(lastchar == found[len - 1] || lastchar == '*') { - break; - } - ++found; - } - if(found == NULL) { - continue; - } - PRINTF("Filter: res has prefix %s\n", found); - if(lastchar != '*' - && (found[len] != '"' && found[len] != ' ' && found[len] != '\0')) { - continue; - } - PRINTF("Filter: res has match\n"); - } -#endif - - PRINTF("res: /%s (%p)\npos: s%zu, o%ld, b%zu\n", resource->url, resource, - strpos, (unsigned long) *offset, bufpos); - - if(strpos > 0) { - ADD_CHAR_IF_POSSIBLE(','); - } - ADD_CHAR_IF_POSSIBLE('<'); - ADD_CHAR_IF_POSSIBLE('/'); - ADD_STRING_IF_POSSIBLE(resource->url, >=); - ADD_CHAR_IF_POSSIBLE('>'); - - if(resource->attributes != NULL && resource->attributes[0]) { - ADD_CHAR_IF_POSSIBLE(';'); - ADD_STRING_IF_POSSIBLE(resource->attributes, >); - } - - /* buffer full, but resource not completed yet; or: do not break if resource exactly fills buffer. */ - if(bufpos > preferred_size && strpos - bufpos > *offset) { - PRINTF("res: BREAK at %s (%p)\n", resource->url, resource); - break; - } - } - - if(bufpos > 0) { - PRINTF("BUF %zu: %.*s\n", bufpos, (int)bufpos, (char *)buffer); - - coap_set_payload(response, buffer, bufpos); - coap_set_header_content_format(response, APPLICATION_LINK_FORMAT); - } else if(strpos > 0) { - PRINTF("well_known_core_handler(): bufpos<=0\n"); - - coap_set_status_code(response, BAD_OPTION_4_02); - coap_set_payload(response, "BlockOutOfScope", 15); - } - - if(resource == NULL) { - PRINTF("res: DONE\n"); - *offset = -1; - } else { - PRINTF("res: MORE at %s (%p)\n", resource->url, resource); - *offset += preferred_size; - } -} -/*---------------------------------------------------------------------------*/ -RESOURCE(res_well_known_core, "ct=40", well_known_core_get_handler, NULL, - NULL, NULL); -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/er-coap/er-coap-separate.c b/net/ip/er-coap/er-coap-separate.c deleted file mode 100644 index e8f145b07c962975cee42c5518605ec954e5c922..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-separate.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for separate responses. - * \author - * Matthias Kovatsch - */ - -#include "sys/cc.h" -#include -#include -#include "er-coap-separate.h" -#include "er-coap-transactions.h" - -#define DEBUG DEBUG_NONE -#include "contiki/ip/uip-debug.h" - -/*---------------------------------------------------------------------------*/ -/*- Separate Response API ---------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -/** - * \brief Reject a request that would require a separate response with an error message - * - * When the server does not have enough resources left to store the information - * for a separate response or otherwise cannot execute the resource handler, - * this function will respond with 5.03 Service Unavailable. The client can - * then retry later. - */ -void -coap_separate_reject() -{ - /* TODO: Accept string pointer for custom error message */ - erbium_status_code = SERVICE_UNAVAILABLE_5_03; - coap_error_message = "AlreadyInUse"; -} -/*----------------------------------------------------------------------------*/ -/** - * \brief Initiate a separate response with an empty ACK - * \param request The request to accept - * \param separate_store A pointer to the data structure that will store the - * relevant information for the response - * - * When the server does not have enough resources left to store the information - * for a separate response or otherwise cannot execute the resource handler, - * this function will respond with 5.03 Service Unavailable. The client can - * then retry later. - */ -void -coap_separate_accept(void *request, coap_separate_t *separate_store) -{ - coap_packet_t *const coap_req = (coap_packet_t *)request; - coap_transaction_t *const t = coap_get_transaction_by_mid(coap_req->mid); - coap_context_t *coap_ctx = coap_get_context(request); - - PRINTF("Separate ACCEPT: /%.*s MID %u\n", coap_req->uri_path_len, - coap_req->uri_path, coap_req->mid); - if(t) { - /* send separate ACK for CON */ - if(coap_req->type == COAP_TYPE_CON) { - coap_packet_t ack[1]; - - /* ACK with empty code (0) */ - coap_init_message(ack, COAP_TYPE_ACK, 0, coap_req->mid); - /* serializing into IPBUF: Only overwrites header parts that are already parsed into the request struct */ - coap_send_message(coap_ctx, &UIP_IP_BUF(coap_ctx->buf)->srcipaddr, - UIP_UDP_BUF(coap_ctx->buf)->srcport, - uip_appdata(coap_ctx->buf), - coap_serialize_message(ack, uip_appdata(coap_ctx->buf))); - } - - /* store remote address */ - uip_ipaddr_copy(&separate_store->addr, &t->addr); - separate_store->port = t->port; - - /* store correct response type */ - separate_store->type = - coap_req->type == COAP_TYPE_CON ? COAP_TYPE_CON : COAP_TYPE_NON; - separate_store->mid = coap_get_mid(); /* if it was a NON, we burned one MID in the engine... */ - - memcpy(separate_store->token, coap_req->token, coap_req->token_len); - separate_store->token_len = coap_req->token_len; - - separate_store->block1_num = coap_req->block1_num; - separate_store->block1_size = coap_req->block1_size; - - separate_store->block2_num = coap_req->block2_num; - separate_store->block2_size = coap_req->block2_size > 0 ? MIN(COAP_MAX_BLOCK_SIZE, coap_req->block2_size) : COAP_MAX_BLOCK_SIZE; - - /* signal the engine to skip automatic response and clear transaction by engine */ - erbium_status_code = MANUAL_RESPONSE; - } else { - PRINTF("ERROR: Response transaction for separate request not found!\n"); - erbium_status_code = INTERNAL_SERVER_ERROR_5_00; - } -} -/*----------------------------------------------------------------------------*/ -void -coap_separate_resume(void *response, coap_separate_t *separate_store, - uint8_t code) -{ - coap_init_message(response, separate_store->type, code, - separate_store->mid); - if(separate_store->token_len) { - coap_set_token(response, separate_store->token, - separate_store->token_len); - } - if(separate_store->block1_size) { - coap_set_header_block1(response, separate_store->block1_num, - 0, separate_store->block1_size); - } -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/er-coap/er-coap-separate.h b/net/ip/er-coap/er-coap-separate.h deleted file mode 100644 index dbecf1b393192d0ea4a254174eb36a5638222baf..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-separate.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for separate responses. - * \author - * Matthias Kovatsch - */ - -#ifndef COAP_SEPARATE_H_ -#define COAP_SEPARATE_H_ - -#include "er-coap.h" - -typedef struct coap_separate { - - uip_ipaddr_t addr; - uint16_t port; - - coap_message_type_t type; - uint16_t mid; - - uint8_t token_len; - uint8_t token[COAP_TOKEN_LEN]; - - uint32_t block1_num; - uint16_t block1_size; - - uint32_t block2_num; - uint16_t block2_size; -} coap_separate_t; - -int coap_separate_handler(resource_t *resource, void *request, - void *response); -void coap_separate_reject(); -void coap_separate_accept(void *request, coap_separate_t *separate_store); -void coap_separate_resume(void *response, coap_separate_t *separate_store, - uint8_t code); - -#endif /* COAP_SEPARATE_H_ */ diff --git a/net/ip/er-coap/er-coap-transactions.c b/net/ip/er-coap/er-coap-transactions.c deleted file mode 100644 index 10083a8aa095aecd2a25009f46be8852925de234..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-transactions.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for reliable transport - * \author - * Matthias Kovatsch - */ - -#include "contiki.h" -#include "contiki-net.h" -#include "er-coap-transactions.h" -#include "er-coap-observe.h" - -#if CONFIG_NETWORK_IP_STACK_DEBUG_COAP_TRANSACTION -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -/*---------------------------------------------------------------------------*/ -MEMB(transactions_memb, coap_transaction_t, COAP_MAX_OPEN_TRANSACTIONS); -LIST(transactions_list); - -static struct process *transaction_handler_process = NULL; - -/*---------------------------------------------------------------------------*/ -/*- Internal API ------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -void -coap_register_as_transaction_handler() -{ - transaction_handler_process = PROCESS_CURRENT(); -} -coap_transaction_t * -coap_new_transaction(uint16_t mid, coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port) -{ - coap_transaction_t *t = memb_alloc(&transactions_memb); - - if(t) { - t->mid = mid; - t->retrans_counter = 0; - - /* save client address */ - uip_ipaddr_copy(&t->addr, addr); - t->port = port; - t->coap_ctx = coap_ctx; - - list_add(transactions_list, t); /* list itself makes sure same element is not added twice */ - } - - return t; -} -/*---------------------------------------------------------------------------*/ -void -coap_send_transaction(coap_transaction_t *t) -{ - PRINTF("Sending transaction %u appdata %p len %d (%d)\n", - t->mid, - ip_buf_appdata(t->coap_ctx->buf), - ip_buf_appdatalen(t->coap_ctx->buf), - t->packet_len); - - if (!t->coap_ctx || !t->coap_ctx->buf) { - PRINTF("***ERROR*** ctx %p buf %p\n", t->coap_ctx, t->coap_ctx->buf); - coap_clear_transaction(t); - return; - } - - NET_COAP_STAT(sent++); - - coap_send_message(t->coap_ctx, &t->addr, t->port, - t->packet, t->packet_len); - - if(COAP_TYPE_CON == - ((COAP_HEADER_TYPE_MASK & t->packet[0]) >> COAP_HEADER_TYPE_POSITION)) { - if(t->retrans_counter < COAP_MAX_RETRANSMIT) { - /* not timed out yet */ - PRINTF("Keeping transaction %u\n", t->mid); - - if(t->retrans_counter == 0) { - t->retrans_timer.timer.interval = - COAP_RESPONSE_TIMEOUT_TICKS + (random_rand() - % - (clock_time_t) - COAP_RESPONSE_TIMEOUT_BACKOFF_MASK); - PRINTF("Initial interval %d\n", - t->retrans_timer.timer.interval / CLOCK_SECOND); - } else { - t->retrans_timer.timer.interval <<= 1; /* double */ - PRINTF("Doubled (%u) interval %d\n", t->retrans_counter, - t->retrans_timer.timer.interval / CLOCK_SECOND); - } - - PROCESS_CONTEXT_BEGIN(transaction_handler_process); - etimer_restart(&t->retrans_timer); /* interval updated above */ - PROCESS_CONTEXT_END(transaction_handler_process); - - t = NULL; - } else { - /* timed out */ - PRINTF("Timeout\n"); - restful_response_handler callback = t->callback; - void *callback_data = t->callback_data; - - /* handle observers */ - coap_remove_observer_by_client(&t->addr, t->port); - - coap_clear_transaction(t); - - if(callback) { - callback(callback_data, NULL); - } - } - } else { - coap_clear_transaction(t); - } -} -/*---------------------------------------------------------------------------*/ -void -coap_clear_transaction(coap_transaction_t *t) -{ - if(t) { - PRINTF("Freeing transaction %u: %p\n", t->mid, t); - - etimer_stop(&t->retrans_timer); - list_remove(transactions_list, t); - memb_free(&transactions_memb, t); - } -} -coap_transaction_t * -coap_get_transaction_by_mid(uint16_t mid) -{ - coap_transaction_t *t = NULL; - - for(t = (coap_transaction_t *)list_head(transactions_list); t; t = t->next) { - if(t->mid == mid) { - PRINTF("Found transaction for MID %u: %p\n", t->mid, t); - return t; - } - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -static inline struct net_buf *get_retransmit_buf(coap_transaction_t *t) -{ - coap_context_t *coap_ctx = t->coap_ctx; - - if (coap_ctx->buf) { - return coap_ctx->buf; - } - - coap_ctx->buf = ip_buf_get_tx(coap_ctx->net_ctx); - if (!coap_ctx->buf) { - return NULL; - } - - /* We set the major buf params correctly. The application data pointer - * should point to start of the coap packet data. - * The tail of the packet points now to byte after coap packet. - */ - ip_buf_appdata(coap_ctx->buf) = net_buf_add(coap_ctx->buf, t->packet_len); - ip_buf_appdatalen(coap_ctx->buf) = t->packet_len; - - /* The total length of the packet is the coap packet + all the UDP/IP - * headers. - */ - uip_len(coap_ctx->buf) = ip_buf_len(coap_ctx->buf); - - return coap_ctx->buf; -} - -void -coap_check_transactions() -{ - coap_transaction_t *t = NULL; - - for(t = (coap_transaction_t *)list_head(transactions_list); t; t = t->next) { - if(etimer_expired(&t->retrans_timer)) { - ++(t->retrans_counter); - PRINTF("Retransmitting %u (%u)\n", t->mid, t->retrans_counter); - if (get_retransmit_buf(t)) { - coap_send_transaction(t); - NET_COAP_STAT(re_sent++); - } - } - } -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/er-coap/er-coap-transactions.h b/net/ip/er-coap/er-coap-transactions.h deleted file mode 100644 index a0f631fcda04fe26c7a7d08fc55d82dbce2b6396..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap-transactions.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for reliable transport - * \author - * Matthias Kovatsch - */ - -#ifndef COAP_TRANSACTIONS_H_ -#define COAP_TRANSACTIONS_H_ - -#include "er-coap.h" - -/* - * Modulo mask (thus +1) for a random number to get the tick number for the random - * retransmission time between COAP_RESPONSE_TIMEOUT and COAP_RESPONSE_TIMEOUT*COAP_RESPONSE_RANDOM_FACTOR. - */ -#define COAP_RESPONSE_TIMEOUT_TICKS (CLOCK_SECOND * COAP_RESPONSE_TIMEOUT) -//#define COAP_RESPONSE_TIMEOUT_BACKOFF_MASK (long)((CLOCK_SECOND * COAP_RESPONSE_TIMEOUT * ((float)COAP_RESPONSE_RANDOM_FACTOR - 1.0)) + 0.5) + 1 -/* Convert to use integer arithmetics */ -#define COAP_RESPONSE_TIMEOUT_BACKOFF_MASK \ - (long)((CLOCK_SECOND * COAP_RESPONSE_TIMEOUT * \ - (COAP_RESPONSE_RANDOM_FACTOR_INT - 10)) + 5) / 10 + 1 - -/* container for transactions with message buffer and retransmission info */ -typedef struct coap_transaction { - struct coap_transaction *next; /* for LIST */ - - uint16_t mid; - struct etimer retrans_timer; - uint8_t retrans_counter; - - uip_ipaddr_t addr; - uint16_t port; - coap_context_t *coap_ctx; - - restful_response_handler callback; - void *callback_data; - - uint16_t packet_len; - uint8_t packet[COAP_MAX_PACKET_SIZE + 1]; /* +1 for the terminating '\0' which will not be sent - * Use snprintf(buf, len+1, "", ...) to completely fill payload */ -} coap_transaction_t; - -void coap_register_as_transaction_handler(); - -coap_transaction_t *coap_new_transaction(uint16_t mid, coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port); -void coap_send_transaction(coap_transaction_t *t); -void coap_clear_transaction(coap_transaction_t *t); -coap_transaction_t *coap_get_transaction_by_mid(uint16_t mid); - -void coap_check_transactions(); - -#endif /* COAP_TRANSACTIONS_H_ */ diff --git a/net/ip/er-coap/er-coap.c b/net/ip/er-coap/er-coap.c deleted file mode 100644 index aead0dd86dc4deabfcbe006fa818ca05e70a3784..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap.c +++ /dev/null @@ -1,1273 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * An implementation of the Constrained Application Protocol (RFC). - * \author - * Matthias Kovatsch - */ - -#include -#include -#include "contiki.h" -#include "sys/cc.h" -#include "contiki-net.h" - -#include "er-coap.h" -#include "er-coap-transactions.h" - -#if CONFIG_NETWORK_IP_STACK_DEBUG_COAP_INTERNAL -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -/*---------------------------------------------------------------------------*/ -/*- Variables ---------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -//static struct uip_udp_conn *udp_conn = NULL; -static uint16_t current_mid = 0; - -coap_status_t erbium_status_code = NO_ERROR; -char *coap_error_message = ""; -/*---------------------------------------------------------------------------*/ -/*- Local helper functions --------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -static uint16_t -coap_log_2(uint16_t value) -{ - uint16_t result = 0; - - do { - value = value >> 1; - result++; - } while(value); - - return result ? result - 1 : result; -} -/*---------------------------------------------------------------------------*/ -static uint32_t -coap_parse_int_option(uint8_t *bytes, size_t length) -{ - uint32_t var = 0; - int i = 0; - - while(i < length) { - var <<= 8; - var |= bytes[i++]; - } - return var; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -coap_option_nibble(unsigned int value) -{ - if(value < 13) { - return value; - } else if(value <= 0xFF + 13) { - return 13; - } else { - return 14; - } -} -/*---------------------------------------------------------------------------*/ -static size_t -coap_set_option_header(unsigned int delta, size_t length, uint8_t *buffer) -{ - size_t written = 0; - - buffer[0] = coap_option_nibble(delta) << 4 | coap_option_nibble(length); - - if(delta > 268) { - buffer[++written] = ((delta - 269) >> 8) & 0xff; - buffer[++written] = (delta - 269) & 0xff; - } else if(delta > 12) { - buffer[++written] = (delta - 13); - } - - if(length > 268) { - buffer[++written] = ((length - 269) >> 8) & 0xff; - buffer[++written] = (length - 269) & 0xff; - } else if(length > 12) { - buffer[++written] = (length - 13); - } - - PRINTF("WRITTEN %u B opt header\n", (unsigned int) (1 + written)); - - return ++written; -} -/*---------------------------------------------------------------------------*/ -static size_t -coap_serialize_int_option(unsigned int number, unsigned int current_number, - uint8_t *buffer, uint32_t value) -{ - size_t i = 0; - - if(0xFF000000 & value) { - ++i; - } - if(0xFFFF0000 & value) { - ++i; - } - if(0xFFFFFF00 & value) { - ++i; - } - if(0xFFFFFFFF & value) { - ++i; - } - PRINTF("OPTION %u (delta %u, len %u)\n", number, number - current_number, - (unsigned int) i); - - i = coap_set_option_header(number - current_number, i, buffer); - - if(0xFF000000 & value) { - buffer[i++] = (uint8_t)(value >> 24); - } - if(0xFFFF0000 & value) { - buffer[i++] = (uint8_t)(value >> 16); - } - if(0xFFFFFF00 & value) { - buffer[i++] = (uint8_t)(value >> 8); - } - if(0xFFFFFFFF & value) { - buffer[i++] = (uint8_t)(value); - } - return i; -} -/*---------------------------------------------------------------------------*/ -static size_t -coap_serialize_array_option(unsigned int number, unsigned int current_number, - uint8_t *buffer, uint8_t *array, size_t length, - char split_char) -{ - size_t i = 0; - - PRINTF("ARRAY type %u, len %u, full [%.*s]\n", number, (unsigned int) length, - (int) length, array); - - if(split_char != '\0') { - int j; - uint8_t *part_start = array; - uint8_t *part_end = NULL; - size_t temp_length; - - for(j = 0; j <= length + 1; ++j) { - PRINTF("STEP %u/%u (%c)\n", j, (unsigned int) length, array[j]); - if(array[j] == split_char || j == length) { - part_end = array + j; - temp_length = part_end - part_start; - - i += coap_set_option_header(number - current_number, temp_length, - &buffer[i]); - memcpy(&buffer[i], part_start, temp_length); - i += temp_length; - - PRINTF("OPTION type %u, delta %u, len %u, part [%.*s]\n", number, - number - current_number, (unsigned int) i, - (unsigned int) temp_length, part_start); - - ++j; /* skip the splitter */ - current_number = number; - part_start = array + j; - } - } /* for */ - } else { - i += coap_set_option_header(number - current_number, length, &buffer[i]); - memcpy(&buffer[i], array, length); - i += length; - - PRINTF("OPTION type %u, delta %u, len %u\n", number, - number - current_number, (unsigned int) length); - } - - return i; -} -/*---------------------------------------------------------------------------*/ -static void -coap_merge_multi_option(char **dst, size_t *dst_len, uint8_t *option, - size_t option_len, char separator) -{ - /* merge multiple options */ - if(*dst_len > 0) { - /* dst already contains an option: concatenate */ - (*dst)[*dst_len] = separator; - *dst_len += 1; - - /* memmove handles 2-byte option headers */ - memmove((*dst) + (*dst_len), option, option_len); - - *dst_len += option_len; - } else { - /* dst is empty: set to option */ - *dst = (char *)option; - *dst_len = option_len; - } -} -/*---------------------------------------------------------------------------*/ -static int -coap_get_variable(const char *buffer, size_t length, const char *name, - const char **output) -{ - const char *start = NULL; - const char *end = NULL; - const char *value_end = NULL; - size_t name_len = 0; - - /*initialize the output buffer first */ - *output = 0; - - name_len = strlen(name); - end = buffer + length; - - for(start = buffer; start + name_len < end; ++start) { - if((start == buffer || start[-1] == '&') && start[name_len] == '=' - && strncmp(name, start, name_len) == 0) { - - /* Point start to variable value */ - start += name_len + 1; - - /* Point end to the end of the value */ - value_end = (const char *)memchr(start, '&', end - start); - if(value_end == NULL) { - value_end = end; - } - *output = start; - - return value_end - start; - } - } - return 0; -} -/*---------------------------------------------------------------------------*/ -/*- Internal API ------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -void coap_init_mid(void) -{ - /* initialize transaction ID */ - current_mid = random_rand(); -} - -coap_context_t * -coap_init_connection(uip_ipaddr_t *server_addr, uint16_t server_port, - uip_ipaddr_t *peer_addr, uint16_t peer_port) -{ - coap_context_t *coap_ctx; - - if (!server_addr) { - PRINTF("%s: local endpoint is missing\n", __func__); - return NULL; - } - -#if defined(CONFIG_NETWORKING_WITH_IPV6) - { - const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; - - if (!memcmp(server_addr, &in6addr_any, sizeof(in6addr_any))) { - uip_ds6_addr_t *uip_addr; - - uip_addr = uip_ds6_get_global(-1); - if (!uip_addr) { - uip_addr = uip_ds6_get_link_local(-1); - } - if (!uip_addr) { - return NULL; - } - memcpy(server_addr, uip_addr, sizeof(*server_addr)); - } - } -#endif - - coap_ctx = coap_context_new(server_addr, server_port); - if (!coap_context_listen(coap_ctx, peer_addr, peer_port)) { - return NULL; - } - - coap_init_mid(); - - return coap_ctx; -} -/*---------------------------------------------------------------------------*/ -uint16_t -coap_get_mid() -{ - return ++current_mid; -} -/*---------------------------------------------------------------------------*/ -void -coap_init_message(void *packet, coap_message_type_t type, uint8_t code, - uint16_t mid) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - /* Important thing */ - memset(coap_pkt, 0, sizeof(coap_packet_t)); - - coap_pkt->type = type; - coap_pkt->code = code; - coap_pkt->mid = mid; -} -/*---------------------------------------------------------------------------*/ -size_t -coap_serialize_message(void *packet, uint8_t *buffer) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - uint8_t *option; - unsigned int current_number = 0; - - /* Initialize */ - coap_pkt->buffer = buffer; - coap_pkt->version = 1; - - PRINTF("-Serializing MID %u to %p, ", coap_pkt->mid, coap_pkt->buffer); - - /* set header fields */ - coap_pkt->buffer[0] = 0x00; - coap_pkt->buffer[0] |= COAP_HEADER_VERSION_MASK - & (coap_pkt->version) << COAP_HEADER_VERSION_POSITION; - coap_pkt->buffer[0] |= COAP_HEADER_TYPE_MASK - & (coap_pkt->type) << COAP_HEADER_TYPE_POSITION; - coap_pkt->buffer[0] |= COAP_HEADER_TOKEN_LEN_MASK - & (coap_pkt->token_len) << COAP_HEADER_TOKEN_LEN_POSITION; - coap_pkt->buffer[1] = coap_pkt->code; - coap_pkt->buffer[2] = (uint8_t)((coap_pkt->mid) >> 8); - coap_pkt->buffer[3] = (uint8_t)(coap_pkt->mid); - - /* empty packet, dont need to do more stuff */ - if(!coap_pkt->code) { - PRINTF("-Done serializing empty message at %p-\n", coap_pkt->buffer); - return 4; - } - - /* set Token */ - PRINTF("Token (len %u)", coap_pkt->token_len); - option = coap_pkt->buffer + COAP_HEADER_LEN; - for(current_number = 0; current_number < coap_pkt->token_len; - ++current_number) { - PRINTF(" %02X", coap_pkt->token[current_number]); - *option = coap_pkt->token[current_number]; - ++option; - } - PRINTF("-\n"); - - /* Serialize options */ - current_number = 0; - - PRINTF("-Serializing options at %p-\n", option); - - /* The options must be serialized in the order of their number */ - COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_IF_MATCH, if_match, "If-Match"); - COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_HOST, uri_host, '\0', - "Uri-Host"); - COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_ETAG, etag, "ETag"); - COAP_SERIALIZE_INT_OPTION(COAP_OPTION_IF_NONE_MATCH, - content_format - - coap_pkt-> - content_format /* hack to get a zero field */, - "If-None-Match"); - COAP_SERIALIZE_INT_OPTION(COAP_OPTION_OBSERVE, observe, "Observe"); - COAP_SERIALIZE_INT_OPTION(COAP_OPTION_URI_PORT, uri_port, "Uri-Port"); - COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_PATH, location_path, '/', - "Location-Path"); - COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_PATH, uri_path, '/', - "Uri-Path"); - PRINTF("Serialize content format: %d\n", coap_pkt->content_format); - COAP_SERIALIZE_INT_OPTION(COAP_OPTION_CONTENT_FORMAT, content_format, - "Content-Format"); - COAP_SERIALIZE_INT_OPTION(COAP_OPTION_MAX_AGE, max_age, "Max-Age"); - COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_QUERY, uri_query, '&', - "Uri-Query"); - COAP_SERIALIZE_INT_OPTION(COAP_OPTION_ACCEPT, accept, "Accept"); - COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_QUERY, location_query, - '&', "Location-Query"); - COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK2, block2, "Block2"); - COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK1, block1, "Block1"); - COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE2, size2, "Size2"); - COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_URI, proxy_uri, '\0', - "Proxy-Uri"); - COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_SCHEME, proxy_scheme, '\0', - "Proxy-Scheme"); - COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE1, size1, "Size1"); - - PRINTF("-Done serializing at %p----\n", option); - - /* Pack payload */ - if((option - coap_pkt->buffer) <= COAP_MAX_HEADER_SIZE) { - /* Payload marker */ - if(coap_pkt->payload_len) { - *option = 0xFF; - ++option; - } - if (!coap_pkt->payload) { - if (coap_pkt->payload_len > 0) { - coap_error_message = "Cannot serialize as payload is NULL"; - PRINTF("ERROR: %s but payload len is %d\n", coap_error_message, - coap_pkt->payload_len); - goto error; - } - } else { - memmove(option, coap_pkt->payload, coap_pkt->payload_len); - } - } else { - /* an error occurred: caller must check for !=0 */ - coap_error_message = "Serialized header exceeds COAP_MAX_HEADER_SIZE"; - error: - coap_pkt->buffer = NULL; - return 0; - } - - PRINTF("-Done %u B (header len %u, payload len %u)-\n", - (unsigned int) (coap_pkt->payload_len + option - buffer), - (unsigned int) (option - buffer), - (unsigned int) coap_pkt->payload_len); - - PRINTF("Dump [0x%02X %02X %02X %02X %02X %02X %02X %02X]\n", - coap_pkt->buffer[0], - coap_pkt->buffer[1], - coap_pkt->buffer[2], - coap_pkt->buffer[3], - coap_pkt->buffer[4], - coap_pkt->buffer[5], coap_pkt->buffer[6], coap_pkt->buffer[7] - ); - - return (option - buffer) + coap_pkt->payload_len; /* packet length */ -} -/*---------------------------------------------------------------------------*/ -void -coap_send_message(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port, - const uint8_t *data, uint16_t length) -{ - if(coap_ctx != COAP_CONTEXT_NONE) { - coap_context_send_message(coap_ctx, addr, port, data, length); - return; - } - - /* configure connection to reply to client */ - uip_ipaddr_copy(&uip_udp_conn(coap_ctx->buf)->ripaddr, addr); - uip_udp_conn(coap_ctx->buf)->rport = port; - - uip_udp_packet_send(coap_ctx->buf, uip_udp_conn(coap_ctx->buf), data, length); - - PRINTF("-sent UDP datagram (%u)-\n", length); - - /* restore server socket to allow data from any node */ - memset(&uip_udp_conn(coap_ctx->buf)->ripaddr, 0, - sizeof(uip_udp_conn(coap_ctx->buf)->ripaddr)); - uip_udp_conn(coap_ctx->buf)->rport = 0; -} -/*---------------------------------------------------------------------------*/ -coap_status_t -coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - /* initialize packet */ - memset(coap_pkt, 0, sizeof(coap_packet_t)); - - /* pointer to packet bytes */ - coap_pkt->buffer = data; - - /* parse header fields */ - coap_pkt->version = (COAP_HEADER_VERSION_MASK & coap_pkt->buffer[0]) - >> COAP_HEADER_VERSION_POSITION; - coap_pkt->type = (COAP_HEADER_TYPE_MASK & coap_pkt->buffer[0]) - >> COAP_HEADER_TYPE_POSITION; - coap_pkt->token_len = - MIN(COAP_TOKEN_LEN, - (COAP_HEADER_TOKEN_LEN_MASK & coap_pkt-> - buffer[0]) >> COAP_HEADER_TOKEN_LEN_POSITION); - coap_pkt->code = coap_pkt->buffer[1]; - coap_pkt->mid = coap_pkt->buffer[2] << 8 | coap_pkt->buffer[3]; - - if(coap_pkt->version != 1) { - coap_error_message = "CoAP version must be 1"; - return BAD_REQUEST_4_00; - } - - uint8_t *current_option = data + COAP_HEADER_LEN; - - memcpy(coap_pkt->token, current_option, coap_pkt->token_len); - PRINTF("Token (len %u) [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", - coap_pkt->token_len, coap_pkt->token[0], coap_pkt->token[1], - coap_pkt->token[2], coap_pkt->token[3], coap_pkt->token[4], - coap_pkt->token[5], coap_pkt->token[6], coap_pkt->token[7] - ); /*FIXME always prints 8 bytes */ - - /* parse options */ - memset(coap_pkt->options, 0, sizeof(coap_pkt->options)); - current_option += coap_pkt->token_len; - - unsigned int option_number = 0; - unsigned int option_delta = 0; - unsigned int option_length = 0; - - while(current_option < data + data_len) { - /* payload marker 0xFF, currently only checking for 0xF* because rest is reserved */ - if((current_option[0] & 0xF0) == 0xF0) { - coap_pkt->payload = ++current_option; - coap_pkt->payload_len = data_len - (coap_pkt->payload - data); - - /* also for receiving, the Erbium upper bound is REST_MAX_CHUNK_SIZE */ - if(coap_pkt->payload_len > REST_MAX_CHUNK_SIZE) { - coap_pkt->payload_len = REST_MAX_CHUNK_SIZE; - /* null-terminate payload */ - } - coap_pkt->payload[coap_pkt->payload_len] = '\0'; - - break; - } - - option_delta = current_option[0] >> 4; - option_length = current_option[0] & 0x0F; - ++current_option; - - if(option_delta == 13) { - option_delta += current_option[0]; - ++current_option; - } else if(option_delta == 14) { - option_delta += 255; - option_delta += current_option[0] << 8; - ++current_option; - option_delta += current_option[0]; - ++current_option; - } - - if(option_length == 13) { - option_length += current_option[0]; - ++current_option; - } else if(option_length == 14) { - option_length += 255; - option_length += current_option[0] << 8; - ++current_option; - option_length += current_option[0]; - ++current_option; - } - - option_number += option_delta; - - PRINTF("OPTION %u (delta %u, len %u): ", option_number, option_delta, - option_length); - - SET_OPTION(coap_pkt, option_number); - - switch(option_number) { - case COAP_OPTION_CONTENT_FORMAT: - coap_pkt->content_format = coap_parse_int_option(current_option, - option_length); - PRINTF("Content-Format [%u]\n", coap_pkt->content_format); - break; - case COAP_OPTION_MAX_AGE: - coap_pkt->max_age = coap_parse_int_option(current_option, - option_length); - PRINTF("Max-Age [%lu]\n", (long unsigned int) coap_pkt->max_age); - break; - case COAP_OPTION_ETAG: - coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_length); - memcpy(coap_pkt->etag, current_option, coap_pkt->etag_len); - PRINTF("ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", - coap_pkt->etag_len, coap_pkt->etag[0], coap_pkt->etag[1], - coap_pkt->etag[2], coap_pkt->etag[3], coap_pkt->etag[4], - coap_pkt->etag[5], coap_pkt->etag[6], coap_pkt->etag[7] - ); /*FIXME always prints 8 bytes */ - break; - case COAP_OPTION_ACCEPT: - coap_pkt->accept = coap_parse_int_option(current_option, option_length); - PRINTF("Accept [%u]\n", coap_pkt->accept); - break; - case COAP_OPTION_IF_MATCH: - /* TODO support multiple ETags */ - coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, option_length); - memcpy(coap_pkt->if_match, current_option, coap_pkt->if_match_len); - PRINTF("If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", - coap_pkt->if_match_len, coap_pkt->if_match[0], - coap_pkt->if_match[1], coap_pkt->if_match[2], - coap_pkt->if_match[3], coap_pkt->if_match[4], - coap_pkt->if_match[5], coap_pkt->if_match[6], - coap_pkt->if_match[7] - ); /* FIXME always prints 8 bytes */ - break; - case COAP_OPTION_IF_NONE_MATCH: - coap_pkt->if_none_match = 1; - PRINTF("If-None-Match\n"); - break; - - case COAP_OPTION_PROXY_URI: -#if COAP_PROXY_OPTION_PROCESSING - coap_pkt->proxy_uri = (char *)current_option; - coap_pkt->proxy_uri_len = option_length; -#endif - PRINTF("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", (int)coap_pkt->proxy_uri_len, - coap_pkt->proxy_uri); - coap_error_message = "This is a constrained server (Contiki)"; - return PROXYING_NOT_SUPPORTED_5_05; - break; - case COAP_OPTION_PROXY_SCHEME: -#if COAP_PROXY_OPTION_PROCESSING - coap_pkt->proxy_scheme = (char *)current_option; - coap_pkt->proxy_scheme_len = option_length; -#endif - PRINTF("Proxy-Scheme NOT IMPLEMENTED [%.*s]\n", - (int) coap_pkt->proxy_scheme_len, coap_pkt->proxy_scheme); - coap_error_message = "This is a constrained server (Contiki)"; - return PROXYING_NOT_SUPPORTED_5_05; - break; - - case COAP_OPTION_URI_HOST: - coap_pkt->uri_host = (char *)current_option; - coap_pkt->uri_host_len = option_length; - PRINTF("Uri-Host [%.*s]\n", (int) coap_pkt->uri_host_len, - coap_pkt->uri_host); - break; - case COAP_OPTION_URI_PORT: - coap_pkt->uri_port = coap_parse_int_option(current_option, - option_length); - PRINTF("Uri-Port [%u]\n", coap_pkt->uri_port); - break; - case COAP_OPTION_URI_PATH: - /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option((char **)&(coap_pkt->uri_path), - &(coap_pkt->uri_path_len), current_option, - option_length, '/'); - PRINTF("Uri-Path [%.*s]\n", (int) coap_pkt->uri_path_len, coap_pkt->uri_path); - break; - case COAP_OPTION_URI_QUERY: - /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option((char **)&(coap_pkt->uri_query), - &(coap_pkt->uri_query_len), current_option, - option_length, '&'); - PRINTF("Uri-Query [%.*s]\n", (int) coap_pkt->uri_query_len, - coap_pkt->uri_query); - break; - - case COAP_OPTION_LOCATION_PATH: - /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option((char **)&(coap_pkt->location_path), - &(coap_pkt->location_path_len), current_option, - option_length, '/'); - PRINTF("Location-Path [%.*s]\n", (int) coap_pkt->location_path_len, - coap_pkt->location_path); - break; - case COAP_OPTION_LOCATION_QUERY: - /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option((char **)&(coap_pkt->location_query), - &(coap_pkt->location_query_len), current_option, - option_length, '&'); - PRINTF("Location-Query [%.*s]\n", (int) coap_pkt->location_query_len, - coap_pkt->location_query); - break; - - case COAP_OPTION_OBSERVE: - coap_pkt->observe = coap_parse_int_option(current_option, - option_length); - PRINTF("Observe [%lu]\n", (long unsigned int) coap_pkt->observe); - break; - case COAP_OPTION_BLOCK2: - coap_pkt->block2_num = coap_parse_int_option(current_option, - option_length); - coap_pkt->block2_more = (coap_pkt->block2_num & 0x08) >> 3; - coap_pkt->block2_size = 16 << (coap_pkt->block2_num & 0x07); - coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F) - << (coap_pkt->block2_num & 0x07); - coap_pkt->block2_num >>= 4; - PRINTF("Block2 [%lu%s (%u B/blk)]\n", (long unsigned int) - coap_pkt->block2_num, - coap_pkt->block2_more ? "+" : "", coap_pkt->block2_size); - break; - case COAP_OPTION_BLOCK1: - coap_pkt->block1_num = coap_parse_int_option(current_option, - option_length); - coap_pkt->block1_more = (coap_pkt->block1_num & 0x08) >> 3; - coap_pkt->block1_size = 16 << (coap_pkt->block1_num & 0x07); - coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F) - << (coap_pkt->block1_num & 0x07); - coap_pkt->block1_num >>= 4; - PRINTF("Block1 [%lu%s (%u B/blk)]\n", (long unsigned int) - coap_pkt->block1_num, - coap_pkt->block1_more ? "+" : "", coap_pkt->block1_size); - break; - case COAP_OPTION_SIZE2: - coap_pkt->size2 = coap_parse_int_option(current_option, option_length); - PRINTF("Size2 [%lu]\n", (long unsigned int) coap_pkt->size2); - break; - case COAP_OPTION_SIZE1: - coap_pkt->size1 = coap_parse_int_option(current_option, option_length); - PRINTF("Size1 [%lu]\n", (long unsigned int) coap_pkt->size1); - break; - default: - PRINTF("unknown (%u)\n", option_number); - /* check if critical (odd) */ - if(option_number & 1) { - coap_error_message = "Unsupported critical option"; - return BAD_OPTION_4_02; - } - } - - current_option += option_length; - } /* for */ - PRINTF("-Done parsing-------\n"); - - return NO_ERROR; -} -/*---------------------------------------------------------------------------*/ -/*- REST Engine API ---------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -int -coap_get_query_variable(void *packet, const char *name, const char **output) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) { - return coap_get_variable(coap_pkt->uri_query, coap_pkt->uri_query_len, - name, output); - } - return 0; -} -int -coap_get_post_variable(void *packet, const char *name, const char **output) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(coap_pkt->payload_len) { - return coap_get_variable((const char *)coap_pkt->payload, - coap_pkt->payload_len, name, output); - } - return 0; -} -/*---------------------------------------------------------------------------*/ -int -coap_set_status_code(void *packet, unsigned int code) -{ - if(code <= 0xFF) { - ((coap_packet_t *)packet)->code = (uint8_t)code; - return 1; - } else { - return 0; - } -} -/*---------------------------------------------------------------------------*/ -int -coap_set_token(void *packet, const uint8_t *token, size_t token_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len); - memcpy(coap_pkt->token, token, coap_pkt->token_len); - - return coap_pkt->token_len; -} -/*---------------------------------------------------------------------------*/ -/*- CoAP REST Implementation API --------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -int -coap_get_header_content_format(void *packet, unsigned int *format) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(!IS_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT)) { - return 0; - } - *format = coap_pkt->content_format; - return 1; -} -int -coap_set_header_content_format(void *packet, unsigned int format) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - coap_pkt->content_format = format; - SET_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT); - return 1; -} -/*---------------------------------------------------------------------------*/ -int -coap_get_header_accept(void *packet, unsigned int *accept) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(!IS_OPTION(coap_pkt, COAP_OPTION_ACCEPT)) { - return 0; - } - *accept = coap_pkt->accept; - return 1; -} -int -coap_set_header_accept(void *packet, unsigned int accept) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - coap_pkt->accept = accept; - SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT); - return 1; -} -/*---------------------------------------------------------------------------*/ -int -coap_get_header_max_age(void *packet, uint32_t *age) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(!IS_OPTION(coap_pkt, COAP_OPTION_MAX_AGE)) { - *age = COAP_DEFAULT_MAX_AGE; - } else { - *age = coap_pkt->max_age; - } return 1; -} -int -coap_set_header_max_age(void *packet, uint32_t age) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - coap_pkt->max_age = age; - SET_OPTION(coap_pkt, COAP_OPTION_MAX_AGE); - return 1; -} -/*---------------------------------------------------------------------------*/ -int -coap_get_header_etag(void *packet, const uint8_t **etag) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(!IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) { - return 0; - } - *etag = coap_pkt->etag; - return coap_pkt->etag_len; -} -int -coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - coap_pkt->etag_len = MIN(COAP_ETAG_LEN, etag_len); - memcpy(coap_pkt->etag, etag, coap_pkt->etag_len); - - SET_OPTION(coap_pkt, COAP_OPTION_ETAG); - return coap_pkt->etag_len; -} -/*---------------------------------------------------------------------------*/ -/*FIXME support multiple ETags */ -int -coap_get_header_if_match(void *packet, const uint8_t **etag) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(!IS_OPTION(coap_pkt, COAP_OPTION_IF_MATCH)) { - return 0; - } - *etag = coap_pkt->if_match; - return coap_pkt->if_match_len; -} -int -coap_set_header_if_match(void *packet, const uint8_t *etag, size_t etag_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, etag_len); - memcpy(coap_pkt->if_match, etag, coap_pkt->if_match_len); - - SET_OPTION(coap_pkt, COAP_OPTION_IF_MATCH); - return coap_pkt->if_match_len; -} -/*---------------------------------------------------------------------------*/ -int -coap_get_header_if_none_match(void *packet) -{ - return IS_OPTION((coap_packet_t *)packet, - COAP_OPTION_IF_NONE_MATCH) ? 1 : 0; -} -int -coap_set_header_if_none_match(void *packet) -{ - SET_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH); - return 1; -} -/*---------------------------------------------------------------------------*/ -int -coap_is_secure(void *packet) -{ - return coap_context_is_secure(coap_get_context(packet)); -} -/*---------------------------------------------------------------------------*/ -coap_context_t * -coap_get_context(void *packet) -{ - coap_packet_t *p = packet; - return p->coap_ctx; -} -/*---------------------------------------------------------------------------*/ -int -coap_set_context(void *packet, coap_context_t *coap_ctx) -{ - coap_packet_t *p = packet; - p->coap_ctx = coap_ctx; - return 1; -} -/*---------------------------------------------------------------------------*/ -int -coap_get_header_proxy_uri(void *packet, const char **uri) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(!IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI)) { - return 0; - } - *uri = coap_pkt->proxy_uri; - return coap_pkt->proxy_uri_len; -} -int -coap_set_header_proxy_uri(void *packet, const char *uri) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - /*TODO Provide alternative that sets Proxy-Scheme and Uri-* options and provide er-coap-conf define */ - - coap_pkt->proxy_uri = uri; - coap_pkt->proxy_uri_len = strlen(uri); - - SET_OPTION(coap_pkt, COAP_OPTION_PROXY_URI); - return coap_pkt->proxy_uri_len; -} -/*---------------------------------------------------------------------------*/ -int -coap_get_header_uri_host(void *packet, const char **host) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST)) { - return 0; - } - *host = coap_pkt->uri_host; - return coap_pkt->uri_host_len; -} -int -coap_set_header_uri_host(void *packet, const char *host) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - coap_pkt->uri_host = host; - coap_pkt->uri_host_len = strlen(host); - - SET_OPTION(coap_pkt, COAP_OPTION_URI_HOST); - return coap_pkt->uri_host_len; -} -/*---------------------------------------------------------------------------*/ -int -coap_get_header_uri_path(void *packet, const char **path) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_PATH)) { - return 0; - } - *path = coap_pkt->uri_path; - return coap_pkt->uri_path_len; -} -int -coap_set_header_uri_path(void *packet, const char *path) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - while(path[0] == '/') - ++path; - - coap_pkt->uri_path = path; - coap_pkt->uri_path_len = strlen(path); - - SET_OPTION(coap_pkt, COAP_OPTION_URI_PATH); - return coap_pkt->uri_path_len; -} -/*---------------------------------------------------------------------------*/ -int -coap_get_header_uri_query(void *packet, const char **query) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) { - return 0; - } - *query = coap_pkt->uri_query; - return coap_pkt->uri_query_len; -} -int -coap_set_header_uri_query(void *packet, const char *query) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - while(query[0] == '?') - ++query; - - coap_pkt->uri_query = query; - coap_pkt->uri_query_len = strlen(query); - - SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); - return coap_pkt->uri_query_len; -} -/*---------------------------------------------------------------------------*/ -int -coap_get_header_location_path(void *packet, const char **path) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH)) { - return 0; - } - *path = coap_pkt->location_path; - return coap_pkt->location_path_len; -} -int -coap_set_header_location_path(void *packet, const char *path) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - char *query; - - while(path[0] == '/') - ++path; - - if((query = strchr(path, '?'))) { - coap_set_header_location_query(packet, query + 1); - coap_pkt->location_path_len = query - path; - } else { - coap_pkt->location_path_len = strlen(path); - } coap_pkt->location_path = path; - - if(coap_pkt->location_path_len > 0) { - SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH); - } - return coap_pkt->location_path_len; -} -/*---------------------------------------------------------------------------*/ -int -coap_get_header_location_query(void *packet, const char **query) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY)) { - return 0; - } - *query = coap_pkt->location_query; - return coap_pkt->location_query_len; -} -int -coap_set_header_location_query(void *packet, const char *query) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - while(query[0] == '?') - ++query; - - coap_pkt->location_query = query; - coap_pkt->location_query_len = strlen(query); - - SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY); - return coap_pkt->location_query_len; -} -/*---------------------------------------------------------------------------*/ -int -coap_get_header_observe(void *packet, uint32_t *observe) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(!IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) { - return 0; - } - *observe = coap_pkt->observe; - return 1; -} -int -coap_set_header_observe(void *packet, uint32_t observe) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - coap_pkt->observe = observe; - SET_OPTION(coap_pkt, COAP_OPTION_OBSERVE); - return 1; -} -/*---------------------------------------------------------------------------*/ -int -coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more, - uint16_t *size, uint32_t *offset) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK2)) { - return 0; - } - /* pointers may be NULL to get only specific block parameters */ - if(num != NULL) { - *num = coap_pkt->block2_num; - } - if(more != NULL) { - *more = coap_pkt->block2_more; - } - if(size != NULL) { - *size = coap_pkt->block2_size; - } - if(offset != NULL) { - *offset = coap_pkt->block2_offset; - } - return 1; -} -int -coap_set_header_block2(void *packet, uint32_t num, uint8_t more, - uint16_t size) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(size < 16) { - return 0; - } - if(size > 2048) { - return 0; - } - if(num > 0x0FFFFF) { - return 0; - } - coap_pkt->block2_num = num; - coap_pkt->block2_more = more ? 1 : 0; - coap_pkt->block2_size = size; - - SET_OPTION(coap_pkt, COAP_OPTION_BLOCK2); - return 1; -} -/*---------------------------------------------------------------------------*/ -int -coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more, - uint16_t *size, uint32_t *offset) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK1)) { - return 0; - } - /* pointers may be NULL to get only specific block parameters */ - if(num != NULL) { - *num = coap_pkt->block1_num; - } - if(more != NULL) { - *more = coap_pkt->block1_more; - } - if(size != NULL) { - *size = coap_pkt->block1_size; - } - if(offset != NULL) { - *offset = coap_pkt->block1_offset; - } - return 1; -} -int -coap_set_header_block1(void *packet, uint32_t num, uint8_t more, - uint16_t size) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(size < 16) { - return 0; - } - if(size > 2048) { - return 0; - } - if(num > 0x0FFFFF) { - return 0; - } - coap_pkt->block1_num = num; - coap_pkt->block1_more = more; - coap_pkt->block1_size = size; - - SET_OPTION(coap_pkt, COAP_OPTION_BLOCK1); - return 1; -} -/*---------------------------------------------------------------------------*/ -int -coap_get_header_size2(void *packet, uint32_t *size) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(!IS_OPTION(coap_pkt, COAP_OPTION_SIZE2)) { - return 0; - } - *size = coap_pkt->size2; - return 1; -} -int -coap_set_header_size2(void *packet, uint32_t size) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - coap_pkt->size2 = size; - SET_OPTION(coap_pkt, COAP_OPTION_SIZE2); - return 1; -} -/*---------------------------------------------------------------------------*/ -int -coap_get_header_size1(void *packet, uint32_t *size) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(!IS_OPTION(coap_pkt, COAP_OPTION_SIZE1)) { - return 0; - } - *size = coap_pkt->size1; - return 1; -} -int -coap_set_header_size1(void *packet, uint32_t size) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - coap_pkt->size1 = size; - SET_OPTION(coap_pkt, COAP_OPTION_SIZE1); - return 1; -} -/*---------------------------------------------------------------------------*/ -int -coap_get_payload(void *packet, const uint8_t **payload) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if(coap_pkt->payload) { - *payload = coap_pkt->payload; - return coap_pkt->payload_len; - } else { - *payload = NULL; - return 0; - } -} -int -coap_set_payload(void *packet, const void *payload, size_t length) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - coap_pkt->payload = (uint8_t *)payload; - coap_pkt->payload_len = MIN(REST_MAX_CHUNK_SIZE, length); - - return coap_pkt->payload_len; -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/er-coap/er-coap.h b/net/ip/er-coap/er-coap.h deleted file mode 100644 index 79fe42b9526e273745144409eaf3bf8e671b1bb1..0000000000000000000000000000000000000000 --- a/net/ip/er-coap/er-coap.h +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * An implementation of the Constrained Application Protocol (RFC). - * \author - * Matthias Kovatsch - */ - -#ifndef ER_COAP_H_ -#define ER_COAP_H_ - -#include - -#include /* for size_t */ -#include "contiki-net.h" -#include "er-coap-constants.h" -#include "er-coap-conf.h" -#include "er-coap-context.h" - -/* sanity check for configured values */ -#define COAP_MAX_PACKET_SIZE (COAP_MAX_HEADER_SIZE + REST_MAX_CHUNK_SIZE) -#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_IPH_LEN - UIP_UDPH_LEN) -#error "UIP_CONF_BUFFER_SIZE too small for REST_MAX_CHUNK_SIZE" -#endif - -#if NET_COAP_CONF_STATS -typedef struct net_coap_stats { - uint32_t recv; - uint32_t recv_err; - uint32_t sent; - uint32_t re_sent; -} net_coap_stats_t; - -extern net_coap_stats_t net_coap_stats; -#endif /* NET_COAP_CONF_STATS */ - -/* use Erbium CoAP for the REST Engine. Must come before include of rest-engine.h. */ -#ifndef REST -#define REST coap_rest_implementation -#endif -#include "rest-engine.h" - -/* REST_MAX_CHUNK_SIZE can be different from 2^x so we need to get next lower 2^x for COAP_MAX_BLOCK_SIZE */ -#ifndef COAP_MAX_BLOCK_SIZE -#define COAP_MAX_BLOCK_SIZE (REST_MAX_CHUNK_SIZE < 32 ? 16 : \ - (REST_MAX_CHUNK_SIZE < 64 ? 32 : \ - (REST_MAX_CHUNK_SIZE < 128 ? 64 : \ - (REST_MAX_CHUNK_SIZE < 256 ? 128 : \ - (REST_MAX_CHUNK_SIZE < 512 ? 256 : \ - (REST_MAX_CHUNK_SIZE < 1024 ? 512 : \ - (REST_MAX_CHUNK_SIZE < 2048 ? 1024 : 2048))))))) -#endif /* COAP_MAX_BLOCK_SIZE */ - -/* direct access into the buffer */ -#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN]) -#if NETSTACK_CONF_WITH_IPV6 -#define UIP_UDP_BUF(buf) ((struct uip_udp_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)]) -#else -#define UIP_UDP_BUF(buf) ((struct uip_udp_hdr *)&uip_buf(buf)[UIP_LLH_LEN + UIP_IPH_LEN]) -#endif - -/* bitmap for set options */ -enum { OPTION_MAP_SIZE = sizeof(uint8_t) * 8 }; - -#define SET_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] |= 1 << (opt % OPTION_MAP_SIZE)) -#define IS_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] & (1 << (opt % OPTION_MAP_SIZE))) - -/* parsed message struct */ -typedef struct { - uint8_t *buffer; /* pointer to CoAP header / incoming packet buffer / memory to serialize packet */ - - uint8_t version; - coap_message_type_t type; - uint8_t code; - uint16_t mid; - - uint8_t token_len; - uint8_t token[COAP_TOKEN_LEN]; - - uint8_t options[COAP_OPTION_SIZE1 / OPTION_MAP_SIZE + 1]; /* bitmap to check if option is set */ - - uint16_t content_format; /* parse options once and store; allows setting options in random order */ - uint32_t max_age; - uint8_t etag_len; - uint8_t etag[COAP_ETAG_LEN]; - size_t proxy_uri_len; - const char *proxy_uri; - size_t proxy_scheme_len; - const char *proxy_scheme; - size_t uri_host_len; - const char *uri_host; - size_t location_path_len; - const char *location_path; - uint16_t uri_port; - size_t location_query_len; - const char *location_query; - size_t uri_path_len; - const char *uri_path; - int32_t observe; - uint16_t accept; - uint8_t if_match_len; - uint8_t if_match[COAP_ETAG_LEN]; - uint32_t block2_num; - uint8_t block2_more; - uint16_t block2_size; - uint32_t block2_offset; - uint32_t block1_num; - uint8_t block1_more; - uint16_t block1_size; - uint32_t block1_offset; - uint32_t size2; - uint32_t size1; - size_t uri_query_len; - const char *uri_query; - uint8_t if_none_match; - - coap_context_t *coap_ctx; - - uint16_t payload_len; - uint8_t *payload; -} coap_packet_t; - -/* option format serialization */ -#define COAP_SERIALIZE_INT_OPTION(number, field, text) \ - if(IS_OPTION(coap_pkt, number)) { \ - PRINTF(text " [%u]\n", (unsigned int) coap_pkt->field); \ - option += coap_serialize_int_option(number, current_number, option, coap_pkt->field); \ - current_number = number; \ - } -#define COAP_SERIALIZE_BYTE_OPTION(number, field, text) \ - if(IS_OPTION(coap_pkt, number)) { \ - PRINTF(text " %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", (unsigned int) coap_pkt->field##_len, \ - coap_pkt->field[0], \ - coap_pkt->field[1], \ - coap_pkt->field[2], \ - coap_pkt->field[3], \ - coap_pkt->field[4], \ - coap_pkt->field[5], \ - coap_pkt->field[6], \ - coap_pkt->field[7] \ - ); /* FIXME always prints 8 bytes */ \ - option += coap_serialize_array_option(number, current_number, option, coap_pkt->field, coap_pkt->field##_len, '\0'); \ - current_number = number; \ - } -#define COAP_SERIALIZE_STRING_OPTION(number, field, splitter, text) \ - if(IS_OPTION(coap_pkt, number)) { \ - PRINTF(text " [%.*s]\n", (int) coap_pkt->field##_len, coap_pkt->field); \ - option += coap_serialize_array_option(number, current_number, option, (uint8_t *)coap_pkt->field, coap_pkt->field##_len, splitter); \ - current_number = number; \ - } -#define COAP_SERIALIZE_BLOCK_OPTION(number, field, text) \ - if(IS_OPTION(coap_pkt, number)) \ - { \ - PRINTF(text " [%lu%s (%u B/blk)]\n", (unsigned long)coap_pkt->field##_num, coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size); \ - uint32_t block = coap_pkt->field##_num << 4; \ - if(coap_pkt->field##_more) { block |= 0x8; } \ - block |= 0xF & coap_log_2(coap_pkt->field##_size / 16); \ - PRINTF(text " encoded: 0x%lX\n", (unsigned long)block); \ - option += coap_serialize_int_option(number, current_number, option, block); \ - current_number = number; \ - } - -/* to store error code and human-readable payload */ -extern coap_status_t erbium_status_code; -extern char *coap_error_message; - -coap_context_t *coap_init_connection(uip_ipaddr_t *server_addr, - uint16_t server_port, - uip_ipaddr_t *peer_addr, - uint16_t peer_port); -uint16_t coap_get_mid(void); - -void coap_init_message(void *packet, coap_message_type_t type, uint8_t code, - uint16_t mid); -size_t coap_serialize_message(void *packet, uint8_t *buffer); -void coap_send_message(coap_context_t *coap_ctx, - uip_ipaddr_t *addr, uint16_t port, - const uint8_t *data, - uint16_t length); -coap_status_t coap_parse_message(void *request, uint8_t *data, - uint16_t data_len); - -int coap_get_query_variable(void *packet, const char *name, - const char **output); -int coap_get_post_variable(void *packet, const char *name, - const char **output); - -/*---------------------------------------------------------------------------*/ -int coap_is_secure(void *packet); -coap_context_t *coap_get_context(void *packet); -int coap_set_context(void *packet, coap_context_t *coap_ctx); -/*---------------------------------------------------------------------------*/ - -int coap_set_status_code(void *packet, unsigned int code); - -int coap_set_token(void *packet, const uint8_t *token, size_t token_len); - -int coap_get_header_content_format(void *packet, unsigned int *format); -int coap_set_header_content_format(void *packet, unsigned int format); - -int coap_get_header_accept(void *packet, unsigned int *accept); -int coap_set_header_accept(void *packet, unsigned int accept); - -int coap_get_header_max_age(void *packet, uint32_t *age); -int coap_set_header_max_age(void *packet, uint32_t age); - -int coap_get_header_etag(void *packet, const uint8_t **etag); -int coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len); - -int coap_get_header_if_match(void *packet, const uint8_t **etag); -int coap_set_header_if_match(void *packet, const uint8_t *etag, - size_t etag_len); - -int coap_get_header_if_none_match(void *packet); -int coap_set_header_if_none_match(void *packet); - -int coap_get_header_proxy_uri(void *packet, const char **uri); /* in-place string might not be 0-terminated. */ -int coap_set_header_proxy_uri(void *packet, const char *uri); - -int coap_get_header_proxy_scheme(void *packet, const char **scheme); /* in-place string might not be 0-terminated. */ -int coap_set_header_proxy_scheme(void *packet, const char *scheme); - -int coap_get_header_uri_host(void *packet, const char **host); /* in-place string might not be 0-terminated. */ -int coap_set_header_uri_host(void *packet, const char *host); - -int coap_get_header_uri_path(void *packet, const char **path); /* in-place string might not be 0-terminated. */ -int coap_set_header_uri_path(void *packet, const char *path); - -int coap_get_header_uri_query(void *packet, const char **query); /* in-place string might not be 0-terminated. */ -int coap_set_header_uri_query(void *packet, const char *query); - -int coap_get_header_location_path(void *packet, const char **path); /* in-place string might not be 0-terminated. */ -int coap_set_header_location_path(void *packet, const char *path); /* also splits optional query into Location-Query option. */ - -int coap_get_header_location_query(void *packet, const char **query); /* in-place string might not be 0-terminated. */ -int coap_set_header_location_query(void *packet, const char *query); - -int coap_get_header_observe(void *packet, uint32_t *observe); -int coap_set_header_observe(void *packet, uint32_t observe); - -int coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more, - uint16_t *size, uint32_t *offset); -int coap_set_header_block2(void *packet, uint32_t num, uint8_t more, - uint16_t size); - -int coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more, - uint16_t *size, uint32_t *offset); -int coap_set_header_block1(void *packet, uint32_t num, uint8_t more, - uint16_t size); - -int coap_get_header_size2(void *packet, uint32_t *size); -int coap_set_header_size2(void *packet, uint32_t size); - -int coap_get_header_size1(void *packet, uint32_t *size); -int coap_set_header_size1(void *packet, uint32_t size); - -int coap_get_payload(void *packet, const uint8_t **payload); -int coap_set_payload(void *packet, const void *payload, size_t length); - -void coap_init_mid(void); - -#endif /* ER_COAP_H_ */ diff --git a/net/ip/ip_buf.c b/net/ip/ip_buf.c deleted file mode 100644 index abdacfe419e732567407be54af2067ab054d4f05..0000000000000000000000000000000000000000 --- a/net/ip/ip_buf.c +++ /dev/null @@ -1,411 +0,0 @@ -/** @file - @brief Network buffers for IP stack - - IP data is passed between application and IP stack via - a net_buf struct. - */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "ip/uip.h" - -#if !defined(CONFIG_NETWORK_IP_STACK_DEBUG_NET_BUF) -#undef NET_DBG -#define NET_DBG(...) -#endif - -extern struct net_tuple *net_context_get_tuple(struct net_context *context); -extern void *net_context_get_internal_connection(struct net_context *context); - -/* Available (free) buffers queue */ -#ifndef IP_BUF_RX_SIZE -#if CONFIG_IP_BUF_RX_SIZE > 0 -#define IP_BUF_RX_SIZE CONFIG_IP_BUF_RX_SIZE -#else -#define IP_BUF_RX_SIZE 1 -#endif -#endif - -#ifndef IP_BUF_TX_SIZE -#if CONFIG_IP_BUF_TX_SIZE > 0 -#define IP_BUF_TX_SIZE CONFIG_IP_BUF_TX_SIZE -#else -#define IP_BUF_TX_SIZE 1 -#endif -#endif - -#ifdef DEBUG_IP_BUFS -static int num_free_rx_bufs = IP_BUF_RX_SIZE; -static int num_free_tx_bufs = IP_BUF_TX_SIZE; - -static inline void dec_free_rx_bufs(struct net_buf *buf) -{ - if (!buf) { - return; - } - - num_free_rx_bufs--; - if (num_free_rx_bufs < 0) { - NET_DBG("*** ERROR *** Invalid RX buffer count.\n"); - num_free_rx_bufs = 0; - } -} - -static inline void inc_free_rx_bufs(struct net_buf *buf) -{ - if (!buf) { - return; - } - - if (num_free_rx_bufs > IP_BUF_RX_SIZE) { - num_free_rx_bufs = IP_BUF_RX_SIZE; - } else { - num_free_rx_bufs++; - } -} - -static inline void dec_free_tx_bufs(struct net_buf *buf) -{ - if (!buf) { - return; - } - - num_free_tx_bufs--; - if (num_free_tx_bufs < 0) { - NET_DBG("*** ERROR *** Invalid TX buffer count.\n"); - num_free_tx_bufs = 0; - } -} - -static inline void inc_free_tx_bufs(struct net_buf *buf) -{ - if (!buf) { - return; - } - - if (num_free_tx_bufs > IP_BUF_TX_SIZE) { - num_free_tx_bufs = IP_BUF_TX_SIZE; - } else { - num_free_tx_bufs++; - } -} - -static inline int get_frees(enum ip_buf_type type) -{ - switch (type) { - case IP_BUF_RX: - return num_free_rx_bufs; - case IP_BUF_TX: - return num_free_tx_bufs; - } - - return 0xffffffff; -} - -#define inc_free_rx_bufs_func inc_free_rx_bufs -#define inc_free_tx_bufs_func inc_free_tx_bufs - -#else -#define dec_free_rx_bufs(...) -#define inc_free_rx_bufs(...) -#define dec_free_tx_bufs(...) -#define inc_free_tx_bufs(...) -#define inc_free_rx_bufs_func(...) -#define inc_free_tx_bufs_func(...) -#endif - -static struct nano_fifo free_rx_bufs; -static struct nano_fifo free_tx_bufs; - -static inline void free_rx_bufs_func(struct net_buf *buf) -{ - inc_free_rx_bufs_func(buf); - - nano_fifo_put(buf->free, buf); -} - -static inline void free_tx_bufs_func(struct net_buf *buf) -{ - inc_free_tx_bufs_func(buf); - - nano_fifo_put(buf->free, buf); -} - -static NET_BUF_POOL(rx_buffers, IP_BUF_RX_SIZE, IP_BUF_MAX_DATA, \ - &free_rx_bufs, free_rx_bufs_func, \ - sizeof(struct ip_buf)); -static NET_BUF_POOL(tx_buffers, IP_BUF_TX_SIZE, IP_BUF_MAX_DATA, \ - &free_tx_bufs, free_tx_bufs_func, \ - sizeof(struct ip_buf)); - -static inline const char *type2str(enum ip_buf_type type) -{ - switch (type) { - case IP_BUF_RX: - return "RX"; - case IP_BUF_TX: - return "TX"; - } - - return NULL; -} - -#ifdef DEBUG_IP_BUFS -static struct net_buf *ip_buf_get_reserve_debug(enum ip_buf_type type, - uint16_t reserve_head, - const char *caller, - int line) -#else -static struct net_buf *ip_buf_get_reserve(enum ip_buf_type type, - uint16_t reserve_head) -#endif -{ - struct net_buf *buf = NULL; - - /* Note that we do not reserve any space in front of the - * buffer so buf->data points to first byte of the IP header. - * This is done like this so that IP stack works the same - * way as BT and 802.15.4 stacks. - * - * The reserve_head variable in the function will tell - * the size of the IP + other headers if there are any. - * That variable is only used to calculate the pointer - * where the application data starts. - */ - switch (type) { - case IP_BUF_RX: - buf = net_buf_get(&free_rx_bufs, 0); - dec_free_rx_bufs(buf); - break; - case IP_BUF_TX: - buf = net_buf_get(&free_tx_bufs, 0); - dec_free_tx_bufs(buf); - break; - } - - if (!buf) { -#ifdef DEBUG_IP_BUFS - NET_ERR("Failed to get free %s buffer (%s():%d)\n", - type2str(type), caller, line); -#else - NET_ERR("Failed to get free %s buffer\n", type2str(type)); -#endif - return NULL; - } - - ip_buf_type(buf) = type; - ip_buf_appdata(buf) = buf->data + reserve_head; - ip_buf_appdatalen(buf) = 0; - ip_buf_reserve(buf) = reserve_head; - net_buf_add(buf, reserve_head); - - NET_BUF_CHECK_IF_NOT_IN_USE(buf); - -#ifdef DEBUG_IP_BUFS - NET_DBG("%s [%d] buf %p reserve %u ref %d (%s():%d)\n", - type2str(type), get_frees(type), - buf, reserve_head, buf->ref, caller, line); -#else - NET_DBG("%s buf %p reserve %u ref %d\n", type2str(type), buf, - reserve_head, buf->ref); -#endif - return buf; -} - -#ifdef DEBUG_IP_BUFS -struct net_buf *ip_buf_get_reserve_rx_debug(uint16_t reserve_head, const char *caller, int line) -#else -struct net_buf *ip_buf_get_reserve_rx(uint16_t reserve_head) -#endif -{ -#ifdef DEBUG_IP_BUFS - return ip_buf_get_reserve_debug(IP_BUF_RX, reserve_head, - caller, line); -#else - return ip_buf_get_reserve(IP_BUF_RX, reserve_head); -#endif -} - -#ifdef DEBUG_IP_BUFS -struct net_buf *ip_buf_get_reserve_tx_debug(uint16_t reserve_head, const char *caller, int line) -#else -struct net_buf *ip_buf_get_reserve_tx(uint16_t reserve_head) -#endif -{ -#ifdef DEBUG_IP_BUFS - return ip_buf_get_reserve_debug(IP_BUF_TX, reserve_head, - caller, line); -#else - return ip_buf_get_reserve(IP_BUF_TX, reserve_head); -#endif -} - -#ifdef DEBUG_IP_BUFS -static struct net_buf *ip_buf_get_debug(enum ip_buf_type type, - struct net_context *context, - const char *caller, int line) -#else -static struct net_buf *ip_buf_get(enum ip_buf_type type, - struct net_context *context) -#endif -{ - struct net_buf *buf; - struct net_tuple *tuple; - uint16_t reserve = 0; - - tuple = net_context_get_tuple(context); - if (!tuple) { - return NULL; - } - - switch (tuple->ip_proto) { - case IPPROTO_UDP: - reserve = UIP_IPUDPH_LEN + UIP_LLH_LEN; - break; - case IPPROTO_TCP: - reserve = UIP_IPTCPH_LEN + UIP_LLH_LEN; - break; - case IPPROTO_ICMPV6: - reserve = UIP_IPICMPH_LEN + UIP_LLH_LEN; - break; - } - -#ifdef DEBUG_IP_BUFS - buf = ip_buf_get_reserve_debug(type, reserve, caller, line); -#else - buf = ip_buf_get_reserve(type, reserve); -#endif - if (!buf) { - return buf; - } - - ip_buf_context(buf) = context; - uip_set_conn(buf) = net_context_get_internal_connection(context); - - return buf; -} - -#ifdef DEBUG_IP_BUFS -struct net_buf *ip_buf_get_rx_debug(struct net_context *context, - const char *caller, int line) -#else -struct net_buf *ip_buf_get_rx(struct net_context *context) -#endif -{ -#ifdef DEBUG_IP_BUFS - return ip_buf_get_debug(IP_BUF_RX, context, caller, line); -#else - return ip_buf_get(IP_BUF_RX, context); -#endif -} - -#ifdef DEBUG_IP_BUFS -struct net_buf *ip_buf_get_tx_debug(struct net_context *context, - const char *caller, int line) -#else -struct net_buf *ip_buf_get_tx(struct net_context *context) -#endif -{ -#ifdef DEBUG_IP_BUFS - return ip_buf_get_debug(IP_BUF_TX, context, caller, line); -#else - return ip_buf_get(IP_BUF_TX, context); -#endif -} - -#ifdef DEBUG_IP_BUFS -void ip_buf_unref_debug(struct net_buf *buf, const char *caller, int line) -#else -void ip_buf_unref(struct net_buf *buf) -#endif -{ - if (!buf) { -#ifdef DEBUG_IP_BUFS - NET_DBG("*** ERROR *** buf %p (%s():%d)\n", buf, caller, line); -#else - NET_DBG("*** ERROR *** buf %p\n", buf); -#endif - return; - } - - if (!buf->ref) { -#ifdef DEBUG_IP_BUFS - NET_DBG("*** ERROR *** buf %p is freed already (%s():%d)\n", - buf, caller, line); -#else - NET_DBG("*** ERROR *** buf %p is freed already\n", buf); -#endif - return; - } - -#ifdef DEBUG_IP_BUFS - NET_DBG("%s [%d] buf %p ref %d (%s():%d)\n", - type2str(ip_buf_type(buf)), get_frees(ip_buf_type(buf)), - buf, buf->ref - 1, caller, line); -#else - NET_DBG("%s buf %p ref %d\n", - type2str(ip_buf_type(buf)), buf, buf->ref - 1); -#endif - - net_buf_unref(buf); -} - -#ifdef DEBUG_IP_BUFS -struct net_buf *ip_buf_ref_debug(struct net_buf *buf, const char *caller, int line) -#else -struct net_buf *ip_buf_ref(struct net_buf *buf) -#endif -{ - if (!buf) { -#ifdef DEBUG_IP_BUFS - NET_DBG("*** ERROR *** buf %p (%s():%d)\n", buf, caller, line); -#else - NET_DBG("*** ERROR *** buf %p\n", buf); -#endif - return NULL; - } - -#ifdef DEBUG_IP_BUFS - NET_DBG("%s [%d] buf %p ref %d (%s():%d)\n", - type2str(ip_buf_type(buf)), get_frees(ip_buf_type(buf)), - buf, buf->ref + 1, caller, line); -#else - NET_DBG("%s buf %p ref %d\n", - type2str(ip_buf_type(buf)), buf, buf->ref + 1); -#endif - - return net_buf_ref(buf); -} - -void ip_buf_init(void) -{ - NET_DBG("Allocating %d RX and %d TX buffers for IP stack\n", - IP_BUF_RX_SIZE, IP_BUF_TX_SIZE); - - net_buf_pool_init(rx_buffers); - net_buf_pool_init(tx_buffers); -} diff --git a/net/ip/l2_buf.c b/net/ip/l2_buf.c deleted file mode 100644 index 32bd00ef1488103a569185fa499b5a81dfd81b85..0000000000000000000000000000000000000000 --- a/net/ip/l2_buf.c +++ /dev/null @@ -1,171 +0,0 @@ -/** @file - @brief Network buffers for IP stack - - IP data is passed between application and IP stack via - a net_buf struct. - */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "ip/uip.h" - -#if !defined(CONFIG_NETWORK_IP_STACK_DEBUG_NET_BUF) -#undef NET_DBG -#define NET_DBG(...) -#endif - -/* Available (free) layer 2 (MAC/L2) buffers queue */ -#ifndef NET_NUM_L2_BUFS -/* Default value is 13 (receiving side) which means that max. UDP data - * (1232 bytes) can be received in one go. In sending side we need 1 - * mbuf + some extras. - */ -#define NET_NUM_L2_BUFS 16 -#endif - -#ifdef DEBUG_L2_BUFS -static int num_free_l2_bufs = NET_NUM_L2_BUFS; - -static inline void dec_free_l2_bufs(struct net_buf *buf) -{ - if (!buf) { - return; - } - - num_free_l2_bufs--; - if (num_free_l2_bufs < 0) { - NET_DBG("*** ERROR *** Invalid L2 buffer count.\n"); - num_free_l2_bufs = 0; - } -} - -static inline void inc_free_l2_bufs(struct net_buf *buf) -{ - if (!buf) { - return; - } - - num_free_l2_bufs++; -} - -static inline int get_free_l2_bufs(void) -{ - return num_free_l2_bufs; -} - -#define inc_free_l2_bufs_func inc_free_l2_bufs - -#else -#define dec_free_l2_bufs(...) -#define inc_free_l2_bufs(...) -#define get_free_l2_bufs(...) -#define inc_free_l2_bufs_func(...) -#endif - -static struct nano_fifo free_l2_bufs; - -static inline void free_l2_bufs_func(struct net_buf *buf) -{ - inc_free_l2_bufs_func(buf); - - nano_fifo_put(buf->free, buf); -} - -static NET_BUF_POOL(l2_buffers, NET_NUM_L2_BUFS, NET_L2_BUF_MAX_SIZE, \ - &free_l2_bufs, free_l2_bufs_func, \ - sizeof(struct l2_buf)); - -#ifdef DEBUG_L2_BUFS -struct net_buf *l2_buf_get_reserve_debug(uint16_t reserve_head, const char *caller, int line) -#else -struct net_buf *l2_buf_get_reserve(uint16_t reserve_head) -#endif -{ - struct net_buf *buf; - - buf = net_buf_get(&free_l2_bufs, reserve_head); - if (!buf) { -#ifdef DEBUG_L2_BUFS - NET_ERR("Failed to get free L2 buffer (%s():%d)\n", - caller, line); -#else - NET_ERR("Failed to get free L2 buffer\n"); -#endif - return NULL; - } - - dec_free_l2_bufs(buf); - - NET_BUF_CHECK_IF_NOT_IN_USE(buf); - -#ifdef DEBUG_L2_BUFS - NET_DBG("[%d] buf %p reserve %u ref %d (%s():%d)\n", - get_free_l2_bufs(), buf, reserve_head, buf->ref, - caller, line); -#else - NET_DBG("buf %p reserve %u ref %d\n", buf, reserve_head, buf->ref); -#endif - - packetbuf_clear(buf); -#if defined(CONFIG_NETWORKING_WITH_15_4) - LIST_STRUCT_INIT(((struct l2_buf *)net_buf_user_data((buf))), neighbor_list); -#endif - - return buf; -} - -#ifdef DEBUG_L2_BUFS -void l2_buf_unref_debug(struct net_buf *buf, const char *caller, int line) -#else -void l2_buf_unref(struct net_buf *buf) -#endif -{ - if (!buf) { -#ifdef DEBUG_L2_BUFS - NET_DBG("*** ERROR *** buf %p (%s():%d)\n", buf, caller, line); -#else - NET_DBG("*** ERROR *** buf %p\n", buf); -#endif - return; - } - -#ifdef DEBUG_L2_BUFS - NET_DBG("[%d] buf %p ref %d (%s():%d)\n", - get_free_l2_bufs() + 1, buf, buf->ref, caller, line); -#else - NET_DBG("buf %p ref %d\n", buf, buf->ref); -#endif - - net_buf_unref(buf); -} - -void l2_buf_init(void) -{ - NET_DBG("Allocating %d L2 buffers\n", NET_NUM_L2_BUFS); - - net_buf_pool_init(l2_buffers); -} diff --git a/net/ip/net_context.c b/net/ip/net_context.c deleted file mode 100644 index 3cfcc3969cda1b743a3619484dd91f80c4aea7ba..0000000000000000000000000000000000000000 --- a/net/ip/net_context.c +++ /dev/null @@ -1,697 +0,0 @@ -/** @file - @brief Network context API - - An API for applications to define a network connection. - */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_CONTEXT -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#include -#include -#include -#include - -#include -#include - -#include "contiki/ip/simple-udp.h" -#include "contiki/ipv6/uip-ds6.h" - -#include "contiki/os/lib/random.h" -#include "contiki/ipv6/uip-ds6.h" - -#ifdef CONFIG_NETWORKING_WITH_TCP -#include "contiki/os/sys/process.h" -#include "contiki/ip/psock.h" -#endif - -#if !defined(CONFIG_NETWORK_IP_STACK_DEBUG_CONTEXT) -#undef NET_DBG -#define NET_DBG(...) -#endif - -int net_context_get_receiver_registered(struct net_context *context); - -struct net_context { - /* Connection tuple identifies the connection */ - struct net_tuple tuple; - - /* Application receives data via this fifo */ - struct nano_fifo rx_queue; - - /* Application connection data */ - union { - struct simple_udp_connection udp; - -#ifdef CONFIG_NETWORKING_WITH_TCP - struct { - /* Proto socket that handles one TCP connection. */ - struct psock ps; - struct process tcp; - enum net_tcp_type tcp_type; - int connection_status; - void *conn; - struct net_buf *pending; - uint8_t retry_count; - }; -#endif - }; - - bool receiver_registered; -}; - -/* Override this in makefile if needed */ -#if defined(CONFIG_NET_MAX_CONTEXTS) -#define NET_MAX_CONTEXT CONFIG_NET_MAX_CONTEXTS -#else -#define NET_MAX_CONTEXT 5 -#endif - -static struct net_context contexts[NET_MAX_CONTEXT]; -static struct nano_sem contexts_lock; - -static void context_sem_give(struct nano_sem *chan) -{ - switch (sys_execution_context_type_get()) { - case NANO_CTX_FIBER: - nano_fiber_sem_give(chan); - break; - case NANO_CTX_TASK: - nano_task_sem_give(chan); - break; - case NANO_CTX_ISR: - default: - /* Invalid context type */ - break; - } -} - -static int context_port_used(enum ip_protocol ip_proto, uint16_t local_port, - const struct net_addr *local_addr) - -{ - int i; - - for (i = 0; i < NET_MAX_CONTEXT; i++) { - if (contexts[i].tuple.ip_proto == ip_proto && - contexts[i].tuple.local_port == local_port && - !memcmp(&contexts[i].tuple.local_addr, local_addr, - sizeof(struct net_addr))) { - return -EEXIST; - } - } - - return 0; -} - -struct net_context *net_context_get(enum ip_protocol ip_proto, - const struct net_addr *remote_addr, - uint16_t remote_port, - struct net_addr *local_addr, - uint16_t local_port) -{ -#ifdef CONFIG_NETWORKING_WITH_IPV6 - const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; - const uip_ds6_addr_t *uip_addr; - uip_ipaddr_t ipaddr; -#endif - int i; - struct net_context *context = NULL; - - /* User must provide storage for the local address. */ - if (!local_addr) { - return NULL; - } - -#ifdef CONFIG_NETWORKING_WITH_IPV6 - if (memcmp(&local_addr->in6_addr, &in6addr_any, - sizeof(in6addr_any)) == 0) { - uip_addr = uip_ds6_get_global(-1); - if (!uip_addr) { - uip_addr = uip_ds6_get_link_local(-1); - } - if (!uip_addr) { - return NULL; - } - - memcpy(&local_addr->in6_addr, &uip_addr->ipaddr, - sizeof(struct in6_addr)); - } -#else - if (local_addr->in_addr.s_addr[0] == INADDR_ANY) { - uip_gethostaddr((uip_ipaddr_t *)&local_addr->in_addr); - } -#endif - - nano_sem_take(&contexts_lock, TICKS_UNLIMITED); - - if (local_port) { - if (context_port_used(ip_proto, local_port, local_addr) < 0) { - return NULL; - } - } else { - do { - local_port = random_rand() | 0x8000; - } while (context_port_used(ip_proto, local_port, - local_addr) == -EEXIST); - } - - for (i = 0; i < NET_MAX_CONTEXT; i++) { - if (!contexts[i].tuple.ip_proto) { - contexts[i].tuple.ip_proto = ip_proto; - contexts[i].tuple.remote_addr = (struct net_addr *)remote_addr; - contexts[i].tuple.remote_port = remote_port; - contexts[i].tuple.local_addr = (struct net_addr *)local_addr; - contexts[i].tuple.local_port = local_port; - context = &contexts[i]; - break; - } - } - - context_sem_give(&contexts_lock); - - /* Set our local address */ -#ifdef CONFIG_NETWORKING_WITH_IPV6 - memcpy(&ipaddr.u8, local_addr->in6_addr.s6_addr, sizeof(ipaddr.u8)); - if (uip_is_addr_mcast(&ipaddr)) { - uip_ds6_maddr_add(&ipaddr); - } else { - uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL); - } -#endif - - return context; -} - -void net_context_put(struct net_context *context) -{ - if (!context) { - return; - } - - nano_sem_take(&contexts_lock, TICKS_UNLIMITED); - - if (context->tuple.ip_proto == IPPROTO_UDP) { - if (net_context_get_receiver_registered(context)) { - struct simple_udp_connection *udp = - net_context_get_udp_connection(context); - simple_udp_unregister(udp); - } - } - -#ifdef CONFIG_NETWORKING_WITH_TCP - if (context->tcp_type == NET_TCP_TYPE_SERVER) { - tcp_unlisten(UIP_HTONS(context->tuple.local_port), - &context->tcp); - } -#endif - - memset(&context->tuple, 0, sizeof(context->tuple)); - memset(&context->udp, 0, sizeof(context->udp)); - context->receiver_registered = false; - - context_sem_give(&contexts_lock); -} - -struct net_tuple *net_context_get_tuple(struct net_context *context) -{ - if (!context) { - return NULL; - } - - return &context->tuple; -} - -struct nano_fifo *net_context_get_queue(struct net_context *context) -{ - if (!context) - return NULL; - - return &context->rx_queue; -} - -struct simple_udp_connection * -net_context_get_udp_connection(struct net_context *context) -{ - if (!context) { - return NULL; - } - - return &context->udp; -} - -#ifdef CONFIG_NETWORKING_WITH_TCP -static int handle_tcp_connection(struct psock *p, enum tcp_event_type type, - struct net_buf *buf) -{ - PSOCK_BEGIN(p); - - if (type == TCP_WRITE_EVENT) { - NET_DBG("Trying to send %d bytes data\n", uip_appdatalen(buf)); - PSOCK_SEND(p, buf); - } - - PSOCK_END(p); -} - -int net_context_tcp_send(struct net_buf *buf) -{ - bool connected, reset; - - /* Prepare data to be sent */ - - process_post_synch(&ip_buf_context(buf)->tcp, - tcpip_event, - INT_TO_POINTER(TCP_WRITE_EVENT), - buf); - - connected = uip_flags(buf) & UIP_CONNECTED; - reset = uip_flags(buf) & UIP_ABORT; - - /* If the buffer ref is 1, then the buffer was sent and it - * is cleared already. - */ - if (buf->ref == 1) { - return 0; - } - - return ip_buf_sent_status(buf); -} - -/* This is called by contiki/ip/tcpip.c:tcpip_uipcall() when packet - * is processed. - */ -PROCESS_THREAD(tcp, ev, data, buf, user_data) -{ - NET_DBG("tcp %p ev %d data %p buf %p user_data %p next line %d\n", - process_thread_tcp, ev, data, buf, user_data, - process_pt->lc); - - PROCESS_BEGIN(); - - while(1) { - PROCESS_YIELD_UNTIL(ev == tcpip_event); - - try_send: - if (POINTER_TO_INT(data) == TCP_WRITE_EVENT) { - /* We want to send data to peer. */ - struct net_context *context = user_data; - - if (!context) { - continue; - } - - context->connection_status = ip_buf_sent_status(buf); - - do { - context = user_data; - if (!context || !buf) { - break; - } - - if (!context->ps.net_buf || - context->ps.net_buf != buf) { - NET_DBG("psock init %p buf %p\n", - &context->ps, buf); - PSOCK_INIT(&context->ps, buf); - } - - handle_tcp_connection(&context->ps, - POINTER_TO_INT(data), - buf); - - PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); - - if (uip_timedout(buf)) { - break; - } - - if (POINTER_TO_INT(data) != TCP_WRITE_EVENT) { - goto read_data; - } - } while(!(uip_closed(buf) || - uip_aborted(buf) || - uip_timedout(buf))); - - context = user_data; - - if (uip_timedout(buf)) { - ip_buf_sent_status(buf) = -ETIMEDOUT; - if (context) { - context->connection_status = -ETIMEDOUT; - } - continue; - } - - if (context && - context->tcp_type == NET_TCP_TYPE_CLIENT) { - NET_DBG("\nConnection closed.\n"); - ip_buf_sent_status(buf) = -ECONNRESET; - } - - continue; - } else { - if (buf && uip_aborted(buf)) { - struct net_context *context = user_data; - NET_DBG("Connection aborted context %p\n", - user_data); - context->connection_status = -ECONNRESET; - continue; - } - - if (buf && uip_connected(buf)) { - struct net_context *context = user_data; - NET_DBG("Connection established context %p\n", - user_data); - context->connection_status = -EALREADY; - data = INT_TO_POINTER(TCP_WRITE_EVENT); - goto try_send; - } - } - - read_data: - /* We are receiving data from peer. */ - if (buf && uip_newdata(buf)) { - struct net_buf *clone; - - if (!uip_len(buf)) { - continue; - } - - /* Note that uIP stack will reuse the buffer when - * sending ACK to peer host. The sending will happen - * right after this function returns. Because of this - * we cannot use the same buffer to pass data to - * application. - */ - clone = net_buf_clone(buf); - if (!clone) { - NET_ERR("No enough RX buffers, " - "packet %p discarded\n", buf); - continue; - } - - ip_buf_appdata(clone) = uip_buf(clone) + - (ip_buf_appdata(buf) - (void *)uip_buf(buf)); - ip_buf_appdatalen(clone) = uip_len(buf); - ip_buf_len(clone) = uip_len(buf) + UIP_IPTCPH_LEN + UIP_LLH_LEN; - ip_buf_context(clone) = user_data; - if (!ip_buf_context(buf)) { - ip_buf_context(buf) = user_data; - } - uip_set_conn(clone) = uip_conn(buf); - uip_flags(clone) = uip_flags(buf); - uip_flags(clone) |= UIP_CONNECTED; - - NET_DBG("packet received context %p buf %p len %d " - "appdata %p appdatalen %d\n", - ip_buf_context(clone), - clone, - ip_buf_len(clone), - ip_buf_appdata(clone), - ip_buf_appdatalen(clone)); - - nano_fifo_put(net_context_get_queue(user_data), clone); - - ip_buf_sent_status(buf) = 1; - - /* We let the application to read the data now */ - fiber_yield(); - } - } - - PROCESS_END(); -} - -int net_context_tcp_init(struct net_context *context, - enum net_tcp_type tcp_type) -{ - if (!context || context->tuple.ip_proto != IPPROTO_TCP) { - return -EINVAL; - } - - if (context->receiver_registered) { - return 0; - } - - context->receiver_registered = true; - - if (context->tcp_type == NET_TCP_TYPE_UNKNOWN) { - /* This is the first call to this init func. - * If we are called by net_receive() first, then - * we are working as a server, if net_send() called - * us first, then we are the client. - */ - context->tcp_type = tcp_type; - } else if (context->tcp_type != tcp_type) { - /* This means that we have already selected that we - * are either client or server. Use the context - * value. - */ - return 0; - } - - context->tcp.thread = process_thread_tcp; - - if (context->tcp_type == NET_TCP_TYPE_SERVER) { - context->tcp.name = "TCP server"; - - NET_DBG("Listen to TCP port %d\n", context->tuple.local_port); - tcp_listen(UIP_HTONS(context->tuple.local_port), - &context->tcp); -#if UIP_ACTIVE_OPEN - } else { - context->tcp.name = "TCP client"; - context->connection_status = -EINPROGRESS; - -#ifdef CONFIG_NETWORKING_WITH_IPV6 - NET_DBG("Connecting to "); - PRINT6ADDR((const uip_ipaddr_t *)&context->tuple.remote_addr->in6_addr); - PRINTF(" port %d\n", context->tuple.remote_port); - - tcp_connect((uip_ipaddr_t *) - &context->tuple.remote_addr->in6_addr, - UIP_HTONS(context->tuple.remote_port), - context, &context->tcp); -#else /* CONFIG_NETWORKING_WITH_IPV6 */ - NET_DBG("Connecting to "); - PRINT6ADDR((const uip_ipaddr_t *)&context->tuple.remote_addr->in_addr); - PRINTF(" port %d\n", context->tuple.remote_port); - - tcp_connect((uip_ipaddr_t *) - &context->tuple.remote_addr->in_addr, - UIP_HTONS(context->tuple.remote_port), - context, &context->tcp); -#endif /* CONFIG_NETWORKING_WITH_IPV6 */ -#endif /* UIP_ACTIVE_OPEN */ - } - - context->tcp.next = NULL; - process_start(&context->tcp, NULL, context); - - return 0; -} -#endif /* TCP */ - -void net_context_init(void) -{ - int i; - - nano_sem_init(&contexts_lock); - - memset(contexts, 0, sizeof(contexts)); - - for (i = 0; i < NET_MAX_CONTEXT; i++) { - nano_fifo_init(&contexts[i].rx_queue); - } - - context_sem_give(&contexts_lock); -} - -int net_context_get_receiver_registered(struct net_context *context) -{ - if (!context) { - return -ENOENT; - } - - if (context->receiver_registered) { - return true; - } - - return false; -} - -void net_context_set_receiver_registered(struct net_context *context) -{ - if (!context) { - return; - } - - context->receiver_registered = true; -} - -void net_context_unset_receiver_registered(struct net_context *context) -{ - if (!context) { - return; - } - - context->receiver_registered = false; -} - -int net_context_get_connection_status(struct net_context *context) -{ - if (!context) { - return -ENOENT; - } - -#if !defined(CONFIG_NETWORKING_WITH_TCP) - return 0; -#else - if (context->tuple.ip_proto == IPPROTO_TCP) { - return context->connection_status; - } else { - return 0; - } -#endif -} - -void net_context_set_connection_status(struct net_context *context, - int status) -{ -#if !defined(CONFIG_NETWORKING_WITH_TCP) - return; -#else - if (!context) { - return; - } - - if (context->tuple.ip_proto == IPPROTO_TCP) { - NET_DBG("context %p status %d\n", context, status); - context->connection_status = status; - } -#endif -} - -void *net_context_get_internal_connection(struct net_context *context) -{ -#if !defined(CONFIG_NETWORKING_WITH_TCP) - return NULL; -#else - if (!context) { - return NULL; - } - - if (context->tuple.ip_proto == IPPROTO_TCP) { - return context->conn; - } else { - return NULL; - } -#endif -} - -void net_context_set_internal_connection(struct net_context *context, - void *conn) -{ -#if !defined(CONFIG_NETWORKING_WITH_TCP) - return; -#else - if (!context) { - return; - } - - if (context->tuple.ip_proto == IPPROTO_TCP) { - context->conn = conn; - } -#endif -} - -struct net_context *net_context_find_internal_connection(void *conn) -{ -#if !defined(CONFIG_NETWORKING_WITH_TCP) - return NULL; -#else - int i; - - for (i = 0; i < NET_MAX_CONTEXT; i++) { - if (contexts[i].conn == conn) { - return &contexts[i]; - } - } - - return NULL; -#endif -} - -struct net_buf *net_context_tcp_get_pending(struct net_context *context) -{ -#if !defined(CONFIG_NETWORKING_WITH_TCP) - return NULL; -#else - if (!context) { - return NULL; - } - - return context->pending; -#endif -} - -void net_context_tcp_set_pending(struct net_context *context, - struct net_buf *buf) -{ -#if !defined(CONFIG_NETWORKING_WITH_TCP) - return; -#else - if (!context) { - return; - } - - context->pending = buf; -#endif -} - -void net_context_tcp_set_retry_count(struct net_context *context, - uint8_t count) -{ -#if !defined(CONFIG_NETWORKING_WITH_TCP) - return; -#else - if (!context) { - return; - } - - context->retry_count = count; -#endif -} - -uint8_t net_context_tcp_get_retry_count(struct net_context *context) -{ -#if !defined(CONFIG_NETWORKING_WITH_TCP) - return 0; -#else - if (!context) { - return 0; - } - - return context->retry_count; -#endif -} diff --git a/net/ip/net_core.c b/net/ip/net_core.c deleted file mode 100644 index bf8173b57e93cd682aed824be03384dd43530f53..0000000000000000000000000000000000000000 --- a/net/ip/net_core.c +++ /dev/null @@ -1,1174 +0,0 @@ -/** @file - * @brief Network initialization - * - * Initialize the network IP stack. Create two fibers, one for reading data - * from applications (Tx fiber) and one for reading data from IP stack - * and passing that data to applications (Rx fiber). - */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef CONFIG_NETWORKING_WITH_LOGGING -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include "net_driver_15_4.h" -#include "net_driver_slip.h" -#include "net_driver_ethernet.h" -#include "net_driver_bt.h" - -#include "contiki/os/sys/process.h" -#include "contiki/os/sys/etimer.h" -#include "contiki/os/sys/ctimer.h" -#include "contiki/netstack.h" -#include "contiki/ipv6/uip-ds6.h" -#include "contiki/ip/simple-udp.h" -#include "contiki/os/dev/slip.h" - -#ifdef CONFIG_15_4_BEACON_SUPPORT -#include "contiki/mac/handler-802154.h" -#endif - -#ifdef CONFIG_DHCP -#include "contiki/ip/dhcpc.h" -#endif - -/* Declare some private functions only to be used in this file so the - * prototypes are not found in .h file. - */ -struct nano_fifo *net_context_get_queue(struct net_context *context); -struct simple_udp_connection * - net_context_get_udp_connection(struct net_context *context); -int net_context_get_receiver_registered(struct net_context *context); -void net_context_set_receiver_registered(struct net_context *context); -int net_context_tcp_init(struct net_context *context, enum net_tcp_type); -int net_context_tcp_send(struct net_buf *buf); -void *net_context_get_internal_connection(struct net_context *context); -struct net_buf *net_context_tcp_get_pending(struct net_context *context); -void net_context_tcp_set_pending(struct net_context *context, - struct net_buf *buf); -void net_context_set_connection_status(struct net_context *context, - int status); -void net_context_unset_receiver_registered(struct net_context *context); -extern void net_context_tcp_set_retry_count(struct net_context *context, - uint8_t count); -extern uint8_t net_context_tcp_get_retry_count(struct net_context *context); - -/* Stacks for the tx & rx fibers. - * FIXME: stack size needs fine-tuning - */ -#define STACKSIZE_UNIT 1024 -#ifndef CONFIG_IP_RX_STACK_SIZE -#define CONFIG_IP_RX_STACK_SIZE (STACKSIZE_UNIT * 1) -#endif -#ifndef CONFIG_IP_TX_STACK_SIZE -#define CONFIG_IP_TX_STACK_SIZE (STACKSIZE_UNIT * 1) -#endif -#ifndef CONFIG_IP_TIMER_STACK_SIZE -#define CONFIG_IP_TIMER_STACK_SIZE (STACKSIZE_UNIT * 3 / 2) -#endif -static char __noinit __stack rx_fiber_stack[CONFIG_IP_RX_STACK_SIZE]; -static char __noinit __stack tx_fiber_stack[CONFIG_IP_TX_STACK_SIZE]; -static char __noinit __stack timer_fiber_stack[CONFIG_IP_TIMER_STACK_SIZE]; -static nano_thread_id_t timer_fiber_id, tx_fiber_id; - -static uint8_t initialized; - -static struct net_dev { - /* Queue for incoming packets from driver */ - struct nano_fifo rx_queue; - - /* Queue for outgoing packets from apps */ - struct nano_fifo tx_queue; - - /* Registered network driver */ - struct net_driver *drv; -} netdev; - -/* Called by application to send a packet */ -int net_send(struct net_buf *buf) -{ - int ret = 0; - - if (!buf || ip_buf_len(buf) == 0) { - return -ENODATA; - } - - if (buf->len && !uip_appdatalen(buf)) { - uip_appdatalen(buf) = ip_buf_appdatalen(buf); - } - - switch (sys_execution_context_type_get()) { - case NANO_CTX_ISR: - break; - case NANO_CTX_FIBER: - fiber_yield(); - break; - case NANO_CTX_TASK: -#ifdef CONFIG_MICROKERNEL - task_yield(); -#endif - break; - } - -#ifdef CONFIG_NETWORKING_WITH_TCP -#define MAX_TCP_RETRY_COUNT 3 - if (ip_buf_context(buf) && - net_context_get_tuple(ip_buf_context(buf))->ip_proto == - IPPROTO_TCP) { - struct uip_conn *conn; - int status; - uint8_t retry_count; - - net_context_tcp_init(ip_buf_context(buf), NET_TCP_TYPE_CLIENT); - - status = net_context_get_connection_status( - ip_buf_context(buf)); - NET_DBG("context %p buf %p status %d\n", - ip_buf_context(buf), buf, status); - - switch (status) { - case EISCONN: - /* User should be able to send new data now. */ - NET_DBG("Send new data buf %p ref %d\n", buf, buf->ref); - net_context_set_connection_status(ip_buf_context(buf), - 0); - conn = (struct uip_conn *)net_context_get_internal_connection(ip_buf_context(buf)); - if (conn->buf) { - ip_buf_unref(conn->buf); - - if (conn->buf == buf) { - conn->buf = NULL; - return 0; - } - - conn->buf = NULL; - } - break; - - case -EALREADY: - NET_DBG("Connection established\n"); - return 0; - - case -EINPROGRESS: - NET_DBG("Connection being established\n"); - retry_count = net_context_tcp_get_retry_count( - ip_buf_context(buf)); - if (retry_count < MAX_TCP_RETRY_COUNT) { - net_context_tcp_set_retry_count( - ip_buf_context(buf), ++retry_count); - return status; - } - net_context_tcp_set_retry_count(ip_buf_context(buf), - 0); - break; - - case -ECONNRESET: - NET_DBG("Connection reset\n"); - net_context_unset_receiver_registered( - ip_buf_context(buf)); - return status; - } - - ret = status; - } -#endif - - nano_fifo_put(&netdev.tx_queue, buf); - - /* Tell the IP stack it can proceed with the packet */ - fiber_wakeup(tx_fiber_id); - - return ret; -} - -#ifdef CONFIG_NETWORKING_STATISTICS -#define STAT(s) uip_stat.s -#define PRINT_STATISTICS_INTERVAL (10 * sys_clock_ticks_per_sec) -#define net_print_statistics stats /* to make the debug print line shorter */ - -#if NET_MAC_CONF_STATS -#include "mac/mac.h" -#endif - -#if RPL_CONF_STATS -#include "rpl/rpl-private.h" -#endif - -#if NET_COAP_CONF_STATS -#include "er-coap/er-coap.h" -#endif - -#if HANDLER_802154_CONF_STATS -#include "mac/handler-802154.h" -#endif - -static void stats(void) -{ - static clock_time_t last_print; - - /* See contiki/ip/uip.h for descriptions of the different values */ - if (clock_time() > (last_print + PRINT_STATISTICS_INTERVAL)) { -#if NET_MAC_CONF_STATS -#define MAC_STAT(s) (net_mac_stats.s) - NET_DBG("L2 bytes recv %d\tsent\t%d\n", - MAC_STAT(bytes_received), - MAC_STAT(bytes_sent)); -#endif - NET_DBG("IP recv %d\tsent\t%d\tdrop\t%d\tforwarded\t%d\n", - STAT(ip.recv), - STAT(ip.sent), - STAT(ip.drop), - STAT(ip.forwarded)); - NET_DBG("IP vhlerr %d\thblener\t%d\tlblener\t%d\n", - STAT(ip.vhlerr), - STAT(ip.hblenerr), - STAT(ip.lblenerr)); - NET_DBG("IP fragerr %d\tchkerr\t%d\tprotoer\t%d\n", - STAT(ip.fragerr), - STAT(ip.chkerr), - STAT(ip.protoerr)); - -#ifdef CONFIG_NETWORKING_WITH_TCP - NET_DBG("TCP recv %d\tsent\t%d\tdrop\t%d\n", - STAT(tcp.recv), - STAT(tcp.sent), - STAT(tcp.drop)); - NET_DBG("TCP chkerr %d\tackerr\t%d\trst\t%d\n", - STAT(tcp.chkerr), - STAT(tcp.ackerr), - STAT(tcp.rst)); - NET_DBG("TCP rexmit %d\tsyndrop\t%d\tsynrst\t%d\n", - STAT(tcp.rexmit), - STAT(tcp.syndrop), - STAT(tcp.synrst)); -#endif - - NET_DBG("ICMP recv %d\tsent\t%d\tdrop\t%d\n", - STAT(icmp.recv), - STAT(icmp.sent), - STAT(icmp.drop)); - NET_DBG("ICMP typeer %d\tchkerr\t%d\n", - STAT(icmp.typeerr), - STAT(icmp.chkerr)); - - NET_DBG("UDP recv %d\tsent\t%d\tdrop\t%d\n", - STAT(udp.recv), - STAT(udp.sent), - STAT(udp.drop)); - NET_DBG("UDP chkerr %d\n", - STAT(icmp.chkerr)); - -#if NET_COAP_CONF_STATS - NET_DBG("CoAP recv %d\terr\t%d\tsent\t%d\tre-sent\t%d\n", - NET_COAP_STAT(recv), - NET_COAP_STAT(recv_err), - NET_COAP_STAT(sent), - NET_COAP_STAT(re_sent)); -#endif - -#if NETSTACK_CONF_WITH_IPV6 - NET_DBG("ND recv %d\tsent\t%d\tdrop\t%d\n", - STAT(nd6.recv), - STAT(nd6.sent), - STAT(nd6.drop)); -#endif - -#if RPL_CONF_STATS -#define RSTAT(s) RPL_STAT(rpl_stats.s) - NET_DBG("RPL overflows %d\tl-repairs\t%d\tg-repairs\t%d\n", - RSTAT(mem_overflows), - RSTAT(local_repairs), - RSTAT(global_repairs)); - NET_DBG("RPL malformed %d\tresets \t%d\tp-switch\t%d\n", - RSTAT(malformed_msgs), - RSTAT(resets), - RSTAT(parent_switch)); - NET_DBG("RPL f-errors %d\tl-errors\t%d\tl-warnings\t%d\n", - RSTAT(forward_errors), - RSTAT(loop_errors), - RSTAT(loop_warnings)); - NET_DBG("RPL r-repairs %d\n", - RSTAT(root_repairs)); -#endif - -#if HANDLER_802154_CONF_STATS -#define IEEE802154_STAT(s) (handler_802154_stats.s) - NET_DBG("802.15.4 beacons recv\t%d\tsent\t%d\treqs sent\t%d\n", - IEEE802154_STAT(beacons_received), - IEEE802154_STAT(beacons_sent), - IEEE802154_STAT(beacons_reqs_sent)); -#endif - last_print = clock_time(); - } -} -#else -#define net_print_statistics() -#endif - -/* Switch the ports and addresses and set route and neighbor cache. - * Returns 1 if packet was sent properly, in this case it is the caller - * that needs to release the net_buf. If 0 is returned, then uIP stack - * has released the net_buf already because there was an some net related - * error when sending the buffer. - */ -static inline int udp_prepare_and_send(struct net_context *context, - struct net_buf *buf) -{ -#ifdef CONFIG_NETWORKING_IPV6_NO_ND - uip_ds6_route_t *route_old, *route_new = NULL; - uip_ds6_nbr_t *nbr; -#endif - uip_ipaddr_t tmp; - uint16_t port; - uint8_t ret; - - if (uip_len(buf) == 0) { - /* This is expected as uIP will typically set the - * packet length to 0 after receiving it. So we need - * to fix the length here. The protocol specific - * part is added also here. - */ - uip_len(buf) = ip_buf_len(buf); - } - - ip_buf_appdata(buf) = &uip_buf(buf)[UIP_IPUDPH_LEN + UIP_LLH_LEN]; - - port = NET_BUF_UDP(buf)->srcport; - NET_BUF_UDP(buf)->srcport = NET_BUF_UDP(buf)->destport; - NET_BUF_UDP(buf)->destport = port; - - uip_ipaddr_copy(&tmp, &NET_BUF_IP(buf)->srcipaddr); - uip_ipaddr_copy(&NET_BUF_IP(buf)->srcipaddr, - &NET_BUF_IP(buf)->destipaddr); - uip_ipaddr_copy(&NET_BUF_IP(buf)->destipaddr, &tmp); - -#ifdef CONFIG_NETWORKING_IPV6_NO_ND - /* The peer needs to be in neighbor cache before route can be added. - */ - nbr = uip_ds6_nbr_lookup((uip_ipaddr_t *)&NET_BUF_IP(buf)->destipaddr); - if (!nbr) { - const uip_lladdr_t *lladdr = - (const uip_lladdr_t *)&ip_buf_ll_src(buf); - nbr = uip_ds6_nbr_add( - (uip_ipaddr_t *)&NET_BUF_IP(buf)->destipaddr, - lladdr, 0, NBR_REACHABLE); - if (!nbr) { - NET_DBG("Cannot add peer "); - PRINT6ADDR(&NET_BUF_IP(buf)->destipaddr); - PRINT(" to neighbor cache\n"); - } - } - - /* Temporarily add route to peer, delete the route after - * sending the packet. Check if there was already a - * route and do not remove it if there was existing - * route to this peer. - */ - route_old = uip_ds6_route_lookup(&NET_BUF_IP(buf)->destipaddr); - if (!route_old) { - route_new = uip_ds6_route_add(&NET_BUF_IP(buf)->destipaddr, - 128, - &NET_BUF_IP(buf)->destipaddr); - if (!route_new) { - NET_DBG("Cannot add route to peer "); - PRINT6ADDR(&NET_BUF_IP(buf)->destipaddr); - PRINT("\n"); - } - } -#endif - - ret = simple_udp_sendto_port(buf, - net_context_get_udp_connection(context), - ip_buf_appdata(buf), - ip_buf_appdatalen(buf), - &NET_BUF_IP(buf)->destipaddr, - uip_ntohs(NET_BUF_UDP(buf)->destport)); - if (ret <= 0) { - ret = -EINVAL; - NET_DBG("Packet could not be sent properly.\n"); - } else { - ret = 0; - } - -#ifdef CONFIG_NETWORKING_IPV6_NO_ND - if (!route_old && route_new) { - /* This will also remove the neighbor cache entry */ - uip_ds6_route_rm(route_new); - } -#endif - - return ret; -} - -#ifdef CONFIG_NETWORKING_WITH_TCP -/* Switch the ports and addresses. Returns 1 if packet was sent properly, - * in this case it is the caller that needs to release the net_buf. - * If 0 is returned, then uIP stack has released the net_buf already - * because there was an some net related error when sending the buffer. - */ -static inline int tcp_prepare_and_send(struct net_context *context, - struct net_buf *buf) -{ -#ifdef CONFIG_NETWORKING_IPV6_NO_ND - uip_ds6_route_t *route_old, *route_new = NULL; - uip_ds6_nbr_t *nbr; -#endif - uip_ipaddr_t tmp; - uint16_t port; - int ret; - - uip_len(buf) = uip_slen(buf) = ip_buf_len(buf); - uip_flags(buf) |= UIP_NEWDATA; - port = NET_BUF_UDP(buf)->srcport; - NET_BUF_UDP(buf)->srcport = NET_BUF_UDP(buf)->destport; - NET_BUF_UDP(buf)->destport = port; - - uip_ipaddr_copy(&tmp, &NET_BUF_IP(buf)->srcipaddr); - uip_ipaddr_copy(&NET_BUF_IP(buf)->srcipaddr, - &NET_BUF_IP(buf)->destipaddr); - uip_ipaddr_copy(&NET_BUF_IP(buf)->destipaddr, &tmp); - -#ifdef CONFIG_NETWORKING_IPV6_NO_ND - /* The peer needs to be in neighbor cache before route can be added. - */ - nbr = uip_ds6_nbr_lookup((uip_ipaddr_t *)&NET_BUF_IP(buf)->destipaddr); - if (!nbr) { - const uip_lladdr_t *lladdr = - (const uip_lladdr_t *)&ip_buf_ll_src(buf); - nbr = uip_ds6_nbr_add( - (uip_ipaddr_t *)&NET_BUF_IP(buf)->destipaddr, - lladdr, 0, NBR_REACHABLE); - if (!nbr) { - NET_DBG("Cannot add peer "); - PRINT6ADDR(&NET_BUF_IP(buf)->destipaddr); - PRINT(" to neighbor cache\n"); - } - } - - /* Temporarily add route to peer, delete the route after - * sending the packet. Check if there was already a - * route and do not remove it if there was existing - * route to this peer. - */ - route_old = uip_ds6_route_lookup(&NET_BUF_IP(buf)->destipaddr); - if (!route_old) { - route_new = uip_ds6_route_add(&NET_BUF_IP(buf)->destipaddr, - 128, - &NET_BUF_IP(buf)->destipaddr); - if (!route_new) { - NET_DBG("Cannot add route to peer "); - PRINT6ADDR(&NET_BUF_IP(buf)->destipaddr); - PRINT("\n"); - } - } -#endif - - NET_DBG("Packet output len %d\n", uip_len(buf)); - - ret = net_context_tcp_send(buf); - if (ret < 0 && ret != -EAGAIN) { - NET_DBG("Packet could not be sent properly (err %d)\n", ret); - } - ip_buf_sent_status(buf) = 0; - -#ifdef CONFIG_NETWORKING_IPV6_NO_ND - if (!route_old && route_new) { - /* This will also remove the neighbor cache entry */ - uip_ds6_route_rm(route_new); - } -#endif - - return ret; -} -#endif - -/* Application wants to send a reply */ -int net_reply(struct net_context *context, struct net_buf *buf) -{ - struct net_tuple *tuple; - struct uip_udp_conn *udp; - int ret = 0; - - if (!context || !buf) { - return -EINVAL; - } - - tuple = net_context_get_tuple(context); - if (!tuple) { - return -ENOENT; - } - - switch (sys_execution_context_type_get()) { - case NANO_CTX_ISR: - break; - case NANO_CTX_FIBER: - fiber_yield(); - break; - case NANO_CTX_TASK: -#ifdef CONFIG_MICROKERNEL - task_yield(); -#endif - break; - } - - switch (tuple->ip_proto) { - case IPPROTO_UDP: - udp = uip_udp_conn(buf); - if (!udp) { - NET_ERR("UDP connection missing\n"); - return -ESRCH; - } - - ret = udp_prepare_and_send(context, buf); - break; - case IPPROTO_TCP: -#ifdef CONFIG_NETWORKING_WITH_TCP - ret = tcp_prepare_and_send(context, buf); -#else - NET_DBG("TCP not supported\n"); - return -EINVAL; -#endif - break; - case IPPROTO_ICMPV6: - NET_DBG("ICMPv6 not yet supported\n"); - return -EINVAL; - } - - return ret; -} - -/* Called by driver when an IP packet has been received */ -int net_recv(struct net_buf *buf) -{ - if (ip_buf_len(buf) == 0) { - return -ENODATA; - } - - nano_fifo_put(&netdev.rx_queue, buf); - - return 0; -} - -static void udp_packet_receive(struct simple_udp_connection *c, - const uip_ipaddr_t *source_addr, - uint16_t source_port, - const uip_ipaddr_t *dest_addr, - uint16_t dest_port, - const uint8_t *data, uint16_t datalen, - void *user_data, - struct net_buf *buf) -{ - struct net_context *context = user_data; - - if (!context) { - /* If the context is not there, then we must discard - * the buffer here, otherwise we have a buffer leak. - */ - ip_buf_unref(buf); - return; - } - - ip_buf_appdatalen(buf) = datalen; - ip_buf_appdata(buf) = &uip_buf(buf)[UIP_IPUDPH_LEN + UIP_LLH_LEN]; - ip_buf_len(buf) = datalen + UIP_IPUDPH_LEN + UIP_LLH_LEN; - - NET_DBG("packet received context %p len %d " - "appdata %p appdatalen %d\n", - context, ip_buf_len(buf), - ip_buf_appdata(buf), ip_buf_appdatalen(buf)); - - nano_fifo_put(net_context_get_queue(context), buf); -} - -#ifdef CONFIG_NANO_TIMEOUTS -static inline struct net_buf *buf_wait_timeout(struct nano_fifo *queue, - int32_t timeout) -{ - switch (sys_execution_context_type_get()) { - case NANO_CTX_FIBER: - return nano_fiber_fifo_get(queue, timeout); - case NANO_CTX_TASK: - return nano_task_fifo_get(queue, timeout); - case NANO_CTX_ISR: - default: - /* Invalid context type */ - break; - } - - return NULL; -} -#endif - -/* Called by application when it wants to receive network data */ -struct net_buf *net_receive(struct net_context *context, int32_t timeout) -{ - struct nano_fifo *rx_queue = net_context_get_queue(context); - struct net_buf *buf; - struct net_tuple *tuple; - int ret = 0; - uint16_t reserve = 0; - - tuple = net_context_get_tuple(context); - if (!tuple) { - return NULL; - } - - switch (tuple->ip_proto) { - case IPPROTO_UDP: - if (!net_context_get_receiver_registered(context)) { - struct simple_udp_connection *udp = - net_context_get_udp_connection(context); - - ret = simple_udp_register(udp, tuple->local_port, -#ifdef CONFIG_NETWORKING_WITH_IPV6 - (uip_ip6addr_t *)&tuple->remote_addr->in6_addr, -#else - (uip_ip4addr_t *)&tuple->remote_addr->in_addr, -#endif - tuple->remote_port, - udp_packet_receive, - context); - if (!ret) { - NET_DBG("UDP connection listener failed\n"); - ret = -ENOENT; - break; - } - } - net_context_set_receiver_registered(context); - ret = 0; - reserve = UIP_IPUDPH_LEN + UIP_LLH_LEN; - break; - case IPPROTO_TCP: -#ifdef CONFIG_NETWORKING_WITH_TCP - ret = net_context_tcp_init(context, NET_TCP_TYPE_SERVER); - if (ret) { - NET_DBG("TCP connection init failed\n"); - ret = -ENOENT; - break; - } - ret = 0; -#else - NET_DBG("TCP not supported\n"); - ret = -EINVAL; -#endif - break; - case IPPROTO_ICMPV6: - NET_DBG("ICMPv6 not yet supported\n"); - ret = -EINVAL; - break; - default: - NET_ERR("Invalid IP protocol. " - "Internal data structure corrupted!\n"); - ret = -EINVAL; - break; - } - - if (ret) { - return NULL; - } - - switch (timeout) { - case TICKS_UNLIMITED: - case TICKS_NONE: - buf = net_buf_get_timeout(rx_queue, 0, _ticks_to_ms(timeout)); - break; - default: -#ifdef CONFIG_NANO_TIMEOUTS - buf = buf_wait_timeout(rx_queue, timeout); -#else /* CONFIG_NANO_TIMEOUTS */ - buf = net_buf_get_timeout(rx_queue, 0, TICKS_NONE); -#endif - break; - } - -#ifdef CONFIG_NETWORKING_WITH_TCP - if (tuple->ip_proto == IPPROTO_TCP && - (ip_buf_appdata(buf) > (void *)buf->data)) { - /* We need to skip the TCP header + possible extensions */ - reserve = ip_buf_appdata(buf) - (void *)buf->data; - } -#endif - - if (buf && reserve) { - ip_buf_appdatalen(buf) = ip_buf_len(buf) - reserve; - ip_buf_appdata(buf) = &uip_buf(buf)[reserve]; - } - - return buf; -} - -static void udp_packet_reply(struct simple_udp_connection *c, - const uip_ipaddr_t *source_addr, - uint16_t source_port, - const uip_ipaddr_t *dest_addr, - uint16_t dest_port, - const uint8_t *data, uint16_t datalen, - void *user_data, - struct net_buf *buf) -{ - struct net_context *context = user_data; - struct nano_fifo *queue; - - if (!context) { - /* If the context is not there, then we must discard - * the buffer here, otherwise we have a buffer leak. - */ - ip_buf_unref(buf); - return; - } - - queue = net_context_get_queue(context); - - /* Contiki stack will overwrite the uip_len(buf) and - * uip_appdatalen(buf) values, so in order to allow - * the application to use them, copy the values here. - */ - ip_buf_appdatalen(buf) = datalen; - - NET_DBG("packet reply context %p len %d " - "appdata %p appdatalen %d queue %p\n", - context, ip_buf_len(buf), - ip_buf_appdata(buf), ip_buf_appdatalen(buf), queue); - - nano_fifo_put(queue, buf); -} - -/* Internal function to send network data to uIP stack */ -static int check_and_send_packet(struct net_buf *buf) -{ - struct net_tuple *tuple; - struct simple_udp_connection *udp; - int ret = 0; - - if (!netdev.drv) { - return -EINVAL; - } - - tuple = net_context_get_tuple(ip_buf_context(buf)); - if (!tuple) { - return -EINVAL; - } - - switch (tuple->ip_proto) { - case IPPROTO_UDP: - udp = net_context_get_udp_connection(ip_buf_context(buf)); - if (!net_context_get_receiver_registered(ip_buf_context(buf))) { - ret = simple_udp_register(udp, tuple->local_port, -#ifdef CONFIG_NETWORKING_WITH_IPV6 - (uip_ip6addr_t *)&tuple->remote_addr->in6_addr, -#else - (uip_ip4addr_t *)&tuple->remote_addr->in_addr, -#endif - tuple->remote_port, udp_packet_reply, - ip_buf_context(buf)); - if (!ret) { - NET_DBG("UDP connection creation failed\n"); - ret = -ENOENT; - break; - } - net_context_set_receiver_registered(ip_buf_context(buf)); - } - - if (ip_buf_appdatalen(buf) == 0) { - /* User application has not set the application data - * length. The buffer will be discarded if we do not - * set the value correctly. - */ - uip_appdatalen(buf) = buf->len - - (UIP_IPUDPH_LEN + UIP_LLH_LEN); - } - - ret = simple_udp_send(buf, udp, uip_appdata(buf), - uip_appdatalen(buf)); - break; - case IPPROTO_TCP: -#ifdef CONFIG_NETWORKING_WITH_TCP - if (ip_buf_appdatalen(buf) == 0) { - /* User application has not set the application data - * length. The buffer will be discarded if we do not - * set the value correctly. - */ - uip_appdatalen(buf) = buf->len - - (UIP_IPTCPH_LEN + UIP_LLH_LEN); - } - if (uip_len(buf) == 0) { - uip_len(buf) = buf->len; - } - ret = net_context_tcp_send(buf); - if (ret < 0 && ret != -EAGAIN) { - NET_DBG("Packet could not be sent properly " - "(err %d)\n", ret); - } else if (ret == 0) { - /* For TCP the return status 0 means that the packet - * is released already. The caller of this function - * expects return value of > 0 in this case. - */ - ret = 1; - } else { - ip_buf_sent_status(buf) = ret; - ret = true; /* This will prevent caller to discard - * the buffer that needs to be resent - * again. - */ - } -#else - NET_DBG("TCP not supported\n"); - ret = -EINVAL; -#endif - break; - case IPPROTO_ICMPV6: - NET_DBG("ICMPv6 not yet supported\n"); - ret = -EINVAL; - break; - } - - return ret; -} - -static void net_tx_fiber(void) -{ - NET_DBG("Starting TX fiber (stack %zu bytes)\n", - sizeof(tx_fiber_stack)); - - while (1) { - struct net_buf *buf; - int ret; - - /* Get next packet from application - wait if necessary */ - buf = net_buf_get_timeout(&netdev.tx_queue, 0, TICKS_UNLIMITED); - - NET_DBG("Sending (buf %p, len %u) to IP stack\n", - buf, buf->len); - - /* What to do with the buffer: - * <0: error, release the buffer - * 0: message was discarded by uIP, release the buffer here - * >0: message was sent ok, buffer released already - */ - ret = check_and_send_packet(buf); - if (ret < 0) { - ip_buf_unref(buf); - goto wait_next; - } else if (ret > 0) { - goto wait_next; - } - - NET_BUF_CHECK_IF_NOT_IN_USE(buf); - - /* Check for any events that we might need to process */ - do { - ret = process_run(buf); - } while (ret > 0); - - ip_buf_unref(buf); - - wait_next: - /* Check stack usage (no-op if not enabled) */ - net_analyze_stack("TX fiber", (unsigned char *)tx_fiber_stack, - sizeof(tx_fiber_stack)); - - net_print_statistics(); - } -} - -static void net_rx_fiber(void) -{ - struct net_buf *buf; - - NET_DBG("Starting RX fiber (stack %zu bytes)\n", - sizeof(rx_fiber_stack)); - - while (1) { - buf = net_buf_get_timeout(&netdev.rx_queue, 0, TICKS_UNLIMITED); - - /* Check stack usage (no-op if not enabled) */ - net_analyze_stack("RX fiber", (unsigned char *)rx_fiber_stack, - sizeof(rx_fiber_stack)); - - NET_DBG("Received buf %p\n", buf); - - if (!tcpip_input(buf)) { - ip_buf_unref(buf); - } - /* The buffer is on to its way to receiver at this - * point. We must not remove it here. - */ - - net_print_statistics(); - } -} - -/* - * Run various Contiki timers. - */ -#define MAX_TIMER_WAKEUP 0x7ffffff - -static void net_timer_fiber(void) -{ - clock_time_t next_wakeup; - - NET_DBG("Starting net timer fiber (stack %zu bytes)\n", - sizeof(timer_fiber_stack)); - - while (1) { - /* Run various timers */ - next_wakeup = etimer_request_poll(); - - if (next_wakeup == 0) { - /* There was no timers, wait again */ - next_wakeup = MAX_TIMER_WAKEUP; - } else { - if (next_wakeup > MAX_TIMER_WAKEUP) { - next_wakeup = MAX_TIMER_WAKEUP; - } - -#ifdef CONFIG_INIT_STACKS - { -#define PRINT_CYCLE (60 * sys_clock_ticks_per_sec) - - static uint32_t next_print; - uint32_t curr = sys_tick_get_32(); - - /* Print stack usage every n. sec */ - if (!next_print || - (next_print < curr && - (!((curr - next_print) > PRINT_CYCLE)))) { - uint32_t new_print; - - net_analyze_stack("timer fiber", - (unsigned char *)timer_fiber_stack, - sizeof(timer_fiber_stack)); - new_print = curr + PRINT_CYCLE; - if (new_print > curr) { - next_print = new_print; - } else { - /* Overflow */ - next_print = PRINT_CYCLE - - (0xffffffff - curr); - } - } - } -#endif - } - - fiber_sleep(next_wakeup); - } -} - -static void init_rx_queue(void) -{ - nano_fifo_init(&netdev.rx_queue); - - fiber_start(rx_fiber_stack, sizeof(rx_fiber_stack), - (nano_fiber_entry_t)net_rx_fiber, 0, 0, 7, 0); -} - -static void init_tx_queue(void) -{ - nano_fifo_init(&netdev.tx_queue); - - tx_fiber_id = fiber_start(tx_fiber_stack, sizeof(tx_fiber_stack), - (nano_fiber_entry_t)net_tx_fiber, - 0, 0, 7, 0); -} - -static void init_timer_fiber(void) -{ - timer_fiber_id = fiber_start(timer_fiber_stack, - sizeof(timer_fiber_stack), - (nano_fiber_entry_t)net_timer_fiber, - 0, 0, 7, 0); -} - -void net_timer_check(void) -{ - fiber_wakeup(timer_fiber_id); -} - -int net_set_mac(uint8_t *mac, uint8_t len) -{ - if (!mac) { - NET_ERR("MAC address cannot be NULL\n"); - return -EINVAL; - } - - if ((len > UIP_LLADDR_LEN) || (len != 6 && len != 8)) { - NET_ERR("Wrong ll addr len, len %d, max %d\n", - len, UIP_LLADDR_LEN); - return -EINVAL; - } - - linkaddr_set_node_addr((linkaddr_t *)mac); - NET_DBG("MAC "); PRINTLLADDR((uip_lladdr_t *)&linkaddr_node_addr); PRINTF("\n"); - -#ifdef CONFIG_NETWORKING_WITH_IPV6 - if (!initialized) { - memcpy(&uip_lladdr, mac, len); - } else { - uip_ds6_addr_t *lladdr; - - uip_ds6_set_lladdr((uip_lladdr_t *)mac); - - lladdr = uip_ds6_get_link_local(-1); - - NET_DBG("Tentative link-local IPv6 address "); - PRINT6ADDR(&lladdr->ipaddr); - PRINTF("\n"); - } -#else - memcpy(&uip_lladdr, mac, len); - - NET_DBG("IPv4 address "); - PRINT6ADDR(&uip_hostaddr); - PRINTF("\n"); -#endif - return 0; -} - -static uint8_t net_tcpip_output(struct net_buf *buf, const uip_lladdr_t *lladdr) -{ - int res; - - if (!netdev.drv) { - return 0; - } - - if (lladdr) { - linkaddr_copy(&ip_buf_ll_dest(buf), - (const linkaddr_t *)lladdr); - } else { - linkaddr_copy(&ip_buf_ll_dest(buf), &linkaddr_null); - } - - if (ip_buf_len(buf) == 0) { - return 0; - } - - res = netdev.drv->send(buf); - if (res < 0) { - res = 0; - } - return (uint8_t)res; -} - -static int network_initialization(void) -{ - /* Initialize and start Contiki uIP stack */ - clock_init(); - - rtimer_init(); - ctimer_init(); - - process_init(); - tcpip_set_outputfunc(net_tcpip_output); - - process_start(&tcpip_process, NULL, NULL); - process_start(&simple_udp_process, NULL, NULL); - process_start(&etimer_process, NULL, NULL); - process_start(&ctimer_process, NULL, NULL); - - slip_start(); - -#if CONFIG_15_4_BEACON_SUPPORT && CONFIG_NETWORKING_WITH_15_4_PAN_ID - handler_802154_join(CONFIG_NETWORKING_WITH_15_4_PAN_ID, 1); -#endif - -#ifdef CONFIG_NETWORKING_WITH_15_4_PAN_ID - NETSTACK_RADIO.set_value(RADIO_PARAM_PAN_ID, IEEE802154_PANID); -#endif - -#ifdef CONFIG_DHCP - dhcpc_init(uip_lladdr.addr, sizeof(uip_lladdr.addr)); -#endif - return 0; -} - -int net_register_driver(struct net_driver *drv) -{ - int r; - - if (netdev.drv) { - return -EALREADY; - } - - if (!drv->open || !drv->send) { - return -EINVAL; - } - - r = drv->open(); - if (r < 0) { - return r; - } - - netdev.drv = drv; - - return 0; -} - -void net_unregister_driver(struct net_driver *drv) -{ - netdev.drv = NULL; -} - -int net_init(void) -{ - if (initialized) - return -EALREADY; - - initialized = 1; - -#if UIP_STATISTICS == 1 - memset(&uip_stat, 0, sizeof(uip_stat)); -#endif /* UIP_STATISTICS == 1 */ - - net_context_init(); - - ip_buf_init(); - l2_buf_init(); - - init_tx_queue(); - init_rx_queue(); - init_timer_fiber(); - -#if defined(CONFIG_NETWORKING_WITH_15_4) - net_driver_15_4_init(); -#endif - -#if defined(CONFIG_NETWORKING_WITH_BT) - net_driver_bt_init(); -#endif - - net_driver_slip_init(); - net_driver_ethernet_init(); - - return network_initialization(); -} diff --git a/net/ip/net_driver_15_4.c b/net/ip/net_driver_15_4.c deleted file mode 100644 index 3b99a81bb2ca05cfa32eb24aaaaa77436f3131a1..0000000000000000000000000000000000000000 --- a/net/ip/net_driver_15_4.c +++ /dev/null @@ -1,178 +0,0 @@ -/* net_driver_15_4.c - IP 15.4 driver */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include - -#if defined(CONFIG_STDOUT_CONSOLE) -#include -#define PRINT printf -#else -#include -#define PRINT printk -#endif - -#include "contiki/ip/uip-debug.h" - -#include -#include -#include -#include -#include "contiki/netstack.h" -#include - -#if !defined(CONFIG_NETWORK_IP_STACK_DEBUG_15_4_NET_DRIVER) -#undef NET_DBG -#define NET_DBG(...) -#endif - -/* Stacks for the tx & rx fibers. - * FIXME: stack size needs fine-tuning - */ -#define STACKSIZE_UNIT 1024 - -#ifndef CONFIG_15_4_RX_STACK_SIZE -#define CONFIG_15_4_RX_STACK_SIZE (STACKSIZE_UNIT * 1) -#endif -static char __noinit __stack rx_fiber_stack[CONFIG_15_4_RX_STACK_SIZE]; - -/* Queue for incoming packets from hw driver */ -static struct nano_fifo rx_queue; - -static int net_driver_15_4_open(void) -{ - return 0; -} - -static int net_driver_15_4_send(struct net_buf *buf) -{ -#if defined(CONFIG_NETWORK_IP_STACK_DEBUG_15_4_NET_DRIVER) - int orig_len = ip_buf_len(buf); -#endif - - if (!NETSTACK_COMPRESS.compress(buf)) { - NET_DBG("compression failed\n"); - ip_buf_unref(buf); - return -EINVAL; - } - - NET_DBG("sending %d bytes (original len %d)\n", ip_buf_len(buf), - orig_len); - - if (uip_len(buf) == 0) { - /* It is possible that uIP stack overwrote the len. - * We need to fix this here. - */ - uip_len(buf) = ip_buf_len(buf); - } - - NET_DBG("Sending (%u bytes) to 15.4 stack\n", ip_buf_len(buf)); - - if (!NETSTACK_FRAGMENT.fragment(buf, NULL)) { - /* Release buffer on error */ - ip_buf_unref(buf); - } - - return 1; -} - -static void net_rx_15_4_fiber(void) -{ - struct net_buf *buf; -#if NET_MAC_CONF_STATS - int byte_count; -#endif - - NET_DBG("Starting 15.4 RX fiber (stack %d bytes)\n", - sizeof(rx_fiber_stack)); - - while (1) { - /* Wait next packet from 15.4 stack */ - buf = net_buf_get_timeout(&rx_queue, 0, TICKS_UNLIMITED); - -#if NET_MAC_CONF_STATS - byte_count = uip_pkt_buflen(buf); -#endif - if (!NETSTACK_RDC.input(buf)) { - NET_DBG("802.15.4 RDC input failed, " - "buf %p discarded\n", buf); - l2_buf_unref(buf); - } else { -#if NET_MAC_CONF_STATS - net_mac_stats.bytes_received += byte_count; -#endif - } - - net_analyze_stack("802.15.4 RX", - (unsigned char *)rx_fiber_stack, - sizeof(rx_fiber_stack)); - } -} - -static void init_rx_queue(void) -{ - nano_fifo_init(&rx_queue); - - fiber_start(rx_fiber_stack, sizeof(rx_fiber_stack), - (nano_fiber_entry_t) net_rx_15_4_fiber, 0, 0, 7, 0); -} - -static struct net_driver net_driver_15_4 = { - .head_reserve = 0, - .open = net_driver_15_4_open, - .send = net_driver_15_4_send, -}; - -int net_driver_15_4_init(void) -{ - init_rx_queue(); - - NETSTACK_RADIO.init(); - NETSTACK_RDC.init(); - NETSTACK_MAC.init(); - NETSTACK_COMPRESS.init(); - - net_register_driver(&net_driver_15_4); - - return 0; -} - -int net_driver_15_4_recv(struct net_buf *buf) -{ - if (!uip_uncompressed(buf)) { - if (!NETSTACK_COMPRESS.uncompress(buf)) { - return -EINVAL; - } - } - - if (net_recv(buf) < 0) { - NET_DBG("input to IP stack failed\n"); - return -EINVAL; - } - - return 0; -} - -int net_driver_15_4_recv_from_hw(struct net_buf *buf) -{ - nano_fifo_put(&rx_queue, buf); - return 0; -} diff --git a/net/ip/net_driver_15_4.h b/net/ip/net_driver_15_4.h deleted file mode 100644 index 84656b6422b01845aa22e93f6a61565c35aa0fdf..0000000000000000000000000000000000000000 --- a/net/ip/net_driver_15_4.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -int net_driver_15_4_init(void); -int net_driver_15_4_recv(struct net_buf *buf); -int net_driver_15_4_recv_from_hw(struct net_buf *buf); diff --git a/net/ip/net_driver_bt.c b/net/ip/net_driver_bt.c deleted file mode 100644 index aa1b4c9c05e9c11fa85eae7def91a896ad80da47..0000000000000000000000000000000000000000 --- a/net/ip/net_driver_bt.c +++ /dev/null @@ -1,206 +0,0 @@ -/* net_driver_bt.c - IP Bluetooth LE driver */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include - -#if defined(CONFIG_STDOUT_CONSOLE) -#include -#define PRINT printf -#else -#include -#define PRINT printk -#endif - -#include -#include -#include -#include -#include -#include "contiki/netstack.h" -#include - -#include -#include -#include -#include - -#define L2CAP_IPSP_PSM 0x0023 -#define L2CAP_IPSP_MTU IP_BUF_MAX_DATA - -static inline void memswap(void *dst, const void *src, int len) -{ - int i; - - for (i = 0; i < len; i++) { - ((uint8_t *)dst)[i] = ((uint8_t *)src)[(len - 1) - i]; - } -} - -static void ipsp_connected(struct bt_l2cap_chan *chan) -{ - struct bt_conn_info info; - char src[BT_ADDR_LE_STR_LEN]; - char dst[BT_ADDR_LE_STR_LEN]; - linkaddr_t addr; - - bt_conn_get_info(chan->conn, &info); - - bt_addr_le_to_str(info.le.src, src, sizeof(src)); - bt_addr_le_to_str(info.le.dst, dst, sizeof(dst)); - - NET_DBG("Channel %p Source %s connected to Destination %s\n", chan, - src, dst); - - /* Swap bytes since net_set_mac expect big endian address */ - memswap(addr.u8, info.le.src->a.val, sizeof(addr.u8)); - - net_set_mac(addr.u8, sizeof(addr)); -} - -static void ipsp_disconnected(struct bt_l2cap_chan *chan) -{ - NET_DBG("Channel %p disconnected\n", chan); -} - -static void ipsp_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) -{ - struct bt_conn_info info; - linkaddr_t src; - linkaddr_t dst; - - NET_DBG("Incoming data channel %p len %u\n", chan, ip_buf_len(buf)); - - bt_conn_get_info(chan->conn, &info); - - /* Swap bytes since linkaddr_copy expect big endian address */ - memswap(src.u8, info.le.src->a.val, sizeof(src)); - memswap(dst.u8, info.le.dst->a.val, sizeof(dst)); - - /* Add MAC addresses to the buffer */ - linkaddr_copy(&ip_buf_ll_dest(buf), &src); - linkaddr_copy(&ip_buf_ll_src(buf), &dst); - - /* Initialize uip_len */ - uip_len(buf) = ip_buf_len(buf); - uip_first_frag_len(buf) = 0; - - /* Uncompress data */ - if (!NETSTACK_COMPRESS.uncompress(buf)) { - NET_ERR("uncompression failed\n"); - return; - } - - /* net_recv takes ownership of the buffer */ - net_buf_ref(buf); - - /* Add buffer to rx_queue */ - if (net_recv(buf) < 0) { - NET_ERR("input to IP stack failed\n"); - net_buf_unref(buf); - return; - } -} - -static struct net_buf *ipsp_alloc_buf(struct bt_l2cap_chan *chan) -{ - NET_DBG("Channel %p requires buffer\n", chan); - - return ip_buf_get_reserve_rx(0); -} - -static struct bt_l2cap_chan_ops ipsp_ops = { - .alloc_buf = ipsp_alloc_buf, - .recv = ipsp_recv, - .connected = ipsp_connected, - .disconnected = ipsp_disconnected, -}; - -static struct bt_l2cap_le_chan ipsp_chan = { - .chan.ops = &ipsp_ops, - .rx.mtu = L2CAP_IPSP_MTU, -}; - -static int ipsp_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) -{ - NET_DBG("Incoming conn %p\n", conn); - - if (ipsp_chan.chan.conn) { - NET_ERR("No channels available"); - return -ENOMEM; - } - - *chan = &ipsp_chan.chan; - - return 0; -} - -static struct bt_l2cap_server server = { - .psm = L2CAP_IPSP_PSM, - .accept = ipsp_accept, -}; - -static struct bt_gatt_attr attrs[] = { - /* IPSS Service Declaration */ - BT_GATT_PRIMARY_SERVICE(BT_UUID_IPSS), -}; - -static int net_driver_bt_open(void) -{ - bt_gatt_register(attrs, ARRAY_SIZE(attrs)); - - bt_l2cap_server_register(&server); - - return 0; -} - -static int net_driver_bt_send(struct net_buf *buf) -{ -#ifdef CONFIG_NETWORKING_WITH_LOGGING - int orig_len = ip_buf_len(buf); -#endif - - if (!NETSTACK_COMPRESS.compress(buf)) { - NET_DBG("compression failed\n"); - ip_buf_unref(buf); - return -EINVAL; - } - - NET_DBG("sending %d bytes (original len %d)\n", ip_buf_len(buf), - orig_len); - - return bt_l2cap_chan_send(&ipsp_chan.chan, buf); -} - -static struct net_driver net_driver_bt = { - .head_reserve = 0, - .open = net_driver_bt_open, - .send = net_driver_bt_send, -}; - -int net_driver_bt_init(void) -{ - NETSTACK_COMPRESS.init(); - - net_register_driver(&net_driver_bt); - - return 0; -} diff --git a/net/ip/net_driver_bt.h b/net/ip/net_driver_bt.h deleted file mode 100644 index bf9f4885d7ac9ad3f98caa413958da256324b3ed..0000000000000000000000000000000000000000 --- a/net/ip/net_driver_bt.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -int net_driver_bt_init(void); diff --git a/net/ip/net_driver_ethernet.c b/net/ip/net_driver_ethernet.c deleted file mode 100644 index c6391fb1d979446da5124edfddc691e2ef277372..0000000000000000000000000000000000000000 --- a/net/ip/net_driver_ethernet.c +++ /dev/null @@ -1,154 +0,0 @@ -/* net_driver_ethernet.c - Ethernet driver */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include - -#if defined(CONFIG_STDOUT_CONSOLE) -#include -#define PRINT printf -#else -#include -#define PRINT printk -#endif - -#include -#include "net_driver_ethernet.h" - -#include "contiki/ipv4/uip_arp.h" - -static bool opened; - -static ethernet_tx_callback tx_cb; - -void net_driver_ethernet_register_tx(ethernet_tx_callback cb) -{ - tx_cb = cb; -} - -static int net_driver_ethernet_open(void) -{ - NET_DBG("Initialized Ethernet driver\n"); - - opened = true; - - return 0; -} - -bool net_driver_ethernet_is_opened(void) -{ - return opened; -} - -static int net_driver_ethernet_send(struct net_buf *buf) -{ -#ifdef CONFIG_NETWORKING_WITH_IPV6 - struct uip_eth_hdr *eth_hdr = (struct uip_eth_hdr *)uip_buf(buf); -#endif - int res; - - NET_DBG("Sending %d bytes\n", buf->len); - - if (!tx_cb) { - NET_ERR("Ethernet transmit callback is uninitialized.\n"); - return -1; - } - -#ifdef CONFIG_NETWORKING_WITH_IPV4 - /* Note that uip_arp_out overwrites the outgoing packet if it needs to - * send an ARP request. It relies on higher layers to resend the - * original packet if necessary. - */ - uip_arp_out(buf); -#else - memcpy(eth_hdr->dest.addr, ip_buf_ll_dest(buf).u8, UIP_LLADDR_LEN); - memcpy(eth_hdr->src.addr, uip_lladdr.addr, UIP_LLADDR_LEN); - eth_hdr->type = UIP_HTONS(UIP_ETHTYPE_IPV6); - uip_len(buf) += sizeof(struct uip_eth_hdr); -#endif - - res = tx_cb(buf); - if (res == 1) { - /* Release the buffer because we sent all the data - * successfully. - */ - ip_buf_unref(buf); - } - - return res; -} - -void net_driver_ethernet_recv(struct net_buf *buf) -{ - struct uip_eth_hdr *eth_hdr = (struct uip_eth_hdr *)uip_buf(buf); - -#ifdef CONFIG_NETWORKING_WITH_IPV4 - if (eth_hdr->type == uip_htons(UIP_ETHTYPE_ARP)) { - uip_arp_arpin(buf); - - /* If uip_arp_arpin needs to send an ARP response, it - * overwrites the contents of buf and updates its - * length variable. Otherwise, it zeroes out the - * length variable. - */ - if (uip_len(buf) == 0) { - ip_buf_unref(buf); - return; - } - - if (!tx_cb) { - NET_ERR("Ethernet transmit callback is uninitialized.\n"); - ip_buf_unref(buf); - return; - } - - if (tx_cb(buf) != 1) { - NET_ERR("Failed to send ARP response.\n"); - } - - ip_buf_unref(buf); - } else -#endif - if (eth_hdr->type == uip_htons(UIP_ETHTYPE_IP) || - eth_hdr->type == uip_htons(UIP_ETHTYPE_IPV6)) { - if (net_recv(buf) != 0) { - NET_ERR("Unexpected return value from net_recv.\n"); - ip_buf_unref(buf); - } - } else { - NET_DBG("Dropping unknown ethertype %x\n", - uip_ntohs(eth_hdr->type)); - ip_buf_unref(buf); - } -} - -static struct net_driver net_driver_ethernet = { - .head_reserve = 0, - .open = net_driver_ethernet_open, - .send = net_driver_ethernet_send, -}; - -int net_driver_ethernet_init(void) -{ - net_register_driver(&net_driver_ethernet); - - return 0; -} diff --git a/net/ip/net_driver_ethernet.h b/net/ip/net_driver_ethernet.h deleted file mode 100644 index 2a3dcfb8484b369825a0a900f520586b47738f79..0000000000000000000000000000000000000000 --- a/net/ip/net_driver_ethernet.h +++ /dev/null @@ -1,16 +0,0 @@ -#include - -#ifdef CONFIG_ETHERNET - -typedef int (*ethernet_tx_callback)(struct net_buf *buf); -void net_driver_ethernet_register_tx(ethernet_tx_callback cb); -bool net_driver_ethernet_is_opened(void); -void net_driver_ethernet_recv(struct net_buf *buf); - -int net_driver_ethernet_init(void); - -#else - -#define net_driver_ethernet_init() - -#endif diff --git a/net/ip/net_driver_loopback.c b/net/ip/net_driver_loopback.c deleted file mode 100644 index a5b1edfd46eb1a9432bf0fd79d867263721a8275..0000000000000000000000000000000000000000 --- a/net/ip/net_driver_loopback.c +++ /dev/null @@ -1,93 +0,0 @@ -/* net_driver_loopback.c - Loopback driver */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include - -#if defined(CONFIG_STDOUT_CONSOLE) -#include -#define PRINT printf -#else -#include -#define PRINT printk -#endif - -#include "contiki/ip/uip-debug.h" - -#include -#include -#include -#include - -/* The following uIP includes are for testing purposes only. Never - * ever use them in your application. - */ -#include "contiki/ipv6/uip-ds6-route.h" /* to set the route */ -#include "contiki/ipv6/uip-ds6-nbr.h" /* to set the neighbor cache */ - -static int net_driver_loopback_open(void) -{ - const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; - uint8_t eui64[8] = { }; - - net_set_mac(eui64, sizeof(eui64)); - - if (!uip_ds6_addr_add((uip_ipaddr_t *)&in6addr_loopback, 0, - ADDR_MANUAL)) - return -EINVAL; - - if (!uip_ds6_nbr_add((uip_ipaddr_t *)&in6addr_loopback, - &uip_lladdr, 0, NBR_REACHABLE)) { - NET_DBG("Cannot add neighbor cache\n"); - return -EINVAL; - } - - if (!uip_ds6_route_add((uip_ipaddr_t *)&in6addr_loopback, 128, - (uip_ipaddr_t *)&in6addr_loopback)) { - NET_DBG("Cannot add localhost route\n"); - return -EINVAL; - } - - NET_DBG("initialized loopback driver\n"); - - return 0; -} - -static int net_driver_loopback_send(struct net_buf *buf) -{ - NET_DBG("received %d bytes\n", buf->len); - - net_recv(buf); - - return 1; -} - -static struct net_driver net_driver_loopback = { - .head_reserve = 0, - .open = net_driver_loopback_open, - .send = net_driver_loopback_send, -}; - -int net_driver_loopback_init(void) -{ - net_register_driver(&net_driver_loopback); - - return 0; -} diff --git a/net/ip/net_driver_loopback.h b/net/ip/net_driver_loopback.h deleted file mode 100644 index 5263352d2f9df9fb7ec77049c56e8ce33835aad9..0000000000000000000000000000000000000000 --- a/net/ip/net_driver_loopback.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - /** - * @brief Register loopback driver - * - * This routine registers the loopback driver. - * - * @return always 0 - */ - -int net_driver_loopback_init(void); diff --git a/net/ip/net_driver_slip.c b/net/ip/net_driver_slip.c deleted file mode 100644 index 26caf434649922afb46419b7565e910cd3289a0c..0000000000000000000000000000000000000000 --- a/net/ip/net_driver_slip.c +++ /dev/null @@ -1,63 +0,0 @@ -/* net_driver_slip.c - Slip (serial line IP) driver */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include - -#include -#include - -#include "contiki/os/dev/slip.h" - -static int net_driver_slip_open(void) -{ - NET_DBG("Initialized slip driver\n"); - - return 0; -} - -static int net_driver_slip_send(struct net_buf *buf) -{ - NET_DBG("Sending %d bytes, application data %d bytes\n", - ip_buf_len(buf), ip_buf_appdatalen(buf)); - - if (!slip_send(buf)) { - /* Release the buffer because we sent all the data - * successfully. - */ - ip_buf_unref(buf); - return 1; - } - - return 0; -} - -static struct net_driver net_driver_slip = { - .head_reserve = 0, - .open = net_driver_slip_open, - .send = net_driver_slip_send, -}; - -int net_driver_slip_init(void) -{ - net_register_driver(&net_driver_slip); - - return 0; -} diff --git a/net/ip/net_driver_slip.h b/net/ip/net_driver_slip.h deleted file mode 100644 index d891a92aff5d680573445d4a95f05ab1f9c8de57..0000000000000000000000000000000000000000 --- a/net/ip/net_driver_slip.h +++ /dev/null @@ -1,6 +0,0 @@ - -#ifdef CONFIG_NETWORKING_UART -int net_driver_slip_init(void); -#else -#define net_driver_slip_init() -#endif diff --git a/net/ip/rest-engine/rest-constants.h b/net/ip/rest-engine/rest-constants.h deleted file mode 100644 index addc0970b004b3ff809419ec54e9e85bc3ef787b..0000000000000000000000000000000000000000 --- a/net/ip/rest-engine/rest-constants.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Constants for the REST Engine (Erbium). - * \author - * Matthias Kovatsch - */ - -#ifndef REST_CONSTANTS_H_ -#define REST_CONSTANTS_H_ - -/** - * Generic status codes that are mapped to either HTTP or CoAP codes. - */ -struct rest_implementation_status { - const unsigned int OK; /* CONTENT_2_05, OK_200 */ - const unsigned int CREATED; /* CREATED_2_01, CREATED_201 */ - const unsigned int CHANGED; /* CHANGED_2_04, NO_CONTENT_204 */ - const unsigned int DELETED; /* DELETED_2_02, NO_CONTENT_204 */ - const unsigned int NOT_MODIFIED; /* VALID_2_03, NOT_MODIFIED_304 */ - - const unsigned int BAD_REQUEST; /* BAD_REQUEST_4_00, BAD_REQUEST_400 */ - const unsigned int UNAUTHORIZED; /* UNAUTHORIZED_4_01, UNAUTHORIZED_401 */ - const unsigned int BAD_OPTION; /* BAD_OPTION_4_02, BAD_REQUEST_400 */ - const unsigned int FORBIDDEN; /* FORBIDDEN_4_03, FORBIDDEN_403 */ - const unsigned int NOT_FOUND; /* NOT_FOUND_4_04, NOT_FOUND_404 */ - const unsigned int METHOD_NOT_ALLOWED; /* METHOD_NOT_ALLOWED_4_05, METHOD_NOT_ALLOWED_405 */ - const unsigned int NOT_ACCEPTABLE; /* NOT_ACCEPTABLE_4_06, NOT_ACCEPTABLE_406 */ - const unsigned int REQUEST_ENTITY_TOO_LARGE; /* REQUEST_ENTITY_TOO_LARGE_4_13, REQUEST_ENTITY_TOO_LARGE_413 */ - const unsigned int UNSUPPORTED_MEDIA_TYPE; /* UNSUPPORTED_MEDIA_TYPE_4_15, UNSUPPORTED_MEDIA_TYPE_415 */ - - const unsigned int INTERNAL_SERVER_ERROR; /* INTERNAL_SERVER_ERROR_5_00, INTERNAL_SERVER_ERROR_500 */ - const unsigned int NOT_IMPLEMENTED; /* NOT_IMPLEMENTED_5_01, NOT_IMPLEMENTED_501 */ - const unsigned int BAD_GATEWAY; /* BAD_GATEWAY_5_02, BAD_GATEWAY_502 */ - const unsigned int SERVICE_UNAVAILABLE; /* SERVICE_UNAVAILABLE_5_03, SERVICE_UNAVAILABLE_503 */ - const unsigned int GATEWAY_TIMEOUT; /* GATEWAY_TIMEOUT_5_04, GATEWAY_TIMEOUT_504 */ - const unsigned int PROXYING_NOT_SUPPORTED; /* PROXYING_NOT_SUPPORTED_5_05, INTERNAL_SERVER_ERROR_500 */ -}; - -/** - * List of Content-Formats which are Internet Media Types plus encoding. - * TODO This should be a constant enum taken from CoAP for both CoAP and HTTP. - */ -struct rest_implementation_type { - unsigned int TEXT_PLAIN; - unsigned int TEXT_XML; - unsigned int TEXT_CSV; - unsigned int TEXT_HTML; - unsigned int IMAGE_GIF; - unsigned int IMAGE_JPEG; - unsigned int IMAGE_PNG; - unsigned int IMAGE_TIFF; - unsigned int AUDIO_RAW; - unsigned int VIDEO_RAW; - unsigned int APPLICATION_LINK_FORMAT; - unsigned int APPLICATION_XML; - unsigned int APPLICATION_OCTET_STREAM; - unsigned int APPLICATION_RDF_XML; - unsigned int APPLICATION_SOAP_XML; - unsigned int APPLICATION_ATOM_XML; - unsigned int APPLICATION_XMPP_XML; - unsigned int APPLICATION_EXI; - unsigned int APPLICATION_FASTINFOSET; - unsigned int APPLICATION_SOAP_FASTINFOSET; - unsigned int APPLICATION_JSON; - unsigned int APPLICATION_X_OBIX_BINARY; -}; - -/** - * Resource flags for allowed methods and special functionalities. - */ -typedef enum { - NO_FLAGS = 0, - - /* methods to handle */ - METHOD_GET = (1 << 0), - METHOD_POST = (1 << 1), - METHOD_PUT = (1 << 2), - METHOD_DELETE = (1 << 3), - - /* special flags */ - HAS_SUB_RESOURCES = (1 << 4), - IS_SEPARATE = (1 << 5), - IS_OBSERVABLE = (1 << 6), - IS_PERIODIC = (1 << 7) -} rest_resource_flags_t; - -#endif /* REST_CONSTANTS_H_ */ diff --git a/net/ip/rest-engine/rest-engine.c b/net/ip/rest-engine/rest-engine.c deleted file mode 100644 index 785f664ac495fe2c603d0d4ef8b9da20728e7350..0000000000000000000000000000000000000000 --- a/net/ip/rest-engine/rest-engine.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * An abstraction layer for RESTful Web services (Erbium). - * Inspired by RESTful Contiki by Dogan Yazar. - * \author - * Matthias Kovatsch - */ - -#include -#include -#include "contiki.h" -#include "rest-engine.h" - -#if defined(CONFIG_NETWORK_IP_STACK_DEBUG_REST_ENGINE) -#define DEBUG 1 -#endif -#include "contiki/ip/uip-debug.h" - -PROCESS(rest_engine_process, "REST Engine"); -/*---------------------------------------------------------------------------*/ -LIST(restful_services); -LIST(restful_periodic_services); -/* avoid initializing twice */ -static uint8_t initialized = 0; -/*---------------------------------------------------------------------------*/ -/*- REST Engine API ---------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -/** - * \brief Initializes and starts the REST Engine process - * - * This function must be called by server processes before any resources are - * registered through rest_activate_resource(). - */ -void -rest_init_engine(void) -{ - if(initialized) { - PRINTF("REST engine process already running - double initialization?\n"); - return; - } - - initialized = 1; - list_init(restful_services); - - REST.set_service_callback(rest_invoke_restful_service); - - /* Start the RESTful server implementation. */ - REST.init(); - - /*Start REST engine process */ - process_start(&rest_engine_process, NULL, NULL); -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Makes a resource available under the given URI path - * \param resource A pointer to a resource implementation - * \param path The URI path string for this resource - * - * The resource implementation must be imported first using the - * extern keyword. The build system takes care of compiling every - * *.c file in the ./resources/ sub-directory (see example Makefile). - */ -void -rest_activate_resource(resource_t *resource, char *path) -{ - resource->url = path; - list_add(restful_services, resource); - - PRINTF("Activating: %s\n", resource->url); - - /* Only add periodic resources with a periodic_handler and a period > 0. */ - if(resource->flags & IS_PERIODIC && resource->periodic->periodic_handler - && resource->periodic->period) { - PRINTF("Periodic resource: %p (%s)\n", resource->periodic, - resource->periodic->resource->url); - list_add(restful_periodic_services, resource->periodic); - } -} -/*---------------------------------------------------------------------------*/ -/*- Internal API ------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -list_t -rest_get_resources(void) -{ - return restful_services; -} -/*---------------------------------------------------------------------------*/ -int -rest_invoke_restful_service(void *request, void *response, uint8_t *buffer, - uint16_t buffer_size, int32_t *offset) -{ - uint8_t found = 0; - uint8_t allowed = 1; - - resource_t *resource = NULL; - const char *url = NULL; - int url_len; - - for(resource = (resource_t *)list_head(restful_services); - resource; resource = resource->next) { - - /* if the web service handles that kind of requests and urls matches */ - url_len = REST.get_url(request, &url); - if((url_len == strlen(resource->url) - || (url_len > strlen(resource->url) - && (resource->flags & HAS_SUB_RESOURCES) - && url[strlen(resource->url)] == '/')) - && strncmp(resource->url, url, strlen(resource->url)) == 0) { - found = 1; - rest_resource_flags_t method = REST.get_method_type(request); - - PRINTF("/%s, method %u, resource->flags %u\n", resource->url, - (uint16_t)method, resource->flags); - - if((method & METHOD_GET) && resource->get_handler != NULL) { - /* call handler function */ - resource->get_handler(request, response, buffer, buffer_size, offset); - } else if((method & METHOD_POST) && resource->post_handler != NULL) { - /* call handler function */ - resource->post_handler(request, response, buffer, buffer_size, - offset); - } else if((method & METHOD_PUT) && resource->put_handler != NULL) { - /* call handler function */ - resource->put_handler(request, response, buffer, buffer_size, offset); - } else if((method & METHOD_DELETE) && resource->delete_handler != NULL) { - /* call handler function */ - resource->delete_handler(request, response, buffer, buffer_size, - offset); - } else { - allowed = 0; - REST.set_response_status(response, REST.status.METHOD_NOT_ALLOWED); - } - break; - } - } - if(!found) { - REST.set_response_status(response, REST.status.NOT_FOUND); - } else if(allowed) { - /* final handler for special flags */ - if(resource->flags & IS_OBSERVABLE) { - REST.subscription_handler(resource, request, response); - } - } - return found & allowed; -} -/*-----------------------------------------------------------------------------------*/ -PROCESS_THREAD(rest_engine_process, ev, data, buf, user_data) -{ - PROCESS_BEGIN(); - - /* pause to let REST server finish adding resources. */ - PROCESS_PAUSE(); - - /* initialize the PERIODIC_RESOURCE timers, which will be handled by this process. */ - periodic_resource_t *periodic_resource = NULL; - - for(periodic_resource = - (periodic_resource_t *)list_head(restful_periodic_services); - periodic_resource; periodic_resource = periodic_resource->next) { - if(periodic_resource->periodic_handler && periodic_resource->period) { - PRINTF("Periodic: Set timer for /%s to %lu\n", - periodic_resource->resource->url, periodic_resource->period); - etimer_set(&periodic_resource->periodic_timer, - periodic_resource->period, &rest_engine_process); - } - } - while(1) { - PROCESS_WAIT_EVENT(); - - if(ev == PROCESS_EVENT_TIMER) { - for(periodic_resource = - (periodic_resource_t *)list_head(restful_periodic_services); - periodic_resource; periodic_resource = periodic_resource->next) { - if(periodic_resource->period - && etimer_expired(&periodic_resource->periodic_timer)) { - - PRINTF("Periodic: etimer expired for /%s (period: %lu)\n", - periodic_resource->resource->url, periodic_resource->period); - - /* Call the periodic_handler function, which was checked during adding to list. */ - (periodic_resource->periodic_handler)(); - - etimer_reset(&periodic_resource->periodic_timer); - } - } - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/rest-engine/rest-engine.h b/net/ip/rest-engine/rest-engine.h deleted file mode 100644 index 3a2848f58c06d31067d2be04708699d072c97c5d..0000000000000000000000000000000000000000 --- a/net/ip/rest-engine/rest-engine.h +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * An abstraction layer for RESTful Web services (Erbium). - * Inspired by RESTful Contiki by Dogan Yazar. - * \author - * Matthias Kovatsch - */ - -#ifndef REST_ENGINE_H_ -#define REST_ENGINE_H_ - -#include -#include "contiki.h" -#include "contiki-lib.h" -#include "rest-constants.h" - -/* list of valid REST Enigne implementations */ -#define REGISTERED_ENGINE_ERBIUM coap_rest_implementation -#define REGISTERED_ENGINE_HELIUM http_rest_implementation - -/* sanity check for configured implementation */ -#if !defined(REST) || (REST != REGISTERED_ENGINE_ERBIUM && REST != REGISTERED_ENGINE_HELIUM) -#error "Define a valid REST Engine implementation (REST define)!" -#endif - -/* - * The maximum buffer size that is provided for resource responses and must be respected due to the limited IP buffer. - * Larger data must be handled by the resource and will be sent chunk-wise through a TCP stream or CoAP blocks. - */ -#ifndef REST_MAX_CHUNK_SIZE -#define REST_MAX_CHUNK_SIZE 64 -#endif - -#ifndef MIN -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif /* MIN */ - -struct resource_s; -struct periodic_resource_s; - -/* signatures of handler functions */ -typedef void (*restful_handler)(void *request, void *response, - uint8_t *buffer, uint16_t preferred_size, - int32_t *offset); -typedef void (*restful_final_handler)(struct resource_s *resource, - void *request, void *response); -typedef void (*restful_periodic_handler)(void); -typedef void (*restful_response_handler)(void *data, void *response); -typedef void (*restful_trigger_handler)(void); - -/* signature of the rest-engine service function */ -typedef int (*service_callback_t)(void *request, void *response, - uint8_t *buffer, uint16_t preferred_size, - int32_t *offset); - -/* data structure representing a resource in REST */ -struct resource_s { - struct resource_s *next; /* for LIST, points to next resource defined */ - const char *url; /*handled URL */ - rest_resource_flags_t flags; /* handled RESTful methods */ - const char *attributes; /* link-format attributes */ - restful_handler get_handler; /* handler function */ - restful_handler post_handler; /* handler function */ - restful_handler put_handler; /* handler function */ - restful_handler delete_handler; /* handler function */ - union { - struct periodic_resource_s *periodic; /* special data depending on flags */ - restful_trigger_handler trigger; - restful_trigger_handler resume; - }; -}; -typedef struct resource_s resource_t; - -struct periodic_resource_s { - struct periodic_resource_s *next; /* for LIST, points to next resource defined */ - const resource_t *resource; - uint32_t period; - struct etimer periodic_timer; - const restful_periodic_handler periodic_handler; -}; -typedef struct periodic_resource_s periodic_resource_t; - -/* - * Macro to define a RESTful resource. - * Resources are statically defined for the sake of efficiency and better memory management. - */ -#define RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler) \ - resource_t name = { NULL, NULL, NO_FLAGS, attributes, get_handler, post_handler, put_handler, delete_handler, { NULL } } - -#define PARENT_RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler) \ - resource_t name = { NULL, NULL, HAS_SUB_RESOURCES, attributes, get_handler, post_handler, put_handler, delete_handler, { NULL } } - -#define SEPARATE_RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler, resume_handler) \ - resource_t name = { NULL, NULL, IS_SEPARATE, attributes, get_handler, post_handler, put_handler, delete_handler, { .resume = resume_handler } } - -#define EVENT_RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler, event_handler) \ - resource_t name = { NULL, NULL, IS_OBSERVABLE, attributes, get_handler, post_handler, put_handler, delete_handler, { .trigger = event_handler } } - -/* - * Macro to define a periodic resource. - * The corresponding [name]_periodic_handler() function will be called every period. - * For instance polling a sensor and publishing a changed value to subscribed clients would be done there. - * The subscriber list will be maintained by the final_handler rest_subscription_handler() (see rest-mapping header file). - */ -#define PERIODIC_RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler, period, periodic_handler) \ - periodic_resource_t periodic_##name; \ - resource_t name = { NULL, NULL, IS_OBSERVABLE | IS_PERIODIC, attributes, get_handler, post_handler, put_handler, delete_handler, { .periodic = &periodic_##name } }; \ - periodic_resource_t periodic_##name = { NULL, &name, period, { { 0 } }, periodic_handler }; - -struct rest_implementation { - char *name; - - /** Initialize the REST implementation. */ - void (*init)(void); - - /** Register the RESTful service callback at implementation. */ - void (*set_service_callback)(service_callback_t callback); - - /** Get request URI path. */ - int (*get_url)(void *request, const char **url); - - /** Get the method of a request. */ - rest_resource_flags_t (*get_method_type)(void *request); - - /** Set the status code of a response. */ - int (*set_response_status)(void *response, unsigned int code); - - /** Get the content-type of a request. */ - int (*get_header_content_type)(void *request, - unsigned int *content_format); - - /** Set the Content-Type of a response. */ - int (*set_header_content_type)(void *response, - unsigned int content_format); - - /** Get the Accept types of a request. */ - int (*get_header_accept)(void *request, unsigned int *accept); - - /** Get the Length option of a request. */ - int (*get_header_length)(void *request, uint32_t *size); - - /** Set the Length option of a response. */ - int (*set_header_length)(void *response, uint32_t size); - - /** Get the Max-Age option of a request. */ - int (*get_header_max_age)(void *request, uint32_t *age); - - /** Set the Max-Age option of a response. */ - int (*set_header_max_age)(void *response, uint32_t age); - - /** Set the ETag option of a response. */ - int (*set_header_etag)(void *response, const uint8_t *etag, - size_t length); - - /** Get the If-Match option of a request. */ - int (*get_header_if_match)(void *request, const uint8_t **etag); - - /** Get the If-Match option of a request. */ - int (*get_header_if_none_match)(void *request); - - /** Get the Host option of a request. */ - int (*get_header_host)(void *request, const char **host); - - /** Set the location option of a response. */ - int (*set_header_location)(void *response, const char *location); - - /** Get the payload option of a request. */ - int (*get_request_payload)(void *request, const uint8_t **payload); - - /** Set the payload option of a response. */ - int (*set_response_payload)(void *response, const void *payload, - size_t length); - - /** Get the query string of a request. */ - int (*get_query)(void *request, const char **value); - - /** Get the value of a request query key-value pair. */ - int (*get_query_variable)(void *request, const char *name, - const char **value); - - /** Get the value of a request POST key-value pair. */ - int (*get_post_variable)(void *request, const char *name, - const char **value); - - /** Send the payload to all subscribers of the resource at url. */ - void (*notify_subscribers)(resource_t *resource); - - /** The handler for resource subscriptions. */ - restful_final_handler subscription_handler; - - /* REST status codes. */ - const struct rest_implementation_status status; - - /* REST content-types. */ - const struct rest_implementation_type type; -}; - -/* instance of REST implementation */ -extern const struct rest_implementation REST; - -/* - * To be called by HTTP/COAP server as a callback function when a new service request appears. - * This function dispatches the corresponding RESTful service. - */ -int rest_invoke_restful_service(void *request, void *response, - uint8_t *buffer, uint16_t buffer_size, - int32_t *offset); -/*---------------------------------------------------------------------------*/ -/** - * \brief Initializes REST framework and starts the HTTP or CoAP process. - */ -void rest_init_engine(void); -/*---------------------------------------------------------------------------*/ -/** - * - * \brief Resources wanted to be accessible should be activated with the following code. - * \param resource - * A RESTful resource defined through the RESOURCE macros. - * \param path - * The local URI path where to provide the resource. - */ -void rest_activate_resource(resource_t *resource, char *path); -/*---------------------------------------------------------------------------*/ -/** - * \brief Returns the list of registered RESTful resources. - * \return The resource list. - */ -list_t rest_get_resources(void); -/*---------------------------------------------------------------------------*/ - -#endif /*REST_ENGINE_H_ */ diff --git a/net/ip/tinydtls/.gitignore b/net/ip/tinydtls/.gitignore deleted file mode 100644 index 02eb10c9c766516a350c8f9ca70df65da8e086ec..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -*~ -*.[oa] -*.gz -*.cap -*.pcap -Makefile -autom4te.cache/ -config.h -config.log -config.status -configure -dtls_config.h.in -doc/Doxyfile -doc/doxygen.out -doc/html/ -libtinydtls.a -tests/ccm-test -tests/dtls-client -tests/dtls-server -tests/prf-test -TAGS -*.patch -ecc/testecc -ecc/testfield -*.d -*.hex -*.elf -*.map -.project diff --git a/net/ip/tinydtls/LICENSE b/net/ip/tinydtls/LICENSE deleted file mode 100644 index 2588fe259e49fdbc2a3caa49f0c02fcccf8fcb73..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License - -Copyright (c) 2011--2012 Olaf Bergmann - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/net/ip/tinydtls/Makefile.in b/net/ip/tinydtls/Makefile.in deleted file mode 100644 index 1349014c9cdcf40a4d9f265502db14b6dd56a727..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/Makefile.in +++ /dev/null @@ -1,141 +0,0 @@ -# Makefile for tinydtls -# -# Copyright (C) 2011--2014 Olaf Bergmann -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, copy, -# modify, merge, publish, distribute, sublicense, and/or sell copies -# of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# the library's version -VERSION:=@PACKAGE_VERSION@ - -# tools -@SET_MAKE@ -SHELL = /bin/sh -MKDIR = mkdir -ETAGS = @ETAGS@ - -prefix = @prefix@ -exec_prefix = @exec_prefix@ -abs_builddir = @abs_builddir@ -top_builddir = @top_builddir@ -libdir = @libdir@ -includedir = @includedir@/@PACKAGE_NAME@ -package = @PACKAGE_TARNAME@-@PACKAGE_VERSION@ - -install := cp - -# files and flags -SOURCES:= dtls.c crypto.c ccm.c hmac.c netq.c peer.c dtls_time.c session.c -ifneq ("@NDEBUG@", "1") -SOURCES += debug.c -endif -SUB_OBJECTS:=aes/rijndael.o @OPT_OBJS@ -OBJECTS:= $(patsubst %.c, %.o, $(SOURCES)) $(SUB_OBJECTS) -HEADERS:=dtls.h hmac.h debug.h dtls_config.h numeric.h crypto.h global.h ccm.h \ - netq.h t_list.h alert.h prng.h peer.h state.h dtls_time.h session.h \ - tinydtls.h -CFLAGS:=-Wall -pedantic -std=c99 @CFLAGS@ -CPPFLAGS:=@CPPFLAGS@ -DDTLS_CHECK_CONTENTTYPE -SUBDIRS:=tests doc platform-specific sha2 aes ecc -DISTSUBDIRS:=$(SUBDIRS) examples/contiki -DISTDIR=$(top_builddir)/$(package) -FILES:=Makefile.in configure configure.in dtls_config.h.in tinydtls.h.in \ - Makefile.tinydtls $(SOURCES) $(HEADERS) -LIB:=libtinydtls.a -LDFLAGS:=@LIBS@ -ARFLAGS:=cru -doc:=doc - -.PHONY: all dirs clean install dist distclean .gitignore doc TAGS - -ifneq ("@WITH_CONTIKI@", "1") -.SUFFIXES: -.SUFFIXES: .c .o - -all: $(LIB) dirs - -check: - echo DISTDIR: $(DISTDIR) - echo top_builddir: $(top_builddir) - $(MAKE) -C tests check - -dirs: $(SUBDIRS) - for dir in $^; do \ - $(MAKE) -C $$dir ; \ - done - -$(SUB_OBJECTS):: - $(MAKE) -C $(@D) $(@F) - -$(LIB): $(OBJECTS) - $(AR) $(ARFLAGS) $@ $^ - ranlib $@ - -clean: - @rm -f $(PROGRAM) main.o $(LIB) $(OBJECTS) - for dir in $(SUBDIRS); do \ - $(MAKE) -C $$dir clean ; \ - done -else # WITH_CONTIKI -all: - $(MAKE) -C examples/contiki $@ -endif # WITH_CONTIKI - -doc: - $(MAKE) -C doc - -distclean: clean - @rm -rf $(DISTDIR) - @rm -f *~ $(DISTDIR).tar.gz - -dist: $(FILES) $(DISTSUBDIRS) - test -d $(DISTDIR) || mkdir $(DISTDIR) - cp $(FILES) $(DISTDIR) - for dir in $(DISTSUBDIRS); do \ - $(MAKE) -C $$dir dist; \ - done - tar czf $(package).tar.gz $(DISTDIR) - -install: $(LIB) $(HEADERS) $(SUBDIRS) - test -d $(libdir) || mkdir -p $(libdir) - test -d $(includedir) || mkdir -p $(includedir) - $(install) $(LIB) $(libdir)/ - $(install) $(HEADERS) $(includedir)/ - for dir in $(SUBDIRS); do \ - $(MAKE) -C $$dir install="$(install)" includedir=$(includedir) install; \ - done - -TAGS: - $(ETAGS) -o $@.new $(SOURCES) - $(ETAGS) -a -o $@.new $(HEADERS) - mv $@.new $@ - -# files that should be ignored by git -GITIGNOREDS:= core \*~ \*.[oa] \*.gz \*.cap \*.pcap Makefile \ - autom4te.cache/ config.h config.log config.status configure \ - doc/Doxyfile doc/doxygen.out doc/html/ $(LIB) tests/ccm-test \ - tests/dtls-client tests/dtls-server tests/prf-test $(package) \ - $(DISTDIR)/ TAGS \*.patch .gitignore ecc/testecc ecc/testfield \ - \*.d \*.hex \*.elf \*.map obj_\* tinydtls.h dtls_config.h \ - $(addprefix \*., $(notdir $(wildcard ../../platform/*))) \ - .project - -.gitignore: - echo $(GITIGNOREDS) | sed 's/ /\n/g' > $@ diff --git a/net/ip/tinydtls/Makefile.tinydtls b/net/ip/tinydtls/Makefile.tinydtls deleted file mode 100644 index 32b9c87eace4121b9decab79924b6045ac62338e..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/Makefile.tinydtls +++ /dev/null @@ -1,27 +0,0 @@ -# This is a -*- Makefile -*- - -ifeq ($(TARGET), redbee-econotag) -CFLAGS += -DLITTLE_ENDIAN=3412 -DBYTE_ORDER=LITTLE_ENDIAN -endif - -ifeq ($(TARGET), wismote) -CFLAGS += -DLITTLE_ENDIAN=3412 -DBYTE_ORDER=LITTLE_ENDIAN -endif - -ifeq ($(TARGET), exp5438) -CFLAGS += -DLITTLE_ENDIAN=3412 -DBYTE_ORDER=LITTLE_ENDIAN -endif - -CFLAGS += -DDTLSv12 -DWITH_SHA256 -DWITH_DTLS=1 -tinydtls_src = dtls.c crypto.c hmac.c rijndael.c sha2.c ccm.c netq.c dtls_time.c peer.c session.c - -# This adds support for TLS_PSK_WITH_AES_128_CCM_8 -CFLAGS += -DDTLS_PSK=1 - -# This adds support for TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 -CFLAGS += -DDTLS_ECC=1 -tinydtls_src += ecc.c - -# This activates debugging support -# CFLAGS += -DNDEBUG -tinydtls_src += debug.c diff --git a/net/ip/tinydtls/README b/net/ip/tinydtls/README deleted file mode 100644 index a7b6093049a6d1687b146c667fdb1a3972bc31af..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/README +++ /dev/null @@ -1,26 +0,0 @@ -CONTENTS - -This library contains functions and structures that can help -constructing a single-threaded UDP server with DTLS support in -C99. The following components are available: - -* dtls - Basic support for DTLS with pre-shared key mode. - -* tests - The subdirectory tests contains test programs that show how each - component is used. - -BUILDING - -When using the code from the git repository at sourceforge, invoke -'autoreconf' to re-create the configure script. To build for Contiki, -place tinydtls into Contiki's apps directory and call - ./configure --with-contiki. - -After configuration, invoke make to build the library and associated -test programs. To add tinydtls as Contiki application, drop it into -the apps directory and add the following line to your Makefile: - - APPS += tinydtls/aes tinydtls/sha2 tinydtls/ecc tinydtls - diff --git a/net/ip/tinydtls/aes/Makefile.in b/net/ip/tinydtls/aes/Makefile.in deleted file mode 100644 index 4cf29d4cf5cd22930303e13ab0cd672399dad07e..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/aes/Makefile.in +++ /dev/null @@ -1,76 +0,0 @@ -# Makefile for tinydtls -# -# Copyright (C) 2011 Olaf Bergmann -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, copy, -# modify, merge, publish, distribute, sublicense, and/or sell copies -# of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# the library's version -VERSION:=@PACKAGE_VERSION@ - -# tools -@SET_MAKE@ -SHELL = /bin/sh -MKDIR = mkdir - -abs_builddir = @abs_builddir@ -top_builddir = @top_builddir@ -top_srcdir:= @top_srcdir@ - -SOURCES:= rijndael.c -HEADERS:= rijndael.h -OBJECTS:= $(patsubst %.c, %.o, $(SOURCES)) -CPPFLAGS=@CPPFLAGS@ -CFLAGS=-Wall -std=c99 -pedantic @CFLAGS@ -LDLIBS=@LIBS@ -FILES:=Makefile.in $(SOURCES) $(HEADERS) -DISTDIR=$(top_builddir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@ - -.PHONY: all dirs clean install dist distclean .gitignore doc - -.SUFFIXES: -.SUFFIXES: .c .o - -all: - -check: - echo DISTDIR: $(DISTDIR) - echo top_builddir: $(top_builddir) - -clean: - @rm -f $(PROGRAMS) main.o $(LIB) $(OBJECTS) - for dir in $(SUBDIRS); do \ - $(MAKE) -C $$dir clean ; \ - done - -distclean: clean - @rm -rf $(DISTDIR) - @rm -f *~ $(DISTDIR).tar.gz - -dist: $(FILES) - test -d $(DISTDIR)/aes || mkdir $(DISTDIR)/aes - cp -p $(FILES) $(DISTDIR)/aes - -install: $(HEADERS) - test -d $(includedir)/aes || mkdir -p $(includedir)/aes - $(install) $(HEADERS) $(includedir)/aes - -.gitignore: - echo "core\n*~\n*.[oa]\n*.gz\n*.cap\n$(PROGRAM)\n$(DISTDIR)\n.gitignore" >$@ diff --git a/net/ip/tinydtls/aes/rijndael.c b/net/ip/tinydtls/aes/rijndael.c deleted file mode 100644 index c7eaabd7809061c8dcbb9d8918687cc0ab9777a4..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/aes/rijndael.c +++ /dev/null @@ -1,1280 +0,0 @@ -/* $OpenBSD: rijndael.c,v 1.19 2008/06/09 07:49:45 djm Exp $ */ - -/** - * rijndael-alg-fst.c - * - * @version 3.0 (December 2000) - * - * Optimised ANSI C code for the Rijndael cipher (now AES) - * - * @author Vincent Rijmen - * @author Antoon Bosselaers - * @author Paulo Barreto - * - * This code is hereby placed in the public domain. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* #include */ -/* #include */ - -#include "rijndael.h" - -#undef FULL_UNROLL - -/* -Te0[x] = S [x].[02, 01, 01, 03]; -Te1[x] = S [x].[03, 02, 01, 01]; -Te2[x] = S [x].[01, 03, 02, 01]; -Te3[x] = S [x].[01, 01, 03, 02]; -Te4[x] = S [x].[01, 01, 01, 01]; - -Td0[x] = Si[x].[0e, 09, 0d, 0b]; -Td1[x] = Si[x].[0b, 0e, 09, 0d]; -Td2[x] = Si[x].[0d, 0b, 0e, 09]; -Td3[x] = Si[x].[09, 0d, 0b, 0e]; -Td4[x] = Si[x].[01, 01, 01, 01]; -*/ - -static const aes_u32 Te0[256] = { - 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, - 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, - 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, - 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, - 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, - 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, - 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, - 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, - 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, - 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, - 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, - 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, - 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, - 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, - 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, - 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, - 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, - 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, - 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, - 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, - 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, - 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, - 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, - 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, - 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, - 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, - 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, - 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, - 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, - 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, - 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, - 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, - 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, - 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, - 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, - 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, - 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, - 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, - 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, - 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, - 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, - 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, - 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, - 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, - 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, - 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, - 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, - 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, - 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, - 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, - 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, - 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, - 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, - 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, - 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, - 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, - 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, - 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, - 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, - 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, - 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, - 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, - 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, - 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, -}; -static const aes_u32 Te1[256] = { - 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, - 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, - 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, - 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, - 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, - 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, - 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, - 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, - 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, - 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, - 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, - 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, - 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, - 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, - 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, - 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, - 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, - 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, - 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, - 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, - 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, - 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, - 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, - 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, - 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, - 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, - 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, - 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, - 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, - 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, - 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, - 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, - 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, - 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, - 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, - 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, - 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, - 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, - 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, - 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, - 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, - 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, - 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, - 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, - 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, - 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, - 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, - 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, - 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, - 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, - 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, - 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, - 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, - 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, - 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, - 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, - 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, - 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, - 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, - 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, - 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, - 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, - 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, - 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, -}; -static const aes_u32 Te2[256] = { - 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, - 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, - 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, - 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, - 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, - 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, - 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, - 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, - 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, - 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, - 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, - 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, - 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, - 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, - 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, - 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, - 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, - 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, - 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, - 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, - 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, - 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, - 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, - 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, - 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, - 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, - 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, - 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, - 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, - 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, - 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, - 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, - 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, - 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, - 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, - 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, - 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, - 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, - 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, - 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, - 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, - 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, - 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, - 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, - 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, - 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, - 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, - 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, - 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, - 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, - 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, - 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, - 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, - 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, - 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, - 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, - 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, - 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, - 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, - 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, - 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, - 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, - 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, - 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, -}; -static const aes_u32 Te3[256] = { - 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, - 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, - 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, - 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, - 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, - 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, - 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, - 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, - 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, - 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, - 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, - 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, - 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, - 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, - 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, - 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, - 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, - 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, - 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, - 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, - 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, - 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, - 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, - 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, - 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, - 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, - 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, - 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, - 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, - 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, - 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, - 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, - 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, - 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, - 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, - 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, - 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, - 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, - 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, - 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, - 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, - 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, - 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, - 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, - 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, - 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, - 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, - 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, - 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, - 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, - 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, - 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, - 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, - 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, - 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, - 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, - 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, - 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, - 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, - 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, - 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, - 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, - 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, - 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, -}; -static const aes_u32 Te4[256] = { - 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, - 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, - 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, - 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, - 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, - 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, - 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, - 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, - 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, - 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, - 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, - 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, - 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, - 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, - 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, - 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, - 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, - 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, - 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, - 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, - 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, - 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, - 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, - 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, - 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, - 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, - 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, - 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, - 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, - 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, - 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, - 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, - 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, - 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, - 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, - 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, - 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, - 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, - 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, - 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, - 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, - 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, - 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, - 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, - 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, - 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, - 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, - 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, - 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, - 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, - 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, - 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, - 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, - 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, - 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, - 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, - 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, - 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, - 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, - 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, - 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, - 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, - 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, - 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, -}; - -#ifdef WITH_AES_DECRYPT - -static const aes_u32 Td0[256] = { - 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, - 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, - 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, - 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, - 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, - 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, - 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, - 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, - 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, - 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, - 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, - 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, - 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, - 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, - 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, - 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, - 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, - 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, - 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, - 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, - 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, - 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, - 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, - 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, - 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, - 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, - 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, - 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, - 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, - 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, - 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, - 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, - 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, - 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, - 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, - 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, - 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, - 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, - 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, - 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, - 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, - 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, - 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, - 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, - 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, - 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, - 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, - 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, - 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, - 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, - 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, - 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, - 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, - 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, - 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, - 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, - 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, - 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, - 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, - 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, - 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, - 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, - 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, - 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, -}; -static const aes_u32 Td1[256] = { - 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, - 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, - 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, - 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, - 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, - 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, - 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, - 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, - 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, - 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, - 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, - 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, - 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, - 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, - 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, - 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, - 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, - 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, - 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, - 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, - 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, - 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, - 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, - 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, - 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, - 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, - 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, - 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, - 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, - 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, - 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, - 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, - 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, - 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, - 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, - 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, - 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, - 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, - 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, - 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, - 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, - 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, - 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, - 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, - 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, - 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, - 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, - 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, - 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, - 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, - 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, - 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, - 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, - 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, - 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, - 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, - 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, - 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, - 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, - 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, - 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, - 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, - 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, - 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, -}; -static const aes_u32 Td2[256] = { - 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, - 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, - 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, - 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, - 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, - 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, - 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, - 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, - 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, - 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, - 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, - 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, - 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, - 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, - 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, - 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, - 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, - 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, - 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, - 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, - 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, - 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, - 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, - 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, - 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, - 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, - 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, - 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, - 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, - 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, - 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, - 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, - 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, - 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, - 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, - 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, - 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, - 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, - 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, - 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, - 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, - 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, - 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, - 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, - 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, - 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, - 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, - 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, - 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, - 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, - 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, - 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, - 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, - 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, - 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, - 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, - 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, - 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, - 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, - 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, - 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, - 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, - 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, - 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, -}; -static const aes_u32 Td3[256] = { - 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, - 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, - 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, - 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, - 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, - 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, - 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, - 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, - 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, - 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, - 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, - 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, - 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, - 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, - 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, - 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, - 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, - 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, - 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, - 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, - 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, - 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, - 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, - 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, - 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, - 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, - 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, - 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, - 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, - 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, - 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, - 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, - 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, - 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, - 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, - 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, - 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, - 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, - 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, - 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, - 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, - 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, - 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, - 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, - 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, - 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, - 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, - 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, - 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, - 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, - 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, - 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, - 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, - 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, - 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, - 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, - 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, - 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, - 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, - 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, - 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, - 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, - 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, - 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, -}; -static const aes_u32 Td4[256] = { - 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, - 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, - 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, - 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, - 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, - 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, - 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, - 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, - 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, - 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, - 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, - 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, - 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, - 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, - 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, - 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, - 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, - 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, - 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, - 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, - 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, - 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, - 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, - 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, - 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, - 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, - 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, - 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, - 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, - 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, - 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, - 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, - 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, - 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, - 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, - 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, - 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, - 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, - 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, - 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, - 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, - 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, - 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, - 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, - 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, - 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, - 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, - 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, - 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, - 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, - 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, - 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, - 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, - 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, - 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, - 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, - 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, - 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, - 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, - 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, - 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, - 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, - 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, - 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, -}; - -#endif /* WITH_AES_DECRYPT */ - -static const aes_u32 rcon[] = { - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ -}; - -#define GETU32(pt) (((aes_u32)(pt)[0] << 24) ^ ((aes_u32)(pt)[1] << 16) ^ ((aes_u32)(pt)[2] << 8) ^ ((aes_u32)(pt)[3])) -#define PUTU32(ct, st) { (ct)[0] = (aes_u8)((st) >> 24); (ct)[1] = (aes_u8)((st) >> 16); (ct)[2] = (aes_u8)((st) >> 8); (ct)[3] = (aes_u8)(st); } - -/** - * Expand the cipher key into the encryption key schedule. - * - * @return the number of rounds for the given cipher key size. - */ -int -rijndaelKeySetupEnc(aes_u32 rk[/*4*(Nr + 1)*/], const aes_u8 cipherKey[], int keyBits) -{ - int i = 0; - aes_u32 temp; - - rk[0] = GETU32(cipherKey ); - rk[1] = GETU32(cipherKey + 4); - rk[2] = GETU32(cipherKey + 8); - rk[3] = GETU32(cipherKey + 12); - if (keyBits == 128) { - for (;;) { - temp = rk[3]; - rk[4] = rk[0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[5] = rk[1] ^ rk[4]; - rk[6] = rk[2] ^ rk[5]; - rk[7] = rk[3] ^ rk[6]; - if (++i == 10) { - return 10; - } - rk += 4; - } - } - rk[4] = GETU32(cipherKey + 16); - rk[5] = GETU32(cipherKey + 20); - if (keyBits == 192) { - for (;;) { - temp = rk[ 5]; - rk[ 6] = rk[ 0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 7] = rk[ 1] ^ rk[ 6]; - rk[ 8] = rk[ 2] ^ rk[ 7]; - rk[ 9] = rk[ 3] ^ rk[ 8]; - if (++i == 8) { - return 12; - } - rk[10] = rk[ 4] ^ rk[ 9]; - rk[11] = rk[ 5] ^ rk[10]; - rk += 6; - } - } - rk[6] = GETU32(cipherKey + 24); - rk[7] = GETU32(cipherKey + 28); - if (keyBits == 256) { - for (;;) { - temp = rk[ 7]; - rk[ 8] = rk[ 0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 9] = rk[ 1] ^ rk[ 8]; - rk[10] = rk[ 2] ^ rk[ 9]; - rk[11] = rk[ 3] ^ rk[10]; - if (++i == 7) { - return 14; - } - temp = rk[11]; - rk[12] = rk[ 4] ^ - (Te4[(temp >> 24) ] & 0xff000000) ^ - (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(temp ) & 0xff] & 0x000000ff); - rk[13] = rk[ 5] ^ rk[12]; - rk[14] = rk[ 6] ^ rk[13]; - rk[15] = rk[ 7] ^ rk[14]; - rk += 8; - } - } - return 0; -} - -#ifdef WITH_AES_DECRYPT -/** - * Expand the cipher key into the decryption key schedule. - * - * @return the number of rounds for the given cipher key size. - */ -int -rijndaelKeySetupDec(aes_u32 rk[/*4*(Nr + 1)*/], const aes_u8 cipherKey[], int keyBits) -{ - int Nr, i, j; - aes_u32 temp; - - /* expand the cipher key: */ - Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits); - - /* invert the order of the round keys: */ - for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) { - temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; - temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; - temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; - temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; - } - /* apply the inverse MixColumn transform to all round keys but the first and the last: */ - for (i = 1; i < Nr; i++) { - rk += 4; - rk[0] = - Td0[Te4[(rk[0] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[0] ) & 0xff] & 0xff]; - rk[1] = - Td0[Te4[(rk[1] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[1] ) & 0xff] & 0xff]; - rk[2] = - Td0[Te4[(rk[2] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[2] ) & 0xff] & 0xff]; - rk[3] = - Td0[Te4[(rk[3] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[3] ) & 0xff] & 0xff]; - } - return Nr; -} -#endif - -void -rijndaelEncrypt(const aes_u32 rk[/*4*(Nr + 1)*/], int Nr, const aes_u8 pt[16], - aes_u8 ct[16]) -{ - aes_u32 s0, s1, s2, s3, t0, t1, t2, t3; -#ifndef FULL_UNROLL - int r; -#endif /* ?FULL_UNROLL */ - - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(pt ) ^ rk[0]; - s1 = GETU32(pt + 4) ^ rk[1]; - s2 = GETU32(pt + 8) ^ rk[2]; - s3 = GETU32(pt + 12) ^ rk[3]; -#ifdef FULL_UNROLL - /* round 1: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7]; - /* round 2: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11]; - /* round 3: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15]; - /* round 4: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19]; - /* round 5: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23]; - /* round 6: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27]; - /* round 7: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31]; - /* round 8: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35]; - /* round 9: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39]; - if (Nr > 10) { - /* round 10: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43]; - /* round 11: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47]; - if (Nr > 12) { - /* round 12: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51]; - /* round 13: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55]; - } - } - rk += Nr << 2; -#else /* !FULL_UNROLL */ - /* - * Nr - 1 full rounds: - */ - r = Nr >> 1; - for (;;) { - t0 = - Te0[(s0 >> 24) ] ^ - Te1[(s1 >> 16) & 0xff] ^ - Te2[(s2 >> 8) & 0xff] ^ - Te3[(s3 ) & 0xff] ^ - rk[4]; - t1 = - Te0[(s1 >> 24) ] ^ - Te1[(s2 >> 16) & 0xff] ^ - Te2[(s3 >> 8) & 0xff] ^ - Te3[(s0 ) & 0xff] ^ - rk[5]; - t2 = - Te0[(s2 >> 24) ] ^ - Te1[(s3 >> 16) & 0xff] ^ - Te2[(s0 >> 8) & 0xff] ^ - Te3[(s1 ) & 0xff] ^ - rk[6]; - t3 = - Te0[(s3 >> 24) ] ^ - Te1[(s0 >> 16) & 0xff] ^ - Te2[(s1 >> 8) & 0xff] ^ - Te3[(s2 ) & 0xff] ^ - rk[7]; - - rk += 8; - if (--r == 0) { - break; - } - - s0 = - Te0[(t0 >> 24) ] ^ - Te1[(t1 >> 16) & 0xff] ^ - Te2[(t2 >> 8) & 0xff] ^ - Te3[(t3 ) & 0xff] ^ - rk[0]; - s1 = - Te0[(t1 >> 24) ] ^ - Te1[(t2 >> 16) & 0xff] ^ - Te2[(t3 >> 8) & 0xff] ^ - Te3[(t0 ) & 0xff] ^ - rk[1]; - s2 = - Te0[(t2 >> 24) ] ^ - Te1[(t3 >> 16) & 0xff] ^ - Te2[(t0 >> 8) & 0xff] ^ - Te3[(t1 ) & 0xff] ^ - rk[2]; - s3 = - Te0[(t3 >> 24) ] ^ - Te1[(t0 >> 16) & 0xff] ^ - Te2[(t1 >> 8) & 0xff] ^ - Te3[(t2 ) & 0xff] ^ - rk[3]; - } -#endif /* ?FULL_UNROLL */ - /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = - (Te4[(t0 >> 24) ] & 0xff000000) ^ - (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t3 ) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTU32(ct , s0); - s1 = - (Te4[(t1 >> 24) ] & 0xff000000) ^ - (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t0 ) & 0xff] & 0x000000ff) ^ - rk[1]; - PUTU32(ct + 4, s1); - s2 = - (Te4[(t2 >> 24) ] & 0xff000000) ^ - (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t1 ) & 0xff] & 0x000000ff) ^ - rk[2]; - PUTU32(ct + 8, s2); - s3 = - (Te4[(t3 >> 24) ] & 0xff000000) ^ - (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t2 ) & 0xff] & 0x000000ff) ^ - rk[3]; - PUTU32(ct + 12, s3); -} - -#ifdef WITH_AES_DECRYPT -static void -rijndaelDecrypt(const aes_u32 rk[/*4*(Nr + 1)*/], int Nr, const aes_u8 ct[16], - aes_u8 pt[16]) -{ - aes_u32 s0, s1, s2, s3, t0, t1, t2, t3; -#ifndef FULL_UNROLL - int r; -#endif /* ?FULL_UNROLL */ - - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(ct ) ^ rk[0]; - s1 = GETU32(ct + 4) ^ rk[1]; - s2 = GETU32(ct + 8) ^ rk[2]; - s3 = GETU32(ct + 12) ^ rk[3]; -#ifdef FULL_UNROLL - /* round 1: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7]; - /* round 2: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11]; - /* round 3: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15]; - /* round 4: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19]; - /* round 5: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23]; - /* round 6: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27]; - /* round 7: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31]; - /* round 8: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35]; - /* round 9: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39]; - if (Nr > 10) { - /* round 10: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43]; - /* round 11: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47]; - if (Nr > 12) { - /* round 12: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51]; - /* round 13: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55]; - } - } - rk += Nr << 2; -#else /* !FULL_UNROLL */ - /* - * Nr - 1 full rounds: - */ - r = Nr >> 1; - for (;;) { - t0 = - Td0[(s0 >> 24) ] ^ - Td1[(s3 >> 16) & 0xff] ^ - Td2[(s2 >> 8) & 0xff] ^ - Td3[(s1 ) & 0xff] ^ - rk[4]; - t1 = - Td0[(s1 >> 24) ] ^ - Td1[(s0 >> 16) & 0xff] ^ - Td2[(s3 >> 8) & 0xff] ^ - Td3[(s2 ) & 0xff] ^ - rk[5]; - t2 = - Td0[(s2 >> 24) ] ^ - Td1[(s1 >> 16) & 0xff] ^ - Td2[(s0 >> 8) & 0xff] ^ - Td3[(s3 ) & 0xff] ^ - rk[6]; - t3 = - Td0[(s3 >> 24) ] ^ - Td1[(s2 >> 16) & 0xff] ^ - Td2[(s1 >> 8) & 0xff] ^ - Td3[(s0 ) & 0xff] ^ - rk[7]; - - rk += 8; - if (--r == 0) { - break; - } - - s0 = - Td0[(t0 >> 24) ] ^ - Td1[(t3 >> 16) & 0xff] ^ - Td2[(t2 >> 8) & 0xff] ^ - Td3[(t1 ) & 0xff] ^ - rk[0]; - s1 = - Td0[(t1 >> 24) ] ^ - Td1[(t0 >> 16) & 0xff] ^ - Td2[(t3 >> 8) & 0xff] ^ - Td3[(t2 ) & 0xff] ^ - rk[1]; - s2 = - Td0[(t2 >> 24) ] ^ - Td1[(t1 >> 16) & 0xff] ^ - Td2[(t0 >> 8) & 0xff] ^ - Td3[(t3 ) & 0xff] ^ - rk[2]; - s3 = - Td0[(t3 >> 24) ] ^ - Td1[(t2 >> 16) & 0xff] ^ - Td2[(t1 >> 8) & 0xff] ^ - Td3[(t0 ) & 0xff] ^ - rk[3]; - } -#endif /* ?FULL_UNROLL */ - /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = - (Td4[(t0 >> 24) ] & 0xff000000) ^ - (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t1 ) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTU32(pt , s0); - s1 = - (Td4[(t1 >> 24) ] & 0xff000000) ^ - (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t2 ) & 0xff] & 0x000000ff) ^ - rk[1]; - PUTU32(pt + 4, s1); - s2 = - (Td4[(t2 >> 24) ] & 0xff000000) ^ - (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t3 ) & 0xff] & 0x000000ff) ^ - rk[2]; - PUTU32(pt + 8, s2); - s3 = - (Td4[(t3 >> 24) ] & 0xff000000) ^ - (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t0 ) & 0xff] & 0x000000ff) ^ - rk[3]; - PUTU32(pt + 12, s3); -} -#endif - -/* setup key context for encryption only */ -int -rijndael_set_key_enc_only(rijndael_ctx *ctx, const u_char *key, int bits) -{ - int rounds; - - rounds = rijndaelKeySetupEnc(ctx->ek, key, bits); - if (rounds == 0) - return -1; - - ctx->Nr = rounds; -#ifdef WITH_AES_DECRYPT - ctx->enc_only = 1; -#endif - - return 0; -} - -#ifdef WITH_AES_DECRYPT -/* setup key context for both encryption and decryption */ -int -rijndael_set_key(rijndael_ctx *ctx, const u_char *key, int bits) -{ - int rounds; - - rounds = rijndaelKeySetupEnc(ctx->ek, key, bits); - if (rounds == 0) - return -1; - if (rijndaelKeySetupDec(ctx->dk, key, bits) != rounds) - return -1; - - ctx->Nr = rounds; - ctx->enc_only = 0; - - return 0; -} - -void -rijndael_decrypt(rijndael_ctx *ctx, const u_char *src, u_char *dst) -{ - rijndaelDecrypt(ctx->dk, ctx->Nr, src, dst); -} -#endif - -void -rijndael_encrypt(rijndael_ctx *ctx, const u_char *src, u_char *dst) -{ - rijndaelEncrypt(ctx->ek, ctx->Nr, src, dst); -} diff --git a/net/ip/tinydtls/aes/rijndael.h b/net/ip/tinydtls/aes/rijndael.h deleted file mode 100644 index 9184ff98ef6245b35b4ef5bda9d405b90216eb3c..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/aes/rijndael.h +++ /dev/null @@ -1,66 +0,0 @@ -/* $OpenBSD: rijndael.h,v 1.13 2008/06/09 07:49:45 djm Exp $ */ - -/** - * rijndael-alg-fst.h - * - * @version 3.0 (December 2000) - * - * Optimised ANSI C code for the Rijndael cipher (now AES) - * - * @author Vincent Rijmen - * @author Antoon Bosselaers - * @author Paulo Barreto - * - * This code is hereby placed in the public domain. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __RIJNDAEL_H -#define __RIJNDAEL_H - -#include - -#define AES_MAXKEYBITS (256) -#define AES_MAXKEYBYTES (AES_MAXKEYBITS/8) -/* for 256-bit keys we need 14 rounds for a 128 we only need 10 round */ -#define AES_MAXROUNDS 10 - -/* bergmann: to avoid conflicts with typedefs from certain Contiki platforms, - * the following type names have been prefixed with "aes_": */ -typedef unsigned char u_char; -typedef uint8_t aes_u8; -typedef uint16_t aes_u16; -typedef uint32_t aes_u32; - -/* The structure for key information */ -typedef struct { -#ifdef WITH_AES_DECRYPT - int enc_only; /* context contains only encrypt schedule */ -#endif - int Nr; /* key-length-dependent number of rounds */ - aes_u32 ek[4*(AES_MAXROUNDS + 1)]; /* encrypt key schedule */ -#ifdef WITH_AES_DECRYPT - aes_u32 dk[4*(AES_MAXROUNDS + 1)]; /* decrypt key schedule */ -#endif -} rijndael_ctx; - -int rijndael_set_key(rijndael_ctx *, const u_char *, int); -int rijndael_set_key_enc_only(rijndael_ctx *, const u_char *, int); -void rijndael_decrypt(rijndael_ctx *, const u_char *, u_char *); -void rijndael_encrypt(rijndael_ctx *, const u_char *, u_char *); - -int rijndaelKeySetupEnc(aes_u32 rk[/*4*(Nr + 1)*/], const aes_u8 cipherKey[], int keyBits); -int rijndaelKeySetupDec(aes_u32 rk[/*4*(Nr + 1)*/], const aes_u8 cipherKey[], int keyBits); -void rijndaelEncrypt(const aes_u32 rk[/*4*(Nr + 1)*/], int Nr, const aes_u8 pt[16], aes_u8 ct[16]); - -#endif /* __RIJNDAEL_H */ diff --git a/net/ip/tinydtls/alert.h b/net/ip/tinydtls/alert.h deleted file mode 100644 index 5a27faa8949635649b289074dad8bc49cce8a039..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/alert.h +++ /dev/null @@ -1,81 +0,0 @@ -/* alert.h -- DTLS alert protocol - * - * Copyright (C) 2012 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * @file alert.h - * @brief DTLS alert protocol - */ - -#ifndef _DTLS_ALERT_H_ -#define _DTLS_ALERT_H_ - -typedef enum { - DTLS_ALERT_LEVEL_WARNING=1, - DTLS_ALERT_LEVEL_FATAL=2 -} dtls_alert_level_t; - -typedef enum { - DTLS_ALERT_CLOSE_NOTIFY = 0, /* close_notify */ - DTLS_ALERT_UNEXPECTED_MESSAGE = 10, /* unexpected_message */ - DTLS_ALERT_BAD_RECORD_MAC = 20, /* bad_record_mac */ - DTLS_ALERT_RECORD_OVERFLOW = 22, /* record_overflow */ - DTLS_ALERT_DECOMPRESSION_FAILURE = 30, /* decompression_failure */ - DTLS_ALERT_HANDSHAKE_FAILURE = 40, /* handshake_failure */ - DTLS_ALERT_BAD_CERTIFICATE = 42, /* bad_certificate */ - DTLS_ALERT_UNSUPPORTED_CERTIFICATE = 43, /* unsupported_certificate */ - DTLS_ALERT_CERTIFICATE_REVOKED = 44, /* certificate_revoked */ - DTLS_ALERT_CERTIFICATE_EXPIRED = 45, /* certificate_expired */ - DTLS_ALERT_CERTIFICATE_UNKNOWN = 46, /* certificate_unknown */ - DTLS_ALERT_ILLEGAL_PARAMETER = 47, /* illegal_parameter */ - DTLS_ALERT_UNKNOWN_CA = 48, /* unknown_ca */ - DTLS_ALERT_ACCESS_DENIED = 49, /* access_denied */ - DTLS_ALERT_DECODE_ERROR = 50, /* decode_error */ - DTLS_ALERT_DECRYPT_ERROR = 51, /* decrypt_error */ - DTLS_ALERT_PROTOCOL_VERSION = 70, /* protocol_version */ - DTLS_ALERT_INSUFFICIENT_SECURITY = 71, /* insufficient_security */ - DTLS_ALERT_INTERNAL_ERROR = 80, /* internal_error */ - DTLS_ALERT_USER_CANCELED = 90, /* user_canceled */ - DTLS_ALERT_NO_RENEGOTIATION = 100, /* no_renegotiation */ - DTLS_ALERT_UNSUPPORTED_EXTENSION = 110 /* unsupported_extension */ -} dtls_alert_t; - -#define DTLS_EVENT_CONNECT 0x01DC /**< initiated handshake */ -#define DTLS_EVENT_CONNECTED 0x01DE /**< handshake or re-negotiation - * has finished */ -#define DTLS_EVENT_RENEGOTIATE 0x01DF /**< re-negotiation has started */ - -static inline int -dtls_alert_create(dtls_alert_level_t level, dtls_alert_t desc) -{ - return -((level << 8) | desc); -} - -static inline int -dtls_alert_fatal_create(dtls_alert_t desc) -{ - return dtls_alert_create(DTLS_ALERT_LEVEL_FATAL, desc); -} - -#endif /* _DTLS_ALERT_H_ */ diff --git a/net/ip/tinydtls/ccm.c b/net/ip/tinydtls/ccm.c deleted file mode 100644 index 7563db80234622db0a99761418878649b39f8014..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/ccm.c +++ /dev/null @@ -1,311 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2014 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include - -#include "dtls_config.h" -#include "global.h" -#include "numeric.h" -#include "ccm.h" - -#ifdef HAVE_ASSERT_H -# include -#endif - -#define CCM_FLAGS(A,M,L) (((A > 0) << 6) | (((M - 2)/2) << 3) | (L - 1)) - -#define MASK_L(_L) ((1 << 8 * _L) - 1) - -#define SET_COUNTER(A,L,cnt,C) { \ - int i; \ - memset((A) + DTLS_CCM_BLOCKSIZE - (L), 0, (L)); \ - (C) = (cnt) & MASK_L(L); \ - for (i = DTLS_CCM_BLOCKSIZE - 1; (C) && (i > (L)); --i, (C) >>= 8) \ - (A)[i] |= (C) & 0xFF; \ - } - -static inline void -block0(size_t M, /* number of auth bytes */ - size_t L, /* number of bytes to encode message length */ - size_t la, /* l(a) octets additional authenticated data */ - size_t lm, /* l(m) message length */ - unsigned char nonce[DTLS_CCM_BLOCKSIZE], - unsigned char *result) { - int i; - - result[0] = CCM_FLAGS(la, M, L); - - /* copy the nonce */ - memcpy(result + 1, nonce, DTLS_CCM_BLOCKSIZE - L); - - for (i=0; i < L; i++) { - result[15-i] = lm & 0xff; - lm >>= 8; - } -} - -/** - * Creates the CBC-MAC for the additional authentication data that - * is sent in cleartext. - * - * \param ctx The crypto context for the AES encryption. - * \param msg The message starting with the additional authentication data. - * \param la The number of additional authentication bytes in \p msg. - * \param B The input buffer for crypto operations. When this function - * is called, \p B must be initialized with \c B0 (the first - * authentication block. - * \param X The output buffer where the result of the CBC calculation - * is placed. - * \return The result is written to \p X. - */ -static void -add_auth_data(rijndael_ctx *ctx, const unsigned char *msg, size_t la, - unsigned char B[DTLS_CCM_BLOCKSIZE], - unsigned char X[DTLS_CCM_BLOCKSIZE]) { - size_t i,j; - - rijndael_encrypt(ctx, B, X); - - memset(B, 0, DTLS_CCM_BLOCKSIZE); - - if (!la) - return; - -#ifndef WITH_CONTIKI - if (la < 0xFF00) { /* 2^16 - 2^8 */ - j = 2; - dtls_int_to_uint16(B, la); - } else if (la <= UINT32_MAX) { - j = 6; - dtls_int_to_uint16(B, 0xFFFE); - dtls_int_to_uint32(B+2, la); - } else { - j = 10; - dtls_int_to_uint16(B, 0xFFFF); - dtls_int_to_uint64(B+2, la); - } -#else /* WITH_CONTIKI */ - /* With Contiki, we are building for small devices and thus - * anticipate that the number of additional authentication bytes - * will not exceed 65280 bytes (0xFF00) and we can skip the - * workarounds required for j=6 and j=10 on devices with a word size - * of 32 bits or 64 bits, respectively. - */ - - assert(la < 0xFF00); - j = 2; - dtls_int_to_uint16(B, la); -#endif /* WITH_CONTIKI */ - - i = min(DTLS_CCM_BLOCKSIZE - j, la); - memcpy(B + j, msg, i); - la -= i; - msg += i; - - memxor(B, X, DTLS_CCM_BLOCKSIZE); - - rijndael_encrypt(ctx, B, X); - - while (la > DTLS_CCM_BLOCKSIZE) { - for (i = 0; i < DTLS_CCM_BLOCKSIZE; ++i) - B[i] = X[i] ^ *msg++; - la -= DTLS_CCM_BLOCKSIZE; - - rijndael_encrypt(ctx, B, X); - } - - if (la) { - memset(B, 0, DTLS_CCM_BLOCKSIZE); - memcpy(B, msg, la); - memxor(B, X, DTLS_CCM_BLOCKSIZE); - - rijndael_encrypt(ctx, B, X); - } -} - -static inline void -encrypt(rijndael_ctx *ctx, size_t L, unsigned long counter, - unsigned char *msg, size_t len, - unsigned char A[DTLS_CCM_BLOCKSIZE], - unsigned char S[DTLS_CCM_BLOCKSIZE]) { - - static unsigned long counter_tmp; - - SET_COUNTER(A, L, counter, counter_tmp); - rijndael_encrypt(ctx, A, S); - memxor(msg, S, len); -} - -static inline void -mac(rijndael_ctx *ctx, - unsigned char *msg, size_t len, - unsigned char B[DTLS_CCM_BLOCKSIZE], - unsigned char X[DTLS_CCM_BLOCKSIZE]) { - size_t i; - - for (i = 0; i < len; ++i) - B[i] = X[i] ^ msg[i]; - - rijndael_encrypt(ctx, B, X); - -} - -long int -dtls_ccm_encrypt_message(rijndael_ctx *ctx, size_t M, size_t L, - unsigned char nonce[DTLS_CCM_BLOCKSIZE], - unsigned char *msg, size_t lm, - const unsigned char *aad, size_t la) { - size_t i, len; - unsigned long counter_tmp; - unsigned long counter = 1; /* \bug does not work correctly on ia32 when - lm >= 2^16 */ - unsigned char A[DTLS_CCM_BLOCKSIZE]; /* A_i blocks for encryption input */ - unsigned char B[DTLS_CCM_BLOCKSIZE]; /* B_i blocks for CBC-MAC input */ - unsigned char S[DTLS_CCM_BLOCKSIZE]; /* S_i = encrypted A_i blocks */ - unsigned char X[DTLS_CCM_BLOCKSIZE]; /* X_i = encrypted B_i blocks */ - - len = lm; /* save original length */ - /* create the initial authentication block B0 */ - block0(M, L, la, lm, nonce, B); - add_auth_data(ctx, aad, la, B, X); - - /* initialize block template */ - A[0] = L-1; - - /* copy the nonce */ - memcpy(A + 1, nonce, DTLS_CCM_BLOCKSIZE - L); - - while (lm >= DTLS_CCM_BLOCKSIZE) { - /* calculate MAC */ - mac(ctx, msg, DTLS_CCM_BLOCKSIZE, B, X); - - /* encrypt */ - encrypt(ctx, L, counter, msg, DTLS_CCM_BLOCKSIZE, A, S); - - /* update local pointers */ - lm -= DTLS_CCM_BLOCKSIZE; - msg += DTLS_CCM_BLOCKSIZE; - counter++; - } - - if (lm) { - /* Calculate MAC. The remainder of B must be padded with zeroes, so - * B is constructed to contain X ^ msg for the first lm bytes (done in - * mac() and X ^ 0 for the remaining DTLS_CCM_BLOCKSIZE - lm bytes - * (i.e., we can use memcpy() here). - */ - memcpy(B + lm, X + lm, DTLS_CCM_BLOCKSIZE - lm); - mac(ctx, msg, lm, B, X); - - /* encrypt */ - encrypt(ctx, L, counter, msg, lm, A, S); - - /* update local pointers */ - msg += lm; - } - - /* calculate S_0 */ - SET_COUNTER(A, L, 0, counter_tmp); - rijndael_encrypt(ctx, A, S); - - for (i = 0; i < M; ++i) - *msg++ = X[i] ^ S[i]; - - return len + M; -} - -long int -dtls_ccm_decrypt_message(rijndael_ctx *ctx, size_t M, size_t L, - unsigned char nonce[DTLS_CCM_BLOCKSIZE], - unsigned char *msg, size_t lm, - const unsigned char *aad, size_t la) { - - size_t len; - unsigned long counter_tmp; - unsigned long counter = 1; /* \bug does not work correctly on ia32 when - lm >= 2^16 */ - unsigned char A[DTLS_CCM_BLOCKSIZE]; /* A_i blocks for encryption input */ - unsigned char B[DTLS_CCM_BLOCKSIZE]; /* B_i blocks for CBC-MAC input */ - unsigned char S[DTLS_CCM_BLOCKSIZE]; /* S_i = encrypted A_i blocks */ - unsigned char X[DTLS_CCM_BLOCKSIZE]; /* X_i = encrypted B_i blocks */ - - if (lm < M) - goto error; - - len = lm; /* save original length */ - lm -= M; /* detract MAC size*/ - - /* create the initial authentication block B0 */ - block0(M, L, la, lm, nonce, B); - add_auth_data(ctx, aad, la, B, X); - - /* initialize block template */ - A[0] = L-1; - - /* copy the nonce */ - memcpy(A + 1, nonce, DTLS_CCM_BLOCKSIZE - L); - - while (lm >= DTLS_CCM_BLOCKSIZE) { - /* decrypt */ - encrypt(ctx, L, counter, msg, DTLS_CCM_BLOCKSIZE, A, S); - - /* calculate MAC */ - mac(ctx, msg, DTLS_CCM_BLOCKSIZE, B, X); - - /* update local pointers */ - lm -= DTLS_CCM_BLOCKSIZE; - msg += DTLS_CCM_BLOCKSIZE; - counter++; - } - - if (lm) { - /* decrypt */ - encrypt(ctx, L, counter, msg, lm, A, S); - - /* Calculate MAC. Note that msg ends in the MAC so we must - * construct B to contain X ^ msg for the first lm bytes (done in - * mac() and X ^ 0 for the remaining DTLS_CCM_BLOCKSIZE - lm bytes - * (i.e., we can use memcpy() here). - */ - memcpy(B + lm, X + lm, DTLS_CCM_BLOCKSIZE - lm); - mac(ctx, msg, lm, B, X); - - /* update local pointers */ - msg += lm; - } - - /* calculate S_0 */ - SET_COUNTER(A, L, 0, counter_tmp); - rijndael_encrypt(ctx, A, S); - - memxor(msg, S, M); - - /* return length if MAC is valid, otherwise continue with error handling */ - if (equals(X, msg, M)) - return len - M; - - error: - return -1; -} diff --git a/net/ip/tinydtls/ccm.h b/net/ip/tinydtls/ccm.h deleted file mode 100644 index c3949d204ea24c4f5f8cf21d68bd4023310b7a3d..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/ccm.h +++ /dev/null @@ -1,69 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2012 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _DTLS_CCM_H_ -#define _DTLS_CCM_H_ - -#include "aes/rijndael.h" - -/* implementation of Counter Mode CBC-MAC, RFC 3610 */ - -#define DTLS_CCM_BLOCKSIZE 16 /**< size of hmac blocks */ -#define DTLS_CCM_MAX 16 /**< max number of bytes in digest */ -#define DTLS_CCM_NONCE_SIZE 12 /**< size of nonce */ - -/** - * Authenticates and encrypts a message using AES in CCM mode. Please - * see also RFC 3610 for the meaning of \p M, \p L, \p lm and \p la. - * - * \param ctx The initialized rijndael_ctx object to be used for AES operations. - * \param M The number of authentication octets. - * \param L The number of bytes used to encode the message length. - * \param N The nonce value to use. You must provide \c DTLS_CCM_BLOCKSIZE - * nonce octets, although only the first \c 16 - \p L are used. - * \param msg The message to encrypt. The first \p la octets are additional - * authentication data that will be cleartext. Note that the - * encryption operation modifies the contents of \p msg and adds - * \p M bytes MAC. Therefore, the buffer must be at least - * \p lm + \p M bytes large. - * \param lm The actual length of \p msg. - * \param aad A pointer to the additional authentication data (can be \c NULL if - * \p la is zero). - * \param la The number of additional authentication octets (may be zero). - * \return FIXME - */ -long int -dtls_ccm_encrypt_message(rijndael_ctx *ctx, size_t M, size_t L, - unsigned char nonce[DTLS_CCM_BLOCKSIZE], - unsigned char *msg, size_t lm, - const unsigned char *aad, size_t la); - -long int -dtls_ccm_decrypt_message(rijndael_ctx *ctx, size_t M, size_t L, - unsigned char nonce[DTLS_CCM_BLOCKSIZE], - unsigned char *msg, size_t lm, - const unsigned char *aad, size_t la); - -#endif /* _DTLS_CCM_H_ */ diff --git a/net/ip/tinydtls/configure.in b/net/ip/tinydtls/configure.in deleted file mode 100644 index 39f6a1dffdf6524ef7077bd16135248c980da2f7..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/configure.in +++ /dev/null @@ -1,121 +0,0 @@ -# -*- Autoconf -*- -# Process this file with autoconf to produce a configure script. -# -# Copyright (C) 2011--2015 Olaf Bergmann -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, copy, -# modify, merge, publish, distribute, sublicense, and/or sell copies -# of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -AC_PREREQ([2.65]) -AC_INIT([tinydtls], [0.8.2]) -AC_CONFIG_SRCDIR([dtls.c]) -dnl AC_CONFIG_HEADERS([config.h]) - -AC_ARG_WITH(contiki, - [AS_HELP_STRING([--with-contiki],[build libtinydtls for the Contiki OS])], - [AC_DEFINE(WITH_CONTIKI,1,[Define to 1 if building for Contiki.]) - WITH_CONTIKI=1], - []) - -AC_PATH_PROG(DOXYGEN, doxygen, [:]) -AC_PATH_PROG(ETAGS, etags, [/bin/false]) - -if test "${with_contiki}" != "yes" ; then -# Checks for programs. -AC_PROG_MAKE_SET -AC_PROG_CC -AC_PROG_RANLIB - -AC_C_BIGENDIAN - -# Checks for libraries. -AC_SEARCH_LIBS([gethostbyname], [nsl]) -AC_SEARCH_LIBS([socket], [socket]) -fi - -AC_ARG_WITH(debug, - [AS_HELP_STRING([--without-debug],[disable all debug output and assertions])], - [CPPFLAGS="${CPPFLAGS} -DNDEBUG" - NDEBUG=1], - []) - -AC_ARG_WITH(ecc, - [AS_HELP_STRING([--without-ecc],[disable support for TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8])], - [], - [AC_DEFINE(DTLS_ECC, 1, [Define to 1 if building with ECC support.]) - OPT_OBJS="${OPT_OBJS} ecc/ecc.o" - DTLS_ECC=1]) - -AC_ARG_WITH(psk, - [AS_HELP_STRING([--without-psk],[disable support for TLS_PSK_WITH_AES_128_CCM_8])], - [], - [AC_DEFINE(DTLS_PSK, 1, [Define to 1 if building with PSK support]) - DTLS_PSK=1]) - -CPPFLAGS="${CPPFLAGS} -DDTLSv12 -DWITH_SHA256" -OPT_OBJS="${OPT_OBJS} sha2/sha2.o" - -AC_SUBST(OPT_OBJS) -AC_SUBST(NDEBUG) -AC_SUBST(WITH_CONTIKI) -AC_SUBST(DTLS_ECC) -AC_SUBST(DTLS_PSK) - -if test "${with_contiki}" = "yes" ; then - AC_MSG_NOTICE([skipping header checks for Contiki]) -else - # Checks for header files. - AC_CHECK_HEADERS([assert.h arpa/inet.h fcntl.h inttypes.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h strings.h sys/param.h sys/socket.h unistd.h]) - - AC_CHECK_HEADERS([sys/time.h time.h]) - AC_CHECK_HEADERS([sys/types.h sys/stat.h]) - -# Checks for typedefs, structures, and compiler characteristics. -AC_C_INLINE -AC_TYPE_SIZE_T - -AC_CHECK_MEMBER([struct sockaddr_in6.sin6_len], - [AC_DEFINE(HAVE_SOCKADDR_IN6_SIN6_LEN, [1], - [Define to 1 if struct sockaddr_in6 has a member sin6_len.])], [], - [#include ]) - -# Checks for library functions. -AC_FUNC_MALLOC -AC_CHECK_FUNCS([memset select socket strdup strerror strnlen fls vprintf]) -fi - -AC_CONFIG_HEADERS([dtls_config.h tinydtls.h]) - -# Adds Contiki-specific definitions to the end of dtls_config.h -AH_BOTTOM([ -#ifdef WITH_CONTIKI -#include "platform-specific/platform.h" -#endif]) - -AC_CONFIG_FILES([Makefile - doc/Makefile - doc/Doxyfile - tests/Makefile - examples/contiki/Makefile - platform-specific/Makefile - sha2/Makefile - aes/Makefile - ecc/Makefile]) -AC_OUTPUT diff --git a/net/ip/tinydtls/crypto.c b/net/ip/tinydtls/crypto.c deleted file mode 100644 index d16b27eb12e03ba456aa65d698cafc07f057464d..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/crypto.c +++ /dev/null @@ -1,572 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2012 Olaf Bergmann - * Copyright (C) 2013 Hauke Mehrtens - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include - -#include "tinydtls.h" -#include "dtls_config.h" - -#ifdef HAVE_ASSERT_H -#include -#endif - -#include "global.h" -#include "debug.h" -#include "numeric.h" -#include "dtls.h" -#include "crypto.h" -#include "ccm.h" -#include "ecc/ecc.h" -#include "prng.h" -#include "netq.h" - -#ifndef WITH_CONTIKI -#include -#endif - -#define HMAC_UPDATE_SEED(Context,Seed,Length) \ - if (Seed) dtls_hmac_update(Context, (Seed), (Length)) - -static struct dtls_cipher_context_t cipher_context; -#ifndef WITH_CONTIKI -static pthread_mutex_t cipher_context_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif - -static struct dtls_cipher_context_t *dtls_cipher_context_get(void) -{ -#ifndef WITH_CONTIKI - pthread_mutex_lock(&cipher_context_mutex); -#endif - return &cipher_context; -} - -static void dtls_cipher_context_release(void) -{ -#ifndef WITH_CONTIKI - pthread_mutex_unlock(&cipher_context_mutex); -#endif -} - -#ifndef WITH_CONTIKI -void crypto_init() -{ -} - -static dtls_handshake_parameters_t *dtls_handshake_malloc() { - return malloc(sizeof(dtls_handshake_parameters_t)); -} - -static void dtls_handshake_dealloc(dtls_handshake_parameters_t *handshake) { - free(handshake); -} - -static dtls_security_parameters_t *dtls_security_malloc() { - return malloc(sizeof(dtls_security_parameters_t)); -} - -static void dtls_security_dealloc(dtls_security_parameters_t *security) { - free(security); -} -#else /* WITH_CONTIKI */ - -#include "memb.h" -MEMB(handshake_storage, dtls_handshake_parameters_t, DTLS_HANDSHAKE_MAX); -MEMB(security_storage, dtls_security_parameters_t, DTLS_SECURITY_MAX); - -void crypto_init() { - memb_init(&handshake_storage); - memb_init(&security_storage); -} - -static dtls_handshake_parameters_t *dtls_handshake_malloc() { - return memb_alloc(&handshake_storage); -} - -static void dtls_handshake_dealloc(dtls_handshake_parameters_t *handshake) { - memb_free(&handshake_storage, handshake); -} - -static dtls_security_parameters_t *dtls_security_malloc() { - return memb_alloc(&security_storage); -} - -static void dtls_security_dealloc(dtls_security_parameters_t *security) { - memb_free(&security_storage, security); -} -#endif /* WITH_CONTIKI */ - -dtls_handshake_parameters_t *dtls_handshake_new() -{ - dtls_handshake_parameters_t *handshake; - - handshake = dtls_handshake_malloc(); - if (!handshake) { - dtls_crit("can not allocate a handshake struct\n"); - return NULL; - } - - memset(handshake, 0, sizeof(*handshake)); - - if (handshake) { - /* initialize the handshake hash wrt. the hard-coded DTLS version */ - dtls_debug("DTLSv12: initialize HASH_SHA256\n"); - /* TLS 1.2: PRF(secret, label, seed) = P_(secret, label + seed) */ - /* FIXME: we use the default SHA256 here, might need to support other - hash functions as well */ - dtls_hash_init(&handshake->hs_state.hs_hash); - } - return handshake; -} - -void dtls_handshake_free(dtls_handshake_parameters_t *handshake) -{ - if (!handshake) - return; - - netq_delete_all(handshake->reorder_queue); - dtls_handshake_dealloc(handshake); -} - -dtls_security_parameters_t *dtls_security_new() -{ - dtls_security_parameters_t *security; - - security = dtls_security_malloc(); - if (!security) { - dtls_crit("can not allocate a security struct\n"); - return NULL; - } - - memset(security, 0, sizeof(*security)); - - if (security) { - security->cipher = TLS_NULL_WITH_NULL_NULL; - security->compression = TLS_COMPRESSION_NULL; - } - return security; -} - -void dtls_security_free(dtls_security_parameters_t *security) -{ - if (!security) - return; - - dtls_security_dealloc(security); -} - -size_t -dtls_p_hash(dtls_hashfunc_t h, - const unsigned char *key, size_t keylen, - const unsigned char *label, size_t labellen, - const unsigned char *random1, size_t random1len, - const unsigned char *random2, size_t random2len, - unsigned char *buf, size_t buflen) { - dtls_hmac_context_t *hmac_a, *hmac_p; - - unsigned char A[DTLS_HMAC_DIGEST_SIZE]; - unsigned char tmp[DTLS_HMAC_DIGEST_SIZE]; - size_t dlen; /* digest length */ - size_t len = 0; /* result length */ - - hmac_a = dtls_hmac_new(key, keylen); - if (!hmac_a) - return 0; - - /* calculate A(1) from A(0) == seed */ - HMAC_UPDATE_SEED(hmac_a, label, labellen); - HMAC_UPDATE_SEED(hmac_a, random1, random1len); - HMAC_UPDATE_SEED(hmac_a, random2, random2len); - - dlen = dtls_hmac_finalize(hmac_a, A); - - hmac_p = dtls_hmac_new(key, keylen); - if (!hmac_p) - goto error; - - while (len + dlen < buflen) { - - /* FIXME: rewrite loop to avoid superflous call to dtls_hmac_init() */ - dtls_hmac_init(hmac_p, key, keylen); - dtls_hmac_update(hmac_p, A, dlen); - - HMAC_UPDATE_SEED(hmac_p, label, labellen); - HMAC_UPDATE_SEED(hmac_p, random1, random1len); - HMAC_UPDATE_SEED(hmac_p, random2, random2len); - - len += dtls_hmac_finalize(hmac_p, tmp); - memcpy(buf, tmp, dlen); - buf += dlen; - - /* calculate A(i+1) */ - dtls_hmac_init(hmac_a, key, keylen); - dtls_hmac_update(hmac_a, A, dlen); - dtls_hmac_finalize(hmac_a, A); - } - - dtls_hmac_init(hmac_p, key, keylen); - dtls_hmac_update(hmac_p, A, dlen); - - HMAC_UPDATE_SEED(hmac_p, label, labellen); - HMAC_UPDATE_SEED(hmac_p, random1, random1len); - HMAC_UPDATE_SEED(hmac_p, random2, random2len); - - dtls_hmac_finalize(hmac_p, tmp); - memcpy(buf, tmp, buflen - len); - - error: - dtls_hmac_free(hmac_a); - dtls_hmac_free(hmac_p); - - return buflen; -} - -size_t -dtls_prf(const unsigned char *key, size_t keylen, - const unsigned char *label, size_t labellen, - const unsigned char *random1, size_t random1len, - const unsigned char *random2, size_t random2len, - unsigned char *buf, size_t buflen) { - - /* Clear the result buffer */ - memset(buf, 0, buflen); - return dtls_p_hash(HASH_SHA256, - key, keylen, - label, labellen, - random1, random1len, - random2, random2len, - buf, buflen); -} - -void -dtls_mac(dtls_hmac_context_t *hmac_ctx, - const unsigned char *record, - const unsigned char *packet, size_t length, - unsigned char *buf) { - uint16 L; - dtls_int_to_uint16(L, length); - - assert(hmac_ctx); - dtls_hmac_update(hmac_ctx, record +3, sizeof(uint16) + sizeof(uint48)); - dtls_hmac_update(hmac_ctx, record, sizeof(uint8) + sizeof(uint16)); - dtls_hmac_update(hmac_ctx, L, sizeof(uint16)); - dtls_hmac_update(hmac_ctx, packet, length); - - dtls_hmac_finalize(hmac_ctx, buf); -} - -static size_t -dtls_ccm_encrypt(aes128_ccm_t *ccm_ctx, const unsigned char *src, size_t srclen, - unsigned char *buf, - unsigned char *nounce, - const unsigned char *aad, size_t la) { - long int len; - - assert(ccm_ctx); - - len = dtls_ccm_encrypt_message(&ccm_ctx->ctx, 8 /* M */, - max(2, 15 - DTLS_CCM_NONCE_SIZE), - nounce, - buf, srclen, - aad, la); - return len; -} - -static size_t -dtls_ccm_decrypt(aes128_ccm_t *ccm_ctx, const unsigned char *src, - size_t srclen, unsigned char *buf, - unsigned char *nounce, - const unsigned char *aad, size_t la) { - long int len; - - assert(ccm_ctx); - - len = dtls_ccm_decrypt_message(&ccm_ctx->ctx, 8 /* M */, - max(2, 15 - DTLS_CCM_NONCE_SIZE), - nounce, - buf, srclen, - aad, la); - return len; -} - -#ifdef DTLS_PSK -int -dtls_psk_pre_master_secret(unsigned char *key, size_t keylen, - unsigned char *result, size_t result_len) { - unsigned char *p = result; - - if (result_len < (2 * (sizeof(uint16) + keylen))) { - return -1; - } - - dtls_int_to_uint16(p, keylen); - p += sizeof(uint16); - - memset(p, 0, keylen); - p += keylen; - - memcpy(p, result, sizeof(uint16)); - p += sizeof(uint16); - - memcpy(p, key, keylen); - - return 2 * (sizeof(uint16) + keylen); -} -#endif /* DTLS_PSK */ - -#ifdef DTLS_ECC -static void dtls_ec_key_to_uint32(const unsigned char *key, size_t key_size, - uint32_t *result) { - int i; - - for (i = (key_size / sizeof(uint32_t)) - 1; i >= 0 ; i--) { - *result = dtls_uint32_to_int(&key[i * sizeof(uint32_t)]); - result++; - } -} - -static void dtls_ec_key_from_uint32(const uint32_t *key, size_t key_size, - unsigned char *result) { - int i; - - for (i = (key_size / sizeof(uint32_t)) - 1; i >= 0 ; i--) { - dtls_int_to_uint32(result, key[i]); - result += 4; - } -} - -int dtls_ec_key_from_uint32_asn1(const uint32_t *key, size_t key_size, - unsigned char *buf) { - int i; - unsigned char *buf_orig = buf; - int first = 1; - - for (i = (key_size / sizeof(uint32_t)) - 1; i >= 0 ; i--) { - if (key[i] == 0) - continue; - /* the first bit has to be set to zero, to indicate a poritive integer */ - if (first && key[i] & 0x80000000) { - *buf = 0; - buf++; - dtls_int_to_uint32(buf, key[i]); - buf += 4; - } else if (first && !(key[i] & 0xFF800000)) { - buf[0] = (key[i] >> 16) & 0xff; - buf[1] = (key[i] >> 8) & 0xff; - buf[2] = key[i] & 0xff; - buf += 3; - } else if (first && !(key[i] & 0xFFFF8000)) { - buf[0] = (key[i] >> 8) & 0xff; - buf[1] = key[i] & 0xff; - buf += 2; - } else if (first && !(key[i] & 0xFFFFFF80)) { - buf[0] = key[i] & 0xff; - buf += 1; - } else { - dtls_int_to_uint32(buf, key[i]); - buf += 4; - } - first = 0; - } - return buf - buf_orig; -} - -int dtls_ecdh_pre_master_secret(unsigned char *priv_key, - unsigned char *pub_key_x, - unsigned char *pub_key_y, - size_t key_size, - unsigned char *result, - size_t result_len) { - uint32_t priv[8]; - uint32_t pub_x[8]; - uint32_t pub_y[8]; - uint32_t result_x[8]; - uint32_t result_y[8]; - - if (result_len < key_size) { - return -1; - } - - dtls_ec_key_to_uint32(priv_key, key_size, priv); - dtls_ec_key_to_uint32(pub_key_x, key_size, pub_x); - dtls_ec_key_to_uint32(pub_key_y, key_size, pub_y); - - ecc_ecdh(pub_x, pub_y, priv, result_x, result_y); - - dtls_ec_key_from_uint32(result_x, key_size, result); - return key_size; -} - -void -dtls_ecdsa_generate_key(unsigned char *priv_key, - unsigned char *pub_key_x, - unsigned char *pub_key_y, - size_t key_size) { - uint32_t priv[8]; - uint32_t pub_x[8]; - uint32_t pub_y[8]; - - do { - dtls_prng((unsigned char *)priv, key_size); - } while (!ecc_is_valid_key(priv)); - - ecc_gen_pub_key(priv, pub_x, pub_y); - - dtls_ec_key_from_uint32(priv, key_size, priv_key); - dtls_ec_key_from_uint32(pub_x, key_size, pub_key_x); - dtls_ec_key_from_uint32(pub_y, key_size, pub_key_y); -} - -/* rfc4492#section-5.4 */ -void -dtls_ecdsa_create_sig_hash(const unsigned char *priv_key, size_t key_size, - const unsigned char *sign_hash, size_t sign_hash_size, - uint32_t point_r[9], uint32_t point_s[9]) { - int ret; - uint32_t priv[8]; - uint32_t hash[8]; - uint32_t rand[8]; - - dtls_ec_key_to_uint32(priv_key, key_size, priv); - dtls_ec_key_to_uint32(sign_hash, sign_hash_size, hash); - do { - dtls_prng((unsigned char *)rand, key_size); - ret = ecc_ecdsa_sign(priv, hash, rand, point_r, point_s); - } while (ret); -} - -void -dtls_ecdsa_create_sig(const unsigned char *priv_key, size_t key_size, - const unsigned char *client_random, size_t client_random_size, - const unsigned char *server_random, size_t server_random_size, - const unsigned char *keyx_params, size_t keyx_params_size, - uint32_t point_r[9], uint32_t point_s[9]) { - dtls_hash_ctx data; - unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE]; - - dtls_hash_init(&data); - dtls_hash_update(&data, client_random, client_random_size); - dtls_hash_update(&data, server_random, server_random_size); - dtls_hash_update(&data, keyx_params, keyx_params_size); - dtls_hash_finalize(sha256hash, &data); - - dtls_ecdsa_create_sig_hash(priv_key, key_size, sha256hash, - sizeof(sha256hash), point_r, point_s); -} - -/* rfc4492#section-5.4 */ -int -dtls_ecdsa_verify_sig_hash(const unsigned char *pub_key_x, - const unsigned char *pub_key_y, size_t key_size, - const unsigned char *sign_hash, size_t sign_hash_size, - unsigned char *result_r, unsigned char *result_s) { - uint32_t pub_x[8]; - uint32_t pub_y[8]; - uint32_t hash[8]; - uint32_t point_r[8]; - uint32_t point_s[8]; - - dtls_ec_key_to_uint32(pub_key_x, key_size, pub_x); - dtls_ec_key_to_uint32(pub_key_y, key_size, pub_y); - dtls_ec_key_to_uint32(result_r, key_size, point_r); - dtls_ec_key_to_uint32(result_s, key_size, point_s); - dtls_ec_key_to_uint32(sign_hash, sign_hash_size, hash); - - return ecc_ecdsa_validate(pub_x, pub_y, hash, point_r, point_s); -} - -int -dtls_ecdsa_verify_sig(const unsigned char *pub_key_x, - const unsigned char *pub_key_y, size_t key_size, - const unsigned char *client_random, size_t client_random_size, - const unsigned char *server_random, size_t server_random_size, - const unsigned char *keyx_params, size_t keyx_params_size, - unsigned char *result_r, unsigned char *result_s) { - dtls_hash_ctx data; - unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE]; - - dtls_hash_init(&data); - dtls_hash_update(&data, client_random, client_random_size); - dtls_hash_update(&data, server_random, server_random_size); - dtls_hash_update(&data, keyx_params, keyx_params_size); - dtls_hash_finalize(sha256hash, &data); - - return dtls_ecdsa_verify_sig_hash(pub_key_x, pub_key_y, key_size, sha256hash, - sizeof(sha256hash), result_r, result_s); -} -#endif /* DTLS_ECC */ - -int -dtls_encrypt(const unsigned char *src, size_t length, - unsigned char *buf, - unsigned char *nounce, - unsigned char *key, size_t keylen, - const unsigned char *aad, size_t la) -{ - int ret; - struct dtls_cipher_context_t *ctx = dtls_cipher_context_get(); - - ret = rijndael_set_key_enc_only(&ctx->data.ctx, key, 8 * keylen); - if (ret < 0) { - /* cleanup everything in case the key has the wrong size */ - dtls_warn("cannot set rijndael key\n"); - goto error; - } - - if (src != buf) - memmove(buf, src, length); - ret = dtls_ccm_encrypt(&ctx->data, src, length, buf, nounce, aad, la); - -error: - dtls_cipher_context_release(); - return ret; -} - -int -dtls_decrypt(const unsigned char *src, size_t length, - unsigned char *buf, - unsigned char *nounce, - unsigned char *key, size_t keylen, - const unsigned char *aad, size_t la) -{ - int ret; - struct dtls_cipher_context_t *ctx = dtls_cipher_context_get(); - - ret = rijndael_set_key_enc_only(&ctx->data.ctx, key, 8 * keylen); - if (ret < 0) { - /* cleanup everything in case the key has the wrong size */ - dtls_warn("cannot set rijndael key\n"); - goto error; - } - - if (src != buf) - memmove(buf, src, length); - ret = dtls_ccm_decrypt(&ctx->data, src, length, buf, nounce, aad, la); - -error: - dtls_cipher_context_release(); - return ret; -} - diff --git a/net/ip/tinydtls/crypto.h b/net/ip/tinydtls/crypto.h deleted file mode 100644 index 972a174986bcf49542dc6654578b50188342f7c3..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/crypto.h +++ /dev/null @@ -1,359 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2012 Olaf Bergmann - * Copyright (C) 2013 Hauke Mehrtens - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _DTLS_CRYPTO_H_ -#define _DTLS_CRYPTO_H_ - -#include /* for rand() and srand() */ -#include - -#include "t_list.h" - -#include "aes/rijndael.h" - -#include "global.h" -#include "state.h" -#include "numeric.h" -#include "hmac.h" -#include "ccm.h" - -/* TLS_PSK_WITH_AES_128_CCM_8 */ -#define DTLS_MAC_KEY_LENGTH 0 -#define DTLS_KEY_LENGTH 16 /* AES-128 */ -#define DTLS_BLK_LENGTH 16 /* AES-128 */ -#define DTLS_MAC_LENGTH DTLS_HMAC_DIGEST_SIZE -#define DTLS_IV_LENGTH 4 /* length of nonce_explicit */ - -/** - * Maximum size of the generated keyblock. Note that MAX_KEYBLOCK_LENGTH must - * be large enough to hold the pre_master_secret, i.e. twice the length of the - * pre-shared key + 1. - */ -#define MAX_KEYBLOCK_LENGTH \ - (2 * DTLS_MAC_KEY_LENGTH + 2 * DTLS_KEY_LENGTH + 2 * DTLS_IV_LENGTH) - -/** Length of DTLS master_secret */ -#define DTLS_MASTER_SECRET_LENGTH 48 -#define DTLS_RANDOM_LENGTH 32 - -typedef enum { AES128=0 -} dtls_crypto_alg; - -typedef enum { - DTLS_ECDH_CURVE_SECP256R1 -} dtls_ecdh_curve; - -/** Crypto context for TLS_PSK_WITH_AES_128_CCM_8 cipher suite. */ -typedef struct { - rijndael_ctx ctx; /**< AES-128 encryption context */ -} aes128_ccm_t; - -typedef struct dtls_cipher_context_t { - /** numeric identifier of this cipher suite in host byte order. */ - aes128_ccm_t data; /**< The crypto context */ -} dtls_cipher_context_t; - -typedef struct { - uint8 own_eph_priv[32]; - uint8 other_eph_pub_x[32]; - uint8 other_eph_pub_y[32]; - uint8 other_pub_x[32]; - uint8 other_pub_y[32]; -} dtls_handshake_parameters_ecdsa_t; - -/* This is the maximal supported length of the psk client identity and psk - * server identity hint */ -#define DTLS_PSK_MAX_CLIENT_IDENTITY_LEN 32 - -/* This is the maximal supported length of the pre-shared key. */ -#define DTLS_PSK_MAX_KEY_LEN 32 - -typedef struct { - uint16_t id_length; - unsigned char identity[DTLS_PSK_MAX_CLIENT_IDENTITY_LEN]; -} dtls_handshake_parameters_psk_t; - -typedef struct { - dtls_compression_t compression; /**< compression method */ - - dtls_cipher_t cipher; /**< cipher type */ - uint16_t epoch; /**< counter for cipher state changes*/ - uint64_t rseq; /**< sequence number of last record sent */ - - /** - * The key block generated from PRF applied to client and server - * random bytes. The actual size is given by the selected cipher and - * can be calculated using dtls_kb_size(). Use \c dtls_kb_ macros to - * access the components of the key block. - */ - uint8 key_block[MAX_KEYBLOCK_LENGTH]; -} dtls_security_parameters_t; - -typedef struct { - union { - struct random_t { - uint8 client[DTLS_RANDOM_LENGTH]; /**< client random gmt and bytes */ - uint8 server[DTLS_RANDOM_LENGTH]; /**< server random gmt and bytes */ - } random; - /** the session's master secret */ - uint8 master_secret[DTLS_MASTER_SECRET_LENGTH]; - } tmp; - LIST_STRUCT(reorder_queue); /**< the packets to reorder */ - dtls_hs_state_t hs_state; /**< handshake protocol status */ - - dtls_compression_t compression; /**< compression method */ - dtls_cipher_t cipher; /**< cipher type */ - unsigned int do_client_auth:1; - union { -#ifdef DTLS_ECC - dtls_handshake_parameters_ecdsa_t ecdsa; -#endif /* DTLS_ECC */ -#ifdef DTLS_PSK - dtls_handshake_parameters_psk_t psk; -#endif /* DTLS_PSK */ - } keyx; -} dtls_handshake_parameters_t; - -/* The following macros provide access to the components of the - * key_block in the security parameters. */ - -#define dtls_kb_client_mac_secret(Param, Role) ((Param)->key_block) -#define dtls_kb_server_mac_secret(Param, Role) \ - (dtls_kb_client_mac_secret(Param, Role) + DTLS_MAC_KEY_LENGTH) -#define dtls_kb_remote_mac_secret(Param, Role) \ - ((Role) == DTLS_SERVER \ - ? dtls_kb_client_mac_secret(Param, Role) \ - : dtls_kb_server_mac_secret(Param, Role)) -#define dtls_kb_local_mac_secret(Param, Role) \ - ((Role) == DTLS_CLIENT \ - ? dtls_kb_client_mac_secret(Param, Role) \ - : dtls_kb_server_mac_secret(Param, Role)) -#define dtls_kb_mac_secret_size(Param, Role) DTLS_MAC_KEY_LENGTH -#define dtls_kb_client_write_key(Param, Role) \ - (dtls_kb_server_mac_secret(Param, Role) + DTLS_MAC_KEY_LENGTH) -#define dtls_kb_server_write_key(Param, Role) \ - (dtls_kb_client_write_key(Param, Role) + DTLS_KEY_LENGTH) -#define dtls_kb_remote_write_key(Param, Role) \ - ((Role) == DTLS_SERVER \ - ? dtls_kb_client_write_key(Param, Role) \ - : dtls_kb_server_write_key(Param, Role)) -#define dtls_kb_local_write_key(Param, Role) \ - ((Role) == DTLS_CLIENT \ - ? dtls_kb_client_write_key(Param, Role) \ - : dtls_kb_server_write_key(Param, Role)) -#define dtls_kb_key_size(Param, Role) DTLS_KEY_LENGTH -#define dtls_kb_client_iv(Param, Role) \ - (dtls_kb_server_write_key(Param, Role) + DTLS_KEY_LENGTH) -#define dtls_kb_server_iv(Param, Role) \ - (dtls_kb_client_iv(Param, Role) + DTLS_IV_LENGTH) -#define dtls_kb_remote_iv(Param, Role) \ - ((Role) == DTLS_SERVER \ - ? dtls_kb_client_iv(Param, Role) \ - : dtls_kb_server_iv(Param, Role)) -#define dtls_kb_local_iv(Param, Role) \ - ((Role) == DTLS_CLIENT \ - ? dtls_kb_client_iv(Param, Role) \ - : dtls_kb_server_iv(Param, Role)) -#define dtls_kb_iv_size(Param, Role) DTLS_IV_LENGTH - -#define dtls_kb_size(Param, Role) \ - (2 * (dtls_kb_mac_secret_size(Param, Role) + \ - dtls_kb_key_size(Param, Role) + dtls_kb_iv_size(Param, Role))) - -/* just for consistency */ -#define dtls_kb_digest_size(Param, Role) DTLS_MAC_LENGTH - -/** - * Expands the secret and key to a block of DTLS_HMAC_MAX - * size according to the algorithm specified in section 5 of - * RFC 4346. - * - * \param h Identifier of the hash function to use. - * \param key The secret. - * \param keylen Length of \p key. - * \param seed The seed. - * \param seedlen Length of \p seed. - * \param buf Output buffer where the result is XORed into - * The buffe must be capable to hold at least - * \p buflen bytes. - * \return The actual number of bytes written to \p buf or 0 - * on error. - */ -size_t dtls_p_hash(dtls_hashfunc_t h, - const unsigned char *key, size_t keylen, - const unsigned char *label, size_t labellen, - const unsigned char *random1, size_t random1len, - const unsigned char *random2, size_t random2len, - unsigned char *buf, size_t buflen); - -/** - * This function implements the TLS PRF for DTLS_VERSION. For version - * 1.0, the PRF is P_MD5 ^ P_SHA1 while version 1.2 uses - * P_SHA256. Currently, the actual PRF is selected at compile time. - */ -size_t dtls_prf(const unsigned char *key, size_t keylen, - const unsigned char *label, size_t labellen, - const unsigned char *random1, size_t random1len, - const unsigned char *random2, size_t random2len, - unsigned char *buf, size_t buflen); - -/** - * Calculates MAC for record + cleartext packet and places the result - * in \p buf. The given \p hmac_ctx must be initialized with the HMAC - * function to use and the proper secret. As the DTLS mac calculation - * requires data from the record header, \p record must point to a - * buffer of at least \c sizeof(dtls_record_header_t) bytes. Usually, - * the remaining packet will be encrypted, therefore, the cleartext - * is passed separately in \p packet. - * - * \param hmac_ctx The HMAC context to use for MAC calculation. - * \param record The record header. - * \param packet Cleartext payload to apply the MAC to. - * \param length Size of \p packet. - * \param buf A result buffer that is large enough to hold - * the generated digest. - */ -void dtls_mac(dtls_hmac_context_t *hmac_ctx, - const unsigned char *record, - const unsigned char *packet, size_t length, - unsigned char *buf); - -/** - * Encrypts the specified \p src of given \p length, writing the - * result to \p buf. The cipher implementation may add more data to - * the result buffer such as an initialization vector or padding - * (e.g. for block cipers in CBC mode). The caller therefore must - * ensure that \p buf provides sufficient storage to hold the result. - * Usually this means ( 2 + \p length / blocksize ) * blocksize. The - * function returns a value less than zero on error or otherwise the - * number of bytes written. - * - * \param ctx The cipher context to use. - * \param src The data to encrypt. - * \param length The actual size of of \p src. - * \param buf The result buffer. \p src and \p buf must not - * overlap. - * \param aad additional data for AEAD ciphers - * \param aad_length actual size of @p aad - * \return The number of encrypted bytes on success, less than zero - * otherwise. - */ -int dtls_encrypt(const unsigned char *src, size_t length, - unsigned char *buf, - unsigned char *nounce, - unsigned char *key, size_t keylen, - const unsigned char *aad, size_t aad_length); - -/** - * Decrypts the given buffer \p src of given \p length, writing the - * result to \p buf. The function returns \c -1 in case of an error, - * or the number of bytes written. Note that for block ciphers, \p - * length must be a multiple of the cipher's block size. A return - * value between \c 0 and the actual length indicates that only \c n-1 - * block have been processed. Unlike dtls_encrypt(), the source - * and destination of dtls_decrypt() may overlap. - * - * \param ctx The cipher context to use. - * \param src The buffer to decrypt. - * \param length The length of the input buffer. - * \param buf The result buffer. - * \param aad additional authentication data for AEAD ciphers - * \param aad_length actual size of @p aad - * \return Less than zero on error, the number of decrypted bytes - * otherwise. - */ -int dtls_decrypt(const unsigned char *src, size_t length, - unsigned char *buf, - unsigned char *nounce, - unsigned char *key, size_t keylen, - const unsigned char *a_data, size_t a_data_length); - -/* helper functions */ - -/** - * Generates pre_master_sercet from given PSK and fills the result - * according to the "plain PSK" case in section 2 of RFC 4279. - * Diffie-Hellman and RSA key exchange are currently not supported. - * - * @param key The shared key. - * @param keylen Length of @p key in bytes. - * @param result The derived pre master secret. - * @return The actual length of @p result. - */ -int dtls_psk_pre_master_secret(unsigned char *key, size_t keylen, - unsigned char *result, size_t result_len); - -#define DTLS_EC_KEY_SIZE 32 - -int dtls_ecdh_pre_master_secret(unsigned char *priv_key, - unsigned char *pub_key_x, - unsigned char *pub_key_y, - size_t key_size, - unsigned char *result, - size_t result_len); - -void dtls_ecdsa_generate_key(unsigned char *priv_key, - unsigned char *pub_key_x, - unsigned char *pub_key_y, - size_t key_size); - -void dtls_ecdsa_create_sig_hash(const unsigned char *priv_key, size_t key_size, - const unsigned char *sign_hash, size_t sign_hash_size, - uint32_t point_r[9], uint32_t point_s[9]); - -void dtls_ecdsa_create_sig(const unsigned char *priv_key, size_t key_size, - const unsigned char *client_random, size_t client_random_size, - const unsigned char *server_random, size_t server_random_size, - const unsigned char *keyx_params, size_t keyx_params_size, - uint32_t point_r[9], uint32_t point_s[9]); - -int dtls_ecdsa_verify_sig_hash(const unsigned char *pub_key_x, - const unsigned char *pub_key_y, size_t key_size, - const unsigned char *sign_hash, size_t sign_hash_size, - unsigned char *result_r, unsigned char *result_s); - -int dtls_ecdsa_verify_sig(const unsigned char *pub_key_x, - const unsigned char *pub_key_y, size_t key_size, - const unsigned char *client_random, size_t client_random_size, - const unsigned char *server_random, size_t server_random_size, - const unsigned char *keyx_params, size_t keyx_params_size, - unsigned char *result_r, unsigned char *result_s); - -int dtls_ec_key_from_uint32_asn1(const uint32_t *key, size_t key_size, - unsigned char *buf); - - -dtls_handshake_parameters_t *dtls_handshake_new(); - -void dtls_handshake_free(dtls_handshake_parameters_t *handshake); - -dtls_security_parameters_t *dtls_security_new(); - -void dtls_security_free(dtls_security_parameters_t *security); -void crypto_init(); - -#endif /* _DTLS_CRYPTO_H_ */ - diff --git a/net/ip/tinydtls/debug.c b/net/ip/tinydtls/debug.c deleted file mode 100644 index 62ddaaf3db830b05da564bd7561bbde6fce385fd..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/debug.c +++ /dev/null @@ -1,380 +0,0 @@ -/* debug.c -- debug utilities - * - * Copyright (C) 2011--2012 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "tinydtls.h" -#include "dtls_config.h" - -#if defined(HAVE_ASSERT_H) && !defined(assert) -#include -#endif - -#include -#include - -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#ifdef HAVE_TIME_H -#include -#endif - -#include "global.h" -#include "debug.h" -#include "session.h" - -#ifndef NDEBUG -static int maxlog = DTLS_LOG_WARN; /* default maximum log level */ -#endif - -const char *dtls_package_name() { - return PACKAGE_NAME; -} - -const char *dtls_package_version() { - return PACKAGE_VERSION; -} - -#ifndef NDEBUG -log_t -dtls_get_log_level() { - return maxlog; -} - -void -dtls_set_log_level(log_t level) { - maxlog = level; -} -#endif - -#ifndef NDEBUG -/* this array has the same order as the type log_t */ -static char *loglevels[] = { - "EMRG", "ALRT", "CRIT", "WARN", "NOTE", "INFO", "DEBG" -}; -#endif - -#ifdef HAVE_TIME_H - -static inline size_t -print_timestamp(char *s, size_t len, time_t t) { - struct tm *tmp; - tmp = localtime(&t); - return strftime(s, len, "%b %d %H:%M:%S", tmp); -} - -#else /* alternative implementation: just print the timestamp */ - -static inline size_t -print_timestamp(char *s, size_t len, clock_time_t t) { -#ifdef HAVE_SNPRINTF - return snprintf(s, len, "%u.%03u", - (unsigned int)(t / CLOCK_SECOND), - (unsigned int)(t % CLOCK_SECOND)); -#else /* HAVE_SNPRINTF */ - /* @todo do manual conversion of timestamp */ - return 0; -#endif /* HAVE_SNPRINTF */ -} - -#endif /* HAVE_TIME_H */ - -/** - * A length-safe strlen() fake. - * - * @param s The string to count characters != 0. - * @param maxlen The maximum length of @p s. - * - * @return The length of @p s. - */ -static inline size_t -dtls_strnlen(const char *s, size_t maxlen) { - size_t n = 0; - while(*s++ && n < maxlen) - ++n; - return n; -} - -#ifndef min -#define min(a,b) ((a) < (b) ? (a) : (b)) -#endif - -static size_t -dsrv_print_addr(const session_t *addr, char *buf, size_t len) { -#ifdef HAVE_ARPA_INET_H - const void *addrptr = NULL; - in_port_t port; - char *p = buf; - - switch (addr->addr.sa.sa_family) { - case AF_INET: - if (len < INET_ADDRSTRLEN) - return 0; - - addrptr = &addr->addr.sin.sin_addr; - port = ntohs(addr->addr.sin.sin_port); - break; - case AF_INET6: - if (len < INET6_ADDRSTRLEN + 2) - return 0; - - *p++ = '['; - - addrptr = &addr->addr.sin6.sin6_addr; - port = ntohs(addr->addr.sin6.sin6_port); - - break; - default: - memcpy(buf, "(unknown address type)", min(22, len)); - return min(22, len); - } - - if (inet_ntop(addr->addr.sa.sa_family, addrptr, p, len) == 0) { - perror("dsrv_print_addr"); - return 0; - } - - p += dtls_strnlen(p, len); - - if (addr->addr.sa.sa_family == AF_INET6) { - if (p < buf + len) { - *p++ = ']'; - } else - return 0; - } - - p += snprintf(p, buf + len - p + 1, ":%d", port); - - return p - buf; -#else /* HAVE_ARPA_INET_H */ -# if WITH_CONTIKI - char *p = buf; -# if NETSTACK_CONF_WITH_IPV6 - uint8_t i; - const char hex[] = "0123456789ABCDEF"; - - if (len < 41) - return 0; - - *p++ = '['; - - for (i=0; i < 16; i += 2) { - if (i) { - *p++ = ':'; - } - *p++ = hex[(addr->addr.ipaddr.u8[i] & 0xf0) >> 4]; - *p++ = hex[(addr->addr.ipaddr.u8[i] & 0x0f)]; - *p++ = hex[(addr->addr.ipaddr.u8[i+1] & 0xf0) >> 4]; - *p++ = hex[(addr->addr.ipaddr.u8[i+1] & 0x0f)]; - } - *p++ = ']'; -# else /* NETSTACK_CONF_WITH_IPV6 */ -# warning "IPv4 network addresses will not be included in debug output" - - if (len < 21) - return 0; -# endif /* NETSTACK_CONF_WITH_IPV6 */ - if (buf + len - p < 6) - return 0; - - p += sprintf(p, ":%d", uip_htons(addr->addr.port)); - - return p - buf; -# else /* WITH_CONTIKI */ - /* TODO: output addresses manually */ -# warning "inet_ntop() not available, network addresses will not be included in debug output" -# endif /* WITH_CONTIKI */ - return 0; -#endif -} - -#ifndef WITH_CONTIKI -void -dsrv_log(log_t level, char *format, ...) { - static char timebuf[32]; - va_list ap; - FILE *log_fd; - - if (maxlog < level) - return; - - log_fd = level <= DTLS_LOG_CRIT ? stderr : stdout; - - if (print_timestamp(timebuf,sizeof(timebuf), time(NULL))) - fprintf(log_fd, "%s ", timebuf); - - if (level <= DTLS_LOG_DEBUG) - fprintf(log_fd, "%s ", loglevels[level]); - - va_start(ap, format); - vfprintf(log_fd, format, ap); - va_end(ap); - fflush(log_fd); -} -#elif defined (HAVE_VPRINTF) /* WITH_CONTIKI */ -void -dsrv_log(log_t level, char *format, ...) { - static char timebuf[32]; - va_list ap; - - if (maxlog < level) - return; - - if (print_timestamp(timebuf,sizeof(timebuf), clock_time())) - PRINTF("%s ", timebuf); - - if (level <= DTLS_LOG_DEBUG) - PRINTF("%s ", loglevels[level]); - - va_start(ap, format); - vprintf(format, ap); - va_end(ap); -} -#endif /* WITH_CONTIKI */ - -#ifndef NDEBUG -/** dumps packets in usual hexdump format */ -void hexdump(const unsigned char *packet, int length) { - int n = 0; - - while (length--) { - if (n % 16 == 0) - printf("%08X ",n); - - printf("%02X ", *packet++); - - n++; - if (n % 8 == 0) { - if (n % 16 == 0) - printf("\n"); - else - printf(" "); - } - } -} - -/** dump as narrow string of hex digits */ -void dump(unsigned char *buf, size_t len) { - while (len--) - printf("%02x", *buf++); -} - -void dtls_dsrv_log_addr(log_t level, const char *name, const session_t *addr) -{ - char addrbuf[73]; - int len; - - len = dsrv_print_addr(addr, addrbuf, sizeof(addrbuf)); - if (!len) - return; - dsrv_log(level, "%s: %s\n", name, addrbuf); -} - -#ifndef WITH_CONTIKI -void -dtls_dsrv_hexdump_log(log_t level, const char *name, const unsigned char *buf, size_t length, int extend) { - static char timebuf[32]; - FILE *log_fd; - int n = 0; - - if (maxlog < level) - return; - - log_fd = level <= DTLS_LOG_CRIT ? stderr : stdout; - - if (print_timestamp(timebuf, sizeof(timebuf), time(NULL))) - fprintf(log_fd, "%s ", timebuf); - - if (level <= DTLS_LOG_DEBUG) - fprintf(log_fd, "%s ", loglevels[level]); - - if (extend) { - fprintf(log_fd, "%s: (%zu bytes):\n", name, length); - - while (length--) { - if (n % 16 == 0) - fprintf(log_fd, "%08X ", n); - - fprintf(log_fd, "%02X ", *buf++); - - n++; - if (n % 8 == 0) { - if (n % 16 == 0) - fprintf(log_fd, "\n"); - else - fprintf(log_fd, " "); - } - } - } else { - fprintf(log_fd, "%s: (%zu bytes): ", name, length); - while (length--) - fprintf(log_fd, "%02X", *buf++); - } - fprintf(log_fd, "\n"); - - fflush(log_fd); -} -#else /* WITH_CONTIKI */ -void -dtls_dsrv_hexdump_log(log_t level, const char *name, const unsigned char *buf, size_t length, int extend) { - static char timebuf[32]; - int n = 0; - - if (maxlog < level) - return; - - if (print_timestamp(timebuf,sizeof(timebuf), clock_time())) - PRINTF("%s ", timebuf); - - if (level >= 0 && level <= DTLS_LOG_DEBUG) - PRINTF("%s ", loglevels[level]); - - if (extend) { - PRINTF("%s: (%zu bytes):\n", name, length); - - while (length--) { - if (n % 16 == 0) - PRINTF("%08X ", n); - - PRINTF("%02X ", *buf++); - - n++; - if (n % 8 == 0) { - if (n % 16 == 0) - PRINTF("\n"); - else - PRINTF(" "); - } - } - } else { - PRINTF("%s: (%zu bytes): ", name, length); - while (length--) - PRINTF("%02X", *buf++); - } - PRINTF("\n"); -} -#endif /* WITH_CONTIKI */ - -#endif /* NDEBUG */ diff --git a/net/ip/tinydtls/debug.h b/net/ip/tinydtls/debug.h deleted file mode 100644 index c6993574a3a158e69f747af9ad162fddd4d15a6d..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/debug.h +++ /dev/null @@ -1,143 +0,0 @@ -/* debug.h -- debug utilities - * - * Copyright (C) 2011--2012 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _DTLS_DEBUG_H_ -#define _DTLS_DEBUG_H_ - -#include - -#include "dtls_config.h" -#include "global.h" -#include "session.h" - -#ifdef WITH_CONTIKI -# ifndef DEBUG -# define DEBUG DEBUG_PRINT -# endif /* DEBUG */ -#include "contiki/ip/uip-debug.h" - -#ifdef CONTIKI_TARGET_MBXXX -extern char __Stack_Init, _estack; - -static inline void check_stack() { - const char *p = &__Stack_Init; - while (p < &_estack && *p == 0x38) { - p++; - } - - PRINTF("Stack: %d bytes used (%d free)\n", &_estack - p, p - &__Stack_Init); -} -#else /* CONTIKI_TARGET_MBXXX */ -static inline void check_stack() { -} -#endif /* CONTIKI_TARGET_MBXXX */ -#else /* WITH_CONTKI */ -#define PRINTF(...) - -static inline void check_stack() { -} -#endif - -struct __session_t; - -/** Pre-defined log levels akin to what is used in \b syslog. */ -typedef enum { DTLS_LOG_EMERG=0, DTLS_LOG_ALERT, DTLS_LOG_CRIT, DTLS_LOG_WARN, - DTLS_LOG_NOTICE, DTLS_LOG_INFO, DTLS_LOG_DEBUG -} log_t; - -/** Returns a zero-terminated string with the name of this library. */ -const char *dtls_package_name(); - -/** Returns a zero-terminated string with the library version. */ -const char *dtls_package_version(); - -#ifndef NDEBUG -/** Returns the current log level. */ -log_t dtls_get_log_level(); - -/** Sets the log level to the specified value. */ -void dtls_set_log_level(log_t level); - -/** - * Writes the given text to \c stdout. The text is output only when \p - * level is below or equal to the log level that set by - * set_log_level(). */ -#ifdef HAVE_VPRINTF -void dsrv_log(log_t level, char *format, ...); -#else -#define dsrv_log(level, format, ...) PRINTF(format, ##__VA_ARGS__) -#endif - -/** dumps packets in usual hexdump format */ -void hexdump(const unsigned char *packet, int length); - -/** dump as narrow string of hex digits */ -void dump(unsigned char *buf, size_t len); - -void dtls_dsrv_hexdump_log(log_t level, const char *name, const unsigned char *buf, size_t length, int extend); - -void dtls_dsrv_log_addr(log_t level, const char *name, const session_t *addr); - -#else /* NDEBUG */ - -static inline log_t dtls_get_log_level() -{ - return DTLS_LOG_EMERG; -} - -static inline void dtls_set_log_level(log_t level) -{} - -static inline void dsrv_log(log_t level, char *format, ...) -{} - -static inline void hexdump(const unsigned char *packet, int length) -{} - -static inline void dump(unsigned char *buf, size_t len) -{} - -static inline void -dtls_dsrv_hexdump_log(log_t level, const char *name, const unsigned char *buf, size_t length, int extend) -{} - -static inline void -dtls_dsrv_log_addr(log_t level, const char *name, const session_t *addr) -{} - -#endif /* NDEBUG */ - -/* A set of convenience macros for common log levels. */ -#define dtls_emerg(...) dsrv_log(DTLS_LOG_EMERG, __VA_ARGS__) -#define dtls_alert(...) dsrv_log(DTLS_LOG_ALERT, __VA_ARGS__) -#define dtls_crit(...) dsrv_log(DTLS_LOG_CRIT, __VA_ARGS__) -#define dtls_warn(...) dsrv_log(DTLS_LOG_WARN, __VA_ARGS__) -#define dtls_notice(...) dsrv_log(DTLS_LOG_NOTICE, __VA_ARGS__) -#define dtls_info(...) dsrv_log(DTLS_LOG_INFO, __VA_ARGS__) -#define dtls_debug(...) dsrv_log(DTLS_LOG_DEBUG, __VA_ARGS__) -#define dtls_debug_hexdump(name, buf, length) dtls_dsrv_hexdump_log(DTLS_LOG_DEBUG, name, buf, length, 1) -#define dtls_debug_dump(name, buf, length) dtls_dsrv_hexdump_log(DTLS_LOG_DEBUG, name, buf, length, 0) - -#endif /* _DTLS_DEBUG_H_ */ diff --git a/net/ip/tinydtls/doc/Doxyfile.in b/net/ip/tinydtls/doc/Doxyfile.in deleted file mode 100644 index 9f7ffdf59b011dfbfbe8ebd23fba52fa45c22d40..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/doc/Doxyfile.in +++ /dev/null @@ -1,1551 +0,0 @@ -# Doxyfile 1.6.3 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = @PACKAGE_NAME@ - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = @PACKAGE_VERSION@ - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = NO - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it parses. -# With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this tag. -# The format is ext=language, where ext is a file extension, and language is one of -# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, -# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat -# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), -# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen to replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penality. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will rougly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by -# doxygen. The layout file controls the global structure of the generated output files -# in an output format independent way. The create the layout file that represents -# doxygen's defaults, run doxygen with the -l option. You can optionally specify a -# file name after the option, if omitted DoxygenLayout.xml will be used as the name -# of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = .. - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = YES - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER -# are set, an additional index file will be generated that can be used as input for -# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated -# HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. -# For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's -# filter section matches. -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be implemented using a PHP enabled web server instead of at the web client using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server based approach is that it scales better to large projects and allows full text search. The disadvances is that it is more difficult to setup -# and does not have live searching capabilities. - -SERVER_BASED_SEARCH = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = DSRV_NO_DTLS DSRV_NO_PROTOCOL_DEMUX - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = NO - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# By default doxygen will write a font called FreeSans.ttf to the output -# directory and reference it in all dot files that doxygen generates. This -# font does not include all possible unicode characters however, so when you need -# these (or just want a differently looking font) you can specify the font name -# using DOT_FONTNAME. You need need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. - -DOT_FONTNAME = FreeSans - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = YES - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/net/ip/tinydtls/doc/DoxygenLayout.xml b/net/ip/tinydtls/doc/DoxygenLayout.xml deleted file mode 100644 index 1c8525c36d7b479db24062a98fc99a67c854bc19..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/doc/DoxygenLayout.xml +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/net/ip/tinydtls/doc/Makefile.in b/net/ip/tinydtls/doc/Makefile.in deleted file mode 100644 index a07101e40c89c69faf8e81ba6e5c009642ef5443..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/doc/Makefile.in +++ /dev/null @@ -1,36 +0,0 @@ -# the library's version -VERSION:=@PACKAGE_VERSION@ -PACKAGE_TARNAME:=@PACKAGE_TARNAME@ - -# tools -@SET_MAKE@ -SHELL = /bin/sh -MKDIR = mkdir -DOXYGEN= @DOXYGEN@ - -top_builddir = @top_builddir@ -prefix = @prefix@ -datarootdir = @datarootdir@ -docdir = @docdir@ -htmldir = @htmldir@ - -DISTDIR?=$(top_builddir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@ -FILES:=Makefile.in Doxyfile.in html - -doc: Doxyfile - $(DOXYGEN) $< >./doxygen.out 2>&1 - -clean: - @rm -rf html - -distclean: clean - @rm -rf $(DISTDIR) - @rm -f *~ - -dist: doc - test -d $(DISTDIR)/doc || mkdir $(DISTDIR)/doc - cp -r $(FILES) $(DISTDIR)/doc - -install: $(doc) html - test -d $(htmldir) || mkdir -p $(htmldir) - cp -r html/* $(htmldir) diff --git a/net/ip/tinydtls/dtls.c b/net/ip/tinydtls/dtls.c deleted file mode 100644 index 6aed6c85c0ba1c10b9ec179f9735cf8b733febde..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/dtls.c +++ /dev/null @@ -1,4032 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2012,2014 Olaf Bergmann - * Copyright (C) 2013 Hauke Mehrtens - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "tinydtls.h" -#include "dtls_config.h" -#include "dtls_time.h" - -#include -#include -#include -#ifdef HAVE_ASSERT_H -#include -#endif - -#include "debug.h" -#include "numeric.h" -#include "netq.h" -#include "dtls.h" - -#include "alert.h" -#include "session.h" -#include "prng.h" - -#ifdef WITH_SHA256 -# include "sha2/sha2.h" -#endif - -#ifdef WITH_CONTIKI -#include -#endif - -/* This buffer is used when constructing an encrypted message to - * be sent. The size of the buffer pool is 1 so only one packet can be - * sent simultaneously. We need a separate buffer here in order not to - * cause deadlock if we run out of tx buffers in the application. - * This buffer will not contain any protocol headers, so we will - * adjust the length accordingly to save some bytes. - */ -static struct nano_fifo free_tx_bufs; -static NET_BUF_POOL(tx_buffer, 1, IP_BUF_MAX_DATA - UIP_IPUDPH_LEN, - &free_tx_bufs, NULL, 0); - -#define dtls_set_version(H,V) dtls_int_to_uint16((H)->version, (V)) -#define dtls_set_content_type(H,V) ((H)->content_type = (V) & 0xff) -#define dtls_set_length(H,V) ((H)->length = (V)) - -#define dtls_get_content_type(H) ((H)->content_type & 0xff) -#define dtls_get_version(H) dtls_uint16_to_int((H)->version) -#define dtls_get_epoch(H) dtls_uint16_to_int((H)->epoch) -#define dtls_get_sequence_number(H) dtls_uint48_to_ulong((H)->sequence_number) -#define dtls_get_fragment_length(H) dtls_uint24_to_int((H)->fragment_length) - -#define DTLS_RH_LENGTH sizeof(dtls_record_header_t) -#define DTLS_HS_LENGTH sizeof(dtls_handshake_header_t) -#define DTLS_CH_LENGTH sizeof(dtls_client_hello_t) /* no variable length fields! */ -#define DTLS_COOKIE_LENGTH_MAX 32 -#define DTLS_CH_LENGTH_MAX sizeof(dtls_client_hello_t) + DTLS_COOKIE_LENGTH_MAX + 12 + 26 -#define DTLS_HV_LENGTH sizeof(dtls_hello_verify_t) -#define DTLS_SH_LENGTH (2 + DTLS_RANDOM_LENGTH + 1 + 2 + 1) -#define DTLS_CE_LENGTH (3 + 3 + 27 + DTLS_EC_KEY_SIZE + DTLS_EC_KEY_SIZE) -#define DTLS_SKEXEC_LENGTH (1 + 2 + 1 + 1 + DTLS_EC_KEY_SIZE + DTLS_EC_KEY_SIZE + 1 + 1 + 2 + 70) -#define DTLS_SKEXECPSK_LENGTH_MIN 2 -#define DTLS_SKEXECPSK_LENGTH_MAX 2 + DTLS_PSK_MAX_CLIENT_IDENTITY_LEN -#define DTLS_CKXPSK_LENGTH_MIN 2 -#define DTLS_CKXEC_LENGTH (1 + 1 + DTLS_EC_KEY_SIZE + DTLS_EC_KEY_SIZE) -#define DTLS_CV_LENGTH (1 + 1 + 2 + 1 + 1 + 1 + 1 + DTLS_EC_KEY_SIZE + 1 + 1 + DTLS_EC_KEY_SIZE) -#define DTLS_FIN_LENGTH 12 - -#define HS_HDR_LENGTH DTLS_RH_LENGTH + DTLS_HS_LENGTH -#define HV_HDR_LENGTH HS_HDR_LENGTH + DTLS_HV_LENGTH - -#define HIGH(V) (((V) >> 8) & 0xff) -#define LOW(V) ((V) & 0xff) - -#define DTLS_RECORD_HEADER(M) ((dtls_record_header_t *)(M)) -#define DTLS_HANDSHAKE_HEADER(M) ((dtls_handshake_header_t *)(M)) - -#define HANDSHAKE(M) ((dtls_handshake_header_t *)((M) + DTLS_RH_LENGTH)) -#define CLIENTHELLO(M) ((dtls_client_hello_t *)((M) + HS_HDR_LENGTH)) - -/* The length check here should work because dtls_*_to_int() works on - * unsigned char. Otherwise, broken messages could cause severe - * trouble. Note that this macro jumps out of the current program flow - * when the message is too short. Beware! - */ -#define SKIP_VAR_FIELD(P,L,T) { \ - if (L < dtls_ ## T ## _to_int(P) + sizeof(T)) \ - goto error; \ - L -= dtls_ ## T ## _to_int(P) + sizeof(T); \ - P += dtls_ ## T ## _to_int(P) + sizeof(T); \ - } - -/* some constants for the PRF */ -#define PRF_LABEL(Label) prf_label_##Label -#define PRF_LABEL_SIZE(Label) (sizeof(PRF_LABEL(Label)) - 1) - -static const unsigned char prf_label_master[] = "master secret"; -static const unsigned char prf_label_key[] = "key expansion"; -static const unsigned char prf_label_client[] = "client"; -static const unsigned char prf_label_server[] = "server"; -static const unsigned char prf_label_finished[] = " finished"; - -/* first part of Raw public key, the is the start of the Subject Public Key */ -static const unsigned char cert_asn1_header[] = { - 0x30, 0x59, /* SEQUENCE, length 89 bytes */ - 0x30, 0x13, /* SEQUENCE, length 19 bytes */ - 0x06, 0x07, /* OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1) */ - 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, - 0x06, 0x08, /* OBJECT IDENTIFIER prime256v1 (1 2 840 10045 3 1 7) */ - 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, - 0x03, 0x42, 0x00, /* BIT STRING, length 66 bytes, 0 bits unused */ - 0x04 /* uncompressed, followed by the r und s values of the public key */ -}; - -#ifdef WITH_CONTIKI -PROCESS(dtls_retransmit_process, "DTLS retransmit process"); - -static dtls_context_t the_dtls_context; - -static inline dtls_context_t * -malloc_context() { - return &the_dtls_context; -} - -static inline void -free_context(dtls_context_t *context) { -} - -#else /* WITH_CONTIKI */ - -static inline dtls_context_t * -malloc_context() { - return (dtls_context_t *)malloc(sizeof(dtls_context_t)); -} - -static inline void -free_context(dtls_context_t *context) { - free(context); -} -#endif - -void -dtls_init() { - dtls_clock_init(); - crypto_init(); - netq_init(); - peer_init(); - net_buf_pool_init(tx_buffer); -} - -/* Calls cb_alert() with given arguments if defined, otherwise an - * error message is logged and the result is -1. This is just an - * internal helper. - */ -#define CALL(Context, which, ...) \ - ((Context)->h && (Context)->h->which \ - ? (Context)->h->which((Context), ##__VA_ARGS__) \ - : -1) - -static int -dtls_send_multi(dtls_context_t *ctx, dtls_peer_t *peer, - dtls_security_parameters_t *security , session_t *session, - unsigned char type, uint8 *buf_array[], - size_t buf_len_array[], size_t buf_array_len); - -/** - * Sends the fragment of length \p buflen given in \p buf to the - * specified \p peer. The data will be MAC-protected and encrypted - * according to the selected cipher and split into one or more DTLS - * records of the specified \p type. This function returns the number - * of bytes that were sent, or \c -1 if an error occurred. - * - * \param ctx The DTLS context to use. - * \param peer The remote peer. - * \param type The content type of the record. - * \param buf The data to send. - * \param buflen The actual length of \p buf. - * \return Less than zero on error, the number of bytes written otherwise. - */ -static int -dtls_send(dtls_context_t *ctx, dtls_peer_t *peer, unsigned char type, - uint8 *buf, size_t buflen) { - return dtls_send_multi(ctx, peer, dtls_security_params(peer), &peer->session, - type, &buf, &buflen, 1); -} - -/** - * Stops ongoing retransmissions of handshake messages for @p peer. - */ -static void dtls_stop_retransmission(dtls_context_t *context, dtls_peer_t *peer); - -dtls_peer_t * -dtls_get_peer(const dtls_context_t *ctx, const session_t *session) { - dtls_peer_t *p = NULL; - - for (p = list_head(ctx->peers); p; p = list_item_next(p)) - if (dtls_session_equals(&p->session, session)) - return p; - - return p; -} - -static void -dtls_add_peer(dtls_context_t *ctx, dtls_peer_t *peer) { - list_add(ctx->peers, peer); -} - -int -dtls_write(struct dtls_context_t *ctx, - session_t *dst, uint8 *buf, size_t len) { - - dtls_peer_t *peer = dtls_get_peer(ctx, dst); - - /* Check if peer connection already exists */ - if (!peer) { /* no ==> create one */ - int res; - - /* dtls_connect() returns a value greater than zero if a new - * connection attempt is made, 0 for session reuse. */ - res = dtls_connect(ctx, dst); - - return (res >= 0) ? 0 : res; - } else { /* a session exists, check if it is in state connected */ - - if (peer->state != DTLS_STATE_CONNECTED) { - return 0; - } else { - return dtls_send(ctx, peer, DTLS_CT_APPLICATION_DATA, buf, len); - } - } -} - -static int -dtls_get_cookie(uint8 *msg, size_t msglen, uint8 **cookie) { - /* To access the cookie, we have to determine the session id's - * length and skip the whole thing. */ - if (msglen < DTLS_HS_LENGTH + DTLS_CH_LENGTH + sizeof(uint8)) - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - - if (dtls_uint16_to_int(msg + DTLS_HS_LENGTH) != DTLS_VERSION) - return dtls_alert_fatal_create(DTLS_ALERT_PROTOCOL_VERSION); - - msglen -= DTLS_HS_LENGTH + DTLS_CH_LENGTH; - msg += DTLS_HS_LENGTH + DTLS_CH_LENGTH; - - SKIP_VAR_FIELD(msg, msglen, uint8); /* skip session id */ - - if (msglen < (*msg & 0xff) + sizeof(uint8)) - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - - *cookie = msg + sizeof(uint8); - return dtls_uint8_to_int(msg); - - error: - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); -} - -static int -dtls_create_cookie(dtls_context_t *ctx, - session_t *session, - uint8 *msg, size_t msglen, - uint8 *cookie, int *clen) { - unsigned char buf[DTLS_HMAC_MAX]; - size_t len, e; - - /* create cookie with HMAC-SHA256 over: - * - SECRET - * - session parameters (only IP address?) - * - client version - * - random gmt and bytes - * - session id - * - cipher_suites - * - compression method - */ - - /* We use our own buffer as hmac_context instead of a dynamic buffer - * created by dtls_hmac_new() to separate storage space for cookie - * creation from storage that is used in real sessions. Note that - * the buffer size must fit with the default hash algorithm (see - * implementation of dtls_hmac_context_new()). */ - - dtls_hmac_context_t hmac_context; - dtls_hmac_init(&hmac_context, ctx->cookie_secret, DTLS_COOKIE_SECRET_LENGTH); - - dtls_hmac_update(&hmac_context, - (unsigned char *)&session->addr, session->size); - - /* feed in the beginning of the Client Hello up to and including the - session id */ - e = sizeof(dtls_client_hello_t); - e += (*(msg + DTLS_HS_LENGTH + e) & 0xff) + sizeof(uint8); - if (e + DTLS_HS_LENGTH > msglen) - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - - dtls_hmac_update(&hmac_context, msg + DTLS_HS_LENGTH, e); - - /* skip cookie bytes and length byte */ - e += *(uint8 *)(msg + DTLS_HS_LENGTH + e) & 0xff; - e += sizeof(uint8); - if (e + DTLS_HS_LENGTH > msglen) - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - - dtls_hmac_update(&hmac_context, - msg + DTLS_HS_LENGTH + e, - dtls_get_fragment_length(DTLS_HANDSHAKE_HEADER(msg)) - e); - - len = dtls_hmac_finalize(&hmac_context, buf); - - if (len < *clen) { - memset(cookie + len, 0, *clen - len); - *clen = len; - } - - memcpy(cookie, buf, *clen); - return 0; -} - -#ifdef DTLS_CHECK_CONTENTTYPE -/* used to check if a received datagram contains a DTLS message */ -static char const content_types[] = { - DTLS_CT_CHANGE_CIPHER_SPEC, - DTLS_CT_ALERT, - DTLS_CT_HANDSHAKE, - DTLS_CT_APPLICATION_DATA, - 0 /* end marker */ -}; -#endif - -/** - * Checks if \p msg points to a valid DTLS record. If - * - */ -static unsigned int -is_record(uint8 *msg, size_t msglen) { - unsigned int rlen = 0; - - if (msglen >= DTLS_RH_LENGTH /* FIXME allow empty records? */ -#ifdef DTLS_CHECK_CONTENTTYPE - && strchr(content_types, msg[0]) -#endif - && msg[1] == HIGH(DTLS_VERSION) - && msg[2] == LOW(DTLS_VERSION)) - { - rlen = DTLS_RH_LENGTH + - dtls_uint16_to_int(DTLS_RECORD_HEADER(msg)->length); - - /* we do not accept wrong length field in record header */ - if (rlen > msglen) - rlen = 0; - } - - return rlen; -} - -/** - * Initializes \p buf as record header. The caller must ensure that \p - * buf is capable of holding at least \c sizeof(dtls_record_header_t) - * bytes. Increments sequence number counter of \p security. - * \return pointer to the next byte after the written header. - * The length will be set to 0 and has to be changed before sending. - */ -static inline uint8 * -dtls_set_record_header(uint8 type, dtls_security_parameters_t *security, - uint8 *buf) { - - dtls_int_to_uint8(buf, type); - buf += sizeof(uint8); - - dtls_int_to_uint16(buf, DTLS_VERSION); - buf += sizeof(uint16); - - if (security) { - dtls_int_to_uint16(buf, security->epoch); - buf += sizeof(uint16); - - dtls_int_to_uint48(buf, security->rseq); - buf += sizeof(uint48); - - /* increment record sequence counter by 1 */ - security->rseq++; - } else { - memset(buf, 0, sizeof(uint16) + sizeof(uint48)); - buf += sizeof(uint16) + sizeof(uint48); - } - - memset(buf, 0, sizeof(uint16)); - return buf + sizeof(uint16); -} - -/** - * Initializes \p buf as handshake header. The caller must ensure that \p - * buf is capable of holding at least \c sizeof(dtls_handshake_header_t) - * bytes. Increments message sequence number counter of \p peer. - * \return pointer to the next byte after \p buf - */ -static inline uint8 * -dtls_set_handshake_header(uint8 type, dtls_peer_t *peer, - int length, - int frag_offset, int frag_length, - uint8 *buf) { - - dtls_int_to_uint8(buf, type); - buf += sizeof(uint8); - - dtls_int_to_uint24(buf, length); - buf += sizeof(uint24); - - if (peer && peer->handshake_params) { - /* and copy the result to buf */ - dtls_int_to_uint16(buf, peer->handshake_params->hs_state.mseq_s); - - /* increment handshake message sequence counter by 1 */ - peer->handshake_params->hs_state.mseq_s++; - } else { - memset(buf, 0, sizeof(uint16)); - } - buf += sizeof(uint16); - - dtls_int_to_uint24(buf, frag_offset); - buf += sizeof(uint24); - - dtls_int_to_uint24(buf, frag_length); - buf += sizeof(uint24); - - return buf; -} - -/** only one compression method is currently defined */ -static uint8 compression_methods[] = { - TLS_COMPRESSION_NULL -}; - -/** returns true if the cipher matches TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 */ -static inline int is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(dtls_cipher_t cipher) -{ -#ifdef DTLS_ECC - return cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8; -#else - return 0; -#endif /* DTLS_ECC */ -} - -/** returns true if the cipher matches TLS_PSK_WITH_AES_128_CCM_8 */ -static inline int is_tls_psk_with_aes_128_ccm_8(dtls_cipher_t cipher) -{ -#ifdef DTLS_PSK - return cipher == TLS_PSK_WITH_AES_128_CCM_8; -#else - return 0; -#endif /* DTLS_PSK */ -} - -/** returns true if the application is configured for psk */ -static inline int is_psk_supported(dtls_context_t *ctx) -{ -#ifdef DTLS_PSK - return ctx && ctx->h && ctx->h->get_psk_info; -#else - return 0; -#endif /* DTLS_PSK */ -} - -/** returns true if the application is configured for ecdhe_ecdsa */ -static inline int is_ecdsa_supported(dtls_context_t *ctx, int is_client) -{ -#ifdef DTLS_ECC - return ctx && ctx->h && ((!is_client && ctx->h->get_ecdsa_key) || - (is_client && ctx->h->verify_ecdsa_key)); -#else - return 0; -#endif /* DTLS_ECC */ -} - -/** Returns true if the application is configured for ecdhe_ecdsa with - * client authentication */ -static inline int is_ecdsa_client_auth_supported(dtls_context_t *ctx) -{ -#ifdef DTLS_ECC - return ctx && ctx->h && ctx->h->get_ecdsa_key && ctx->h->verify_ecdsa_key; -#else - return 0; -#endif /* DTLS_ECC */ -} - -/** - * Returns @c 1 if @p code is a cipher suite other than @c - * TLS_NULL_WITH_NULL_NULL that we recognize. - * - * @param ctx The current DTLS context - * @param code The cipher suite identifier to check - * @param is_client 1 for a dtls client, 0 for server - * @return @c 1 iff @p code is recognized, - */ -static int -known_cipher(dtls_context_t *ctx, dtls_cipher_t code, int is_client) { - int psk; - int ecdsa; - - psk = is_psk_supported(ctx); - ecdsa = is_ecdsa_supported(ctx, is_client); - return (psk && is_tls_psk_with_aes_128_ccm_8(code)) || - (ecdsa && is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(code)); -} - -/** Dump out the cipher keys and IVs used for the symetric cipher. */ -static void dtls_debug_keyblock(dtls_security_parameters_t *config) -{ - dtls_debug("key_block (%d bytes):\n", dtls_kb_size(config, peer->role)); - dtls_debug_dump(" client_MAC_secret", - dtls_kb_client_mac_secret(config, peer->role), - dtls_kb_mac_secret_size(config, peer->role)); - - dtls_debug_dump(" server_MAC_secret", - dtls_kb_server_mac_secret(config, peer->role), - dtls_kb_mac_secret_size(config, peer->role)); - - dtls_debug_dump(" client_write_key", - dtls_kb_client_write_key(config, peer->role), - dtls_kb_key_size(config, peer->role)); - - dtls_debug_dump(" server_write_key", - dtls_kb_server_write_key(config, peer->role), - dtls_kb_key_size(config, peer->role)); - - dtls_debug_dump(" client_IV", - dtls_kb_client_iv(config, peer->role), - dtls_kb_iv_size(config, peer->role)); - - dtls_debug_dump(" server_IV", - dtls_kb_server_iv(config, peer->role), - dtls_kb_iv_size(config, peer->role)); -} - -/** returns the name of the goven handshake type number. - * see IANA for a full list of types: - * https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-7 - */ -static char *dtls_handshake_type_to_name(int type) -{ - switch (type) { - case DTLS_HT_HELLO_REQUEST: - return "hello_request"; - case DTLS_HT_CLIENT_HELLO: - return "client_hello"; - case DTLS_HT_SERVER_HELLO: - return "server_hello"; - case DTLS_HT_HELLO_VERIFY_REQUEST: - return "hello_verify_request"; - case DTLS_HT_CERTIFICATE: - return "certificate"; - case DTLS_HT_SERVER_KEY_EXCHANGE: - return "server_key_exchange"; - case DTLS_HT_CERTIFICATE_REQUEST: - return "certificate_request"; - case DTLS_HT_SERVER_HELLO_DONE: - return "server_hello_done"; - case DTLS_HT_CERTIFICATE_VERIFY: - return "certificate_verify"; - case DTLS_HT_CLIENT_KEY_EXCHANGE: - return "client_key_exchange"; - case DTLS_HT_FINISHED: - return "finished"; - default: - return "unknown"; - } -} - -/** - * Calculate the pre master secret and after that calculate the master-secret. - */ -static int -calculate_key_block(dtls_context_t *ctx, - dtls_handshake_parameters_t *handshake, - dtls_peer_t *peer, - session_t *session, - dtls_peer_type role) { - unsigned char *pre_master_secret; - int pre_master_len = 0; - dtls_security_parameters_t *security = dtls_security_params_next(peer); - uint8 master_secret[DTLS_MASTER_SECRET_LENGTH]; - - if (!security) { - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - pre_master_secret = security->key_block; - - switch (handshake->cipher) { -#ifdef DTLS_PSK - case TLS_PSK_WITH_AES_128_CCM_8: { - unsigned char psk[DTLS_PSK_MAX_KEY_LEN]; - int len; - - len = CALL(ctx, get_psk_info, session, DTLS_PSK_KEY, - handshake->keyx.psk.identity, - handshake->keyx.psk.id_length, - psk, DTLS_PSK_MAX_KEY_LEN); - if (len < 0) { - dtls_crit("no psk key for session available\n"); - return len; - } - /* Temporarily use the key_block storage space for the pre master secret. */ - pre_master_len = dtls_psk_pre_master_secret(psk, len, - pre_master_secret, - MAX_KEYBLOCK_LENGTH); - - dtls_debug_hexdump("psk", psk, len); - - memset(psk, 0, DTLS_PSK_MAX_KEY_LEN); - if (pre_master_len < 0) { - dtls_crit("the psk was too long, for the pre master secret\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - break; - } -#endif /* DTLS_PSK */ -#ifdef DTLS_ECC - case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: { - pre_master_len = dtls_ecdh_pre_master_secret(handshake->keyx.ecdsa.own_eph_priv, - handshake->keyx.ecdsa.other_eph_pub_x, - handshake->keyx.ecdsa.other_eph_pub_y, - sizeof(handshake->keyx.ecdsa.own_eph_priv), - pre_master_secret, - MAX_KEYBLOCK_LENGTH); - if (pre_master_len < 0) { - dtls_crit("the curve was too long, for the pre master secret\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - break; - } -#endif /* DTLS_ECC */ - default: - dtls_crit("calculate_key_block: unknown cipher\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - dtls_debug_dump("client_random", handshake->tmp.random.client, DTLS_RANDOM_LENGTH); - dtls_debug_dump("server_random", handshake->tmp.random.server, DTLS_RANDOM_LENGTH); - dtls_debug_dump("pre_master_secret", pre_master_secret, pre_master_len); - - dtls_prf(pre_master_secret, pre_master_len, - PRF_LABEL(master), PRF_LABEL_SIZE(master), - handshake->tmp.random.client, DTLS_RANDOM_LENGTH, - handshake->tmp.random.server, DTLS_RANDOM_LENGTH, - master_secret, - DTLS_MASTER_SECRET_LENGTH); - - dtls_debug_dump("master_secret", master_secret, DTLS_MASTER_SECRET_LENGTH); - - /* create key_block from master_secret - * key_block = PRF(master_secret, - "key expansion" + tmp.random.server + tmp.random.client) */ - - dtls_prf(master_secret, - DTLS_MASTER_SECRET_LENGTH, - PRF_LABEL(key), PRF_LABEL_SIZE(key), - handshake->tmp.random.server, DTLS_RANDOM_LENGTH, - handshake->tmp.random.client, DTLS_RANDOM_LENGTH, - security->key_block, - dtls_kb_size(security, role)); - - memcpy(handshake->tmp.master_secret, master_secret, DTLS_MASTER_SECRET_LENGTH); - dtls_debug_keyblock(security); - - security->cipher = handshake->cipher; - security->compression = handshake->compression; - security->rseq = 0; - - return 0; -} - -/* TODO: add a generic method which iterates over a list and searches for a specific key */ -static int verify_ext_eliptic_curves(uint8 *data, size_t data_length) { - int i, curve_name; - - /* length of curve list */ - i = dtls_uint16_to_int(data); - data += sizeof(uint16); - if (i + sizeof(uint16) != data_length) { - dtls_warn("the list of the supported elliptic curves should be tls extension length - 2\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - - for (i = data_length - sizeof(uint16); i > 0; i -= sizeof(uint16)) { - /* check if this curve is supported */ - curve_name = dtls_uint16_to_int(data); - data += sizeof(uint16); - - if (curve_name == TLS_EXT_ELLIPTIC_CURVES_SECP256R1) - return 0; - } - - dtls_warn("no supported elliptic curve found\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); -} - -static int verify_ext_cert_type(uint8 *data, size_t data_length) { - int i, cert_type; - - /* length of cert type list */ - i = dtls_uint8_to_int(data); - data += sizeof(uint8); - if (i + sizeof(uint8) != data_length) { - dtls_warn("the list of the supported certificate types should be tls extension length - 1\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - - for (i = data_length - sizeof(uint8); i > 0; i -= sizeof(uint8)) { - /* check if this cert type is supported */ - cert_type = dtls_uint8_to_int(data); - data += sizeof(uint8); - - if (cert_type == TLS_CERT_TYPE_RAW_PUBLIC_KEY) - return 0; - } - - dtls_warn("no supported certificate type found\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); -} - -static int verify_ext_ec_point_formats(uint8 *data, size_t data_length) { - int i, cert_type; - - /* length of ec_point_formats list */ - i = dtls_uint8_to_int(data); - data += sizeof(uint8); - if (i + sizeof(uint8) != data_length) { - dtls_warn("the list of the supported ec_point_formats should be tls extension length - 1\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - - for (i = data_length - sizeof(uint8); i > 0; i -= sizeof(uint8)) { - /* check if this ec_point_format is supported */ - cert_type = dtls_uint8_to_int(data); - data += sizeof(uint8); - - if (cert_type == TLS_EXT_EC_POINT_FORMATS_UNCOMPRESSED) - return 0; - } - - dtls_warn("no supported ec_point_format found\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); -} - -/* - * Check for some TLS Extensions used by the ECDHE_ECDSA cipher. - */ -static int -dtls_check_tls_extension(dtls_peer_t *peer, - uint8 *data, size_t data_length, int client_hello) -{ - uint16_t i, j; - int ext_elliptic_curve = 0; - int ext_client_cert_type = 0; - int ext_server_cert_type = 0; - int ext_ec_point_formats = 0; - dtls_handshake_parameters_t *handshake = peer->handshake_params; - - if (data_length < sizeof(uint16)) { - /* no tls extensions specified */ - if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher)) { - goto error; - } - return 0; - } - - /* get the length of the tls extension list */ - j = dtls_uint16_to_int(data); - data += sizeof(uint16); - data_length -= sizeof(uint16); - - if (data_length < j) - goto error; - - /* check for TLS extensions needed for this cipher */ - while (data_length) { - if (data_length < sizeof(uint16) * 2) - goto error; - - /* get the tls extension type */ - i = dtls_uint16_to_int(data); - data += sizeof(uint16); - data_length -= sizeof(uint16); - - /* get the length of the tls extension */ - j = dtls_uint16_to_int(data); - data += sizeof(uint16); - data_length -= sizeof(uint16); - - if (data_length < j) - goto error; - - switch (i) { - case TLS_EXT_ELLIPTIC_CURVES: - ext_elliptic_curve = 1; - if (verify_ext_eliptic_curves(data, j)) - goto error; - break; - case TLS_EXT_CLIENT_CERTIFICATE_TYPE: - ext_client_cert_type = 1; - if (client_hello) { - if (verify_ext_cert_type(data, j)) - goto error; - } else { - if (dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY) - goto error; - } - break; - case TLS_EXT_SERVER_CERTIFICATE_TYPE: - ext_server_cert_type = 1; - if (client_hello) { - if (verify_ext_cert_type(data, j)) - goto error; - } else { - if (dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY) - goto error; - } - break; - case TLS_EXT_EC_POINT_FORMATS: - ext_ec_point_formats = 1; - if (verify_ext_ec_point_formats(data, j)) - goto error; - break; - case TLS_EXT_ENCRYPT_THEN_MAC: - /* As only AEAD cipher suites are currently available, this - * extension can be skipped. - */ - dtls_info("skipped encrypt-then-mac extension\n"); - break; - default: - dtls_warn("unsupported tls extension: %i\n", i); - break; - } - data += j; - data_length -= j; - } - if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) && client_hello) { - if (!ext_elliptic_curve || !ext_client_cert_type || !ext_server_cert_type - || !ext_ec_point_formats) { - dtls_warn("not all required tls extensions found in client hello\n"); - goto error; - } - } else if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) && !client_hello) { - if (!ext_client_cert_type || !ext_server_cert_type) { - dtls_warn("not all required tls extensions found in server hello\n"); - goto error; - } - } - return 0; - -error: - if (client_hello && peer->state == DTLS_STATE_CONNECTED) { - return dtls_alert_create(DTLS_ALERT_LEVEL_WARNING, DTLS_ALERT_NO_RENEGOTIATION); - } else { - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } -} - -/** - * Parses the ClientHello from the client and updates the internal handshake - * parameters with the new data for the given \p peer. When the ClientHello - * handshake message in \p data does not contain a cipher suite or - * compression method, it is copied from the the current security parameters. - * - * \param ctx The current DTLS context. - * \param peer The remote peer whose security parameters are about to change. - * \param data The handshake message with a ClientHello. - * \param data_length The actual size of \p data. - * \return \c -Something if an error occurred, \c 0 on success. - */ -static int -dtls_update_parameters(dtls_context_t *ctx, - dtls_peer_t *peer, - uint8 *data, size_t data_length) { - int i, j; - int ok; - dtls_handshake_parameters_t *config = peer->handshake_params; - dtls_security_parameters_t *security = dtls_security_params(peer); - - assert(config); - assert(data_length > DTLS_HS_LENGTH + DTLS_CH_LENGTH); - - /* skip the handshake header and client version information */ - data += DTLS_HS_LENGTH + sizeof(uint16); - data_length -= DTLS_HS_LENGTH + sizeof(uint16); - - /* store client random in config */ - memcpy(config->tmp.random.client, data, DTLS_RANDOM_LENGTH); - data += DTLS_RANDOM_LENGTH; - data_length -= DTLS_RANDOM_LENGTH; - - /* Caution: SKIP_VAR_FIELD may jump to error: */ - SKIP_VAR_FIELD(data, data_length, uint8); /* skip session id */ - SKIP_VAR_FIELD(data, data_length, uint8); /* skip cookie */ - - i = dtls_uint16_to_int(data); - if (data_length < i + sizeof(uint16)) { - /* Looks like we do not have a cipher nor compression. This is ok - * for renegotiation, but not for the initial handshake. */ - - if (!security || security->cipher == TLS_NULL_WITH_NULL_NULL) - goto error; - - config->cipher = security->cipher; - config->compression = security->compression; - - return 0; - } - - data += sizeof(uint16); - data_length -= sizeof(uint16) + i; - - ok = 0; - while (i && !ok) { - config->cipher = dtls_uint16_to_int(data); - ok = known_cipher(ctx, config->cipher, 0); - i -= sizeof(uint16); - data += sizeof(uint16); - } - - /* skip remaining ciphers */ - data += i; - - if (!ok) { - /* reset config cipher to a well-defined value */ - config->cipher = TLS_NULL_WITH_NULL_NULL; - dtls_warn("No matching cipher found\n"); - goto error; - } - - if (data_length < sizeof(uint8)) { - /* no compression specified, take the current compression method */ - if (security) - config->compression = security->compression; - else - config->compression = TLS_COMPRESSION_NULL; - return 0; - } - - i = dtls_uint8_to_int(data); - if (data_length < i + sizeof(uint8)) - goto error; - - data += sizeof(uint8); - data_length -= sizeof(uint8) + i; - - ok = 0; - while (i && !ok) { - for (j = 0; j < sizeof(compression_methods) / sizeof(uint8); ++j) - if (dtls_uint8_to_int(data) == compression_methods[j]) { - config->compression = compression_methods[j]; - ok = 1; - } - i -= sizeof(uint8); - data += sizeof(uint8); - } - - if (!ok) { - /* reset config cipher to a well-defined value */ - goto error; - } - - return dtls_check_tls_extension(peer, data, data_length, 1); -error: - if (peer->state == DTLS_STATE_CONNECTED) { - return dtls_alert_create(DTLS_ALERT_LEVEL_WARNING, DTLS_ALERT_NO_RENEGOTIATION); - } else { - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } -} - -/** - * Parse the ClientKeyExchange and update the internal handshake state with - * the new data. - */ -static inline int -check_client_keyexchange(dtls_context_t *ctx, - dtls_handshake_parameters_t *handshake, - uint8 *data, size_t length) { - -#ifdef DTLS_ECC - if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher)) { - - if (length < DTLS_HS_LENGTH + DTLS_CKXEC_LENGTH) { - dtls_debug("The client key exchange is too short\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - data += DTLS_HS_LENGTH; - - if (dtls_uint8_to_int(data) != 1 + 2 * DTLS_EC_KEY_SIZE) { - dtls_alert("expected 65 bytes long public point\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - data += sizeof(uint8); - - if (dtls_uint8_to_int(data) != 4) { - dtls_alert("expected uncompressed public point\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - data += sizeof(uint8); - - memcpy(handshake->keyx.ecdsa.other_eph_pub_x, data, - sizeof(handshake->keyx.ecdsa.other_eph_pub_x)); - data += sizeof(handshake->keyx.ecdsa.other_eph_pub_x); - - memcpy(handshake->keyx.ecdsa.other_eph_pub_y, data, - sizeof(handshake->keyx.ecdsa.other_eph_pub_y)); - data += sizeof(handshake->keyx.ecdsa.other_eph_pub_y); - } -#endif /* DTLS_ECC */ -#ifdef DTLS_PSK - if (is_tls_psk_with_aes_128_ccm_8(handshake->cipher)) { - int id_length; - - if (length < DTLS_HS_LENGTH + DTLS_CKXPSK_LENGTH_MIN) { - dtls_debug("The client key exchange is too short\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - data += DTLS_HS_LENGTH; - - id_length = dtls_uint16_to_int(data); - data += sizeof(uint16); - - if (DTLS_HS_LENGTH + DTLS_CKXPSK_LENGTH_MIN + id_length != length) { - dtls_debug("The identity has a wrong length\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - - if (id_length > DTLS_PSK_MAX_CLIENT_IDENTITY_LEN) { - dtls_warn("please use a smaller client identity\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - handshake->keyx.psk.id_length = id_length; - memcpy(handshake->keyx.psk.identity, data, id_length); - } -#endif /* DTLS_PSK */ - return 0; -} - -static inline void -update_hs_hash(dtls_peer_t *peer, uint8 *data, size_t length) { - dtls_debug_dump("add MAC data", data, length); - dtls_hash_update(&peer->handshake_params->hs_state.hs_hash, data, length); -} - -static void -copy_hs_hash(dtls_peer_t *peer, dtls_hash_ctx *hs_hash) { - memcpy(hs_hash, &peer->handshake_params->hs_state.hs_hash, - sizeof(peer->handshake_params->hs_state.hs_hash)); -} - -static inline size_t -finalize_hs_hash(dtls_peer_t *peer, uint8 *buf) { - return dtls_hash_finalize(buf, &peer->handshake_params->hs_state.hs_hash); -} - -static inline void -clear_hs_hash(dtls_peer_t *peer) { - assert(peer); - dtls_debug("clear MAC\n"); - dtls_hash_init(&peer->handshake_params->hs_state.hs_hash); -} - -/** - * Checks if \p record + \p data contain a Finished message with valid - * verify_data. - * - * \param ctx The current DTLS context. - * \param peer The remote peer of the security association. - * \param data The cleartext payload of the message. - * \param data_length Actual length of \p data. - * \return \c 0 if the Finished message is valid, \c negative number otherwise. - */ -static int -check_finished(dtls_context_t *ctx, dtls_peer_t *peer, - uint8 *data, size_t data_length) { - size_t digest_length, label_size; - const unsigned char *label; - unsigned char buf[DTLS_HMAC_MAX]; - - if (data_length < DTLS_HS_LENGTH + DTLS_FIN_LENGTH) - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - - /* Use a union here to ensure that sufficient stack space is - * reserved. As statebuf and verify_data are not used at the same - * time, we can re-use the storage safely. - */ - union { - unsigned char statebuf[DTLS_HASH_CTX_SIZE]; - unsigned char verify_data[DTLS_FIN_LENGTH]; - } b; - - /* temporarily store hash status for roll-back after finalize */ - memcpy(b.statebuf, &peer->handshake_params->hs_state.hs_hash, DTLS_HASH_CTX_SIZE); - - digest_length = finalize_hs_hash(peer, buf); - /* clear_hash(); */ - - /* restore hash status */ - memcpy(&peer->handshake_params->hs_state.hs_hash, b.statebuf, DTLS_HASH_CTX_SIZE); - - if (peer->role == DTLS_CLIENT) { - label = PRF_LABEL(server); - label_size = PRF_LABEL_SIZE(server); - } else { /* server */ - label = PRF_LABEL(client); - label_size = PRF_LABEL_SIZE(client); - } - - dtls_prf(peer->handshake_params->tmp.master_secret, - DTLS_MASTER_SECRET_LENGTH, - label, label_size, - PRF_LABEL(finished), PRF_LABEL_SIZE(finished), - buf, digest_length, - b.verify_data, sizeof(b.verify_data)); - - dtls_debug_dump("d:", data + DTLS_HS_LENGTH, sizeof(b.verify_data)); - dtls_debug_dump("v:", b.verify_data, sizeof(b.verify_data)); - - /* compare verify data and create DTLS alert code when they differ */ - return equals(data + DTLS_HS_LENGTH, b.verify_data, sizeof(b.verify_data)) - ? 0 - : dtls_alert_create(DTLS_ALERT_LEVEL_FATAL, DTLS_ALERT_HANDSHAKE_FAILURE); -} - -/** - * Prepares the payload given in \p data for sending with - * dtls_send(). The \p data is encrypted and compressed according to - * the current security parameters of \p peer. The result of this - * operation is put into \p sendbuf with a prepended record header of - * type \p type ready for sending. As some cipher suites add a MAC - * before encryption, \p data must be large enough to hold this data - * as well (usually \c dtls_kb_digest_size(CURRENT_CONFIG(peer)). - * - * \param peer The remote peer the packet will be sent to. - * \param security The encryption paramater used to encrypt - * \param type The content type of this record. - * \param data_array Array with payloads in correct order. - * \param data_len_array sizes of the payloads in correct order. - * \param data_array_len The number of payloads given. - * \param sendbuf The output buffer where the encrypted record - * will be placed. - * \param rlen This parameter must be initialized with the - * maximum size of \p sendbuf and will be updated - * to hold the actual size of the stored packet - * on success. On error, the value of \p rlen is - * undefined. - * \return Less than zero on error, or greater than zero success. - */ -static int -dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security, - unsigned char type, - uint8 *data_array[], size_t data_len_array[], - size_t data_array_len, - uint8 *sendbuf, size_t *rlen) { - uint8 *p, *start; - int res; - unsigned int i; - - if (*rlen < DTLS_RH_LENGTH) { - dtls_alert("The sendbuf (%d bytes) is too small\n", *rlen); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - p = dtls_set_record_header(type, security, sendbuf); - start = p; - - if (!security || security->cipher == TLS_NULL_WITH_NULL_NULL) { - /* no cipher suite */ - - res = 0; - for (i = 0; i < data_array_len; i++) { - /* check the minimum that we need for packets that are not encrypted */ - if (*rlen < res + DTLS_RH_LENGTH + data_len_array[i]) { - dtls_debug("dtls_prepare_record: send buffer too small\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - memcpy(p, data_array[i], data_len_array[i]); - p += data_len_array[i]; - res += data_len_array[i]; - } - } else { /* TLS_PSK_WITH_AES_128_CCM_8 or TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 */ - /** - * length of additional_data for the AEAD cipher which consists of - * seq_num(2+6) + type(1) + version(2) + length(2) - */ -#define A_DATA_LEN 13 - unsigned char nonce[DTLS_CCM_BLOCKSIZE]; - unsigned char A_DATA[A_DATA_LEN]; - - if (is_tls_psk_with_aes_128_ccm_8(security->cipher)) { - dtls_debug("dtls_prepare_record(): encrypt using TLS_PSK_WITH_AES_128_CCM_8\n"); - } else if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(security->cipher)) { - dtls_debug("dtls_prepare_record(): encrypt using TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8\n"); - } else { - dtls_debug("dtls_prepare_record(): encrypt using unknown cipher\n"); - } - - /* set nonce - from RFC 6655: - The "nonce" input to the AEAD algorithm is exactly that of [RFC5288]: - the "nonce" SHALL be 12 bytes long and is constructed as follows: - (this is an example of a "partially explicit" nonce; see Section - 3.2.1 in [RFC5116]). - - struct { - opaque salt[4]; - opaque nonce_explicit[8]; - } CCMNonce; - - [...] - - In DTLS, the 64-bit seq_num is the 16-bit epoch concatenated with the - 48-bit seq_num. - - When the nonce_explicit is equal to the sequence number, the CCMNonce - will have the structure of the CCMNonceExample given below. - - struct { - uint32 client_write_IV; // low order 32-bits - uint64 seq_num; // TLS sequence number - } CCMClientNonce. - - - struct { - uint32 server_write_IV; // low order 32-bits - uint64 seq_num; // TLS sequence number - } CCMServerNonce. - - - struct { - case client: - CCMClientNonce; - case server: - CCMServerNonce: - } CCMNonceExample; - */ - - memcpy(p, &DTLS_RECORD_HEADER(sendbuf)->epoch, 8); - p += 8; - res = 8; - - for (i = 0; i < data_array_len; i++) { - /* check the minimum that we need for packets that are not encrypted */ - if (*rlen < res + DTLS_RH_LENGTH + data_len_array[i]) { - dtls_debug("dtls_prepare_record: send buffer too small\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - memcpy(p, data_array[i], data_len_array[i]); - p += data_len_array[i]; - res += data_len_array[i]; - } - - memset(nonce, 0, DTLS_CCM_BLOCKSIZE); - memcpy(nonce, dtls_kb_local_iv(security, peer->role), - dtls_kb_iv_size(security, peer->role)); - memcpy(nonce + dtls_kb_iv_size(security, peer->role), start, 8); /* epoch + seq_num */ - - dtls_debug_dump("nonce:", nonce, DTLS_CCM_BLOCKSIZE); - dtls_debug_dump("key:", dtls_kb_local_write_key(security, peer->role), - dtls_kb_key_size(security, peer->role)); - - /* re-use N to create additional data according to RFC 5246, Section 6.2.3.3: - * - * additional_data = seq_num + TLSCompressed.type + - * TLSCompressed.version + TLSCompressed.length; - */ - memcpy(A_DATA, &DTLS_RECORD_HEADER(sendbuf)->epoch, 8); /* epoch and seq_num */ - memcpy(A_DATA + 8, &DTLS_RECORD_HEADER(sendbuf)->content_type, 3); /* type and version */ - dtls_int_to_uint16(A_DATA + 11, res - 8); /* length */ - - res = dtls_encrypt(start + 8, res - 8, start + 8, nonce, - dtls_kb_local_write_key(security, peer->role), - dtls_kb_key_size(security, peer->role), - A_DATA, A_DATA_LEN); - - if (res < 0) - return res; - - res += 8; /* increment res by size of nonce_explicit */ - dtls_debug_dump("message:", start, res); - } - - /* fix length of fragment in sendbuf */ - dtls_int_to_uint16(sendbuf + 11, res); - - *rlen = DTLS_RH_LENGTH + res; - return 0; -} - -static int -dtls_send_handshake_msg_hash(dtls_context_t *ctx, - dtls_peer_t *peer, - session_t *session, - uint8 header_type, - uint8 *data, size_t data_length, - int add_hash) -{ - uint8 buf[DTLS_HS_LENGTH]; - uint8 *data_array[2]; - size_t data_len_array[2]; - int i = 0; - dtls_security_parameters_t *security = peer ? dtls_security_params(peer) : NULL; - - dtls_set_handshake_header(header_type, peer, data_length, 0, - data_length, buf); - - if (add_hash) { - update_hs_hash(peer, buf, sizeof(buf)); - } - data_array[i] = buf; - data_len_array[i] = sizeof(buf); - i++; - - if (data != NULL) { - if (add_hash) { - update_hs_hash(peer, data, data_length); - } - data_array[i] = data; - data_len_array[i] = data_length; - i++; - } - dtls_debug("send handshake packet of type: %s (%i)\n", - dtls_handshake_type_to_name(header_type), header_type); - return dtls_send_multi(ctx, peer, security, session, DTLS_CT_HANDSHAKE, - data_array, data_len_array, i); -} - -static int -dtls_send_handshake_msg(dtls_context_t *ctx, - dtls_peer_t *peer, - uint8 header_type, - uint8 *data, size_t data_length) -{ - return dtls_send_handshake_msg_hash(ctx, peer, &peer->session, - header_type, data, data_length, 1); -} - -/** - * Returns true if the message @p Data is a handshake message that - * must be included in the calculation of verify_data in the Finished - * message. - * - * @param Type The message type. Only handshake messages but the initial - * Client Hello and Hello Verify Request are included in the hash, - * @param Data The PDU to examine. - * @param Length The length of @p Data. - * - * @return @c 1 if @p Data must be included in hash, @c 0 otherwise. - * - * @hideinitializer - */ -#define MUST_HASH(Type, Data, Length) \ - ((Type) == DTLS_CT_HANDSHAKE && \ - ((Data) != NULL) && ((Length) > 0) && \ - ((Data)[0] != DTLS_HT_HELLO_VERIFY_REQUEST) && \ - ((Data)[0] != DTLS_HT_CLIENT_HELLO || \ - ((Length) >= HS_HDR_LENGTH && \ - (dtls_uint16_to_int(DTLS_RECORD_HEADER(Data)->epoch > 0) || \ - (dtls_uint16_to_int(HANDSHAKE(Data)->message_seq) > 0))))) - -/** - * Sends the data passed in @p buf as a DTLS record of type @p type to - * the given peer. The data will be encrypted and compressed according - * to the security parameters for @p peer. - * - * @param ctx The DTLS context in effect. - * @param peer The remote party where the packet is sent. - * @param type The content type of this record. - * @param buf The data to send. - * @param buflen The number of bytes to send from @p buf. - * @return Less than zero in case of an error or the number of - * bytes that have been sent otherwise. - */ -static int -dtls_send_multi(dtls_context_t *ctx, dtls_peer_t *peer, - dtls_security_parameters_t *security , session_t *session, - unsigned char type, uint8 *buf_array[], - size_t buf_len_array[], size_t buf_array_len) -{ - /* We cannot use ctx->sendbuf here as it is reserved for collecting - * the input for this function, i.e. buf == ctx->sendbuf. - * - * TODO: check if we can use the receive buf here. This would mean - * that we might not be able to handle multiple records stuffed in - * one UDP datagram */ -#ifdef WITH_CONTIKI - /* Prepare to receive max. IPv6 frame size packets. */ - struct net_buf *buf; - unsigned char *sendbuf; - size_t len; -#else - unsigned char sendbuf[DTLS_MAX_BUF]; - size_t len = sizeof(sendbuf); -#endif - int res; - unsigned int i; - size_t overall_len = 0; - -#ifdef WITH_CONTIKI - buf = net_buf_get(&free_tx_bufs, 0); - if (!buf) { - return -ENOMEM; - } - sendbuf = buf->data; - len = net_buf_tailroom(buf); /* max application data len */ -#endif - - res = dtls_prepare_record(peer, security, type, buf_array, buf_len_array, buf_array_len, sendbuf, &len); - - if (res < 0) { -#ifdef WITH_CONTIKI - net_buf_unref(buf); -#endif - return res; - } - - /* if (peer && MUST_HASH(peer, type, buf, buflen)) */ - /* update_hs_hash(peer, buf, buflen); */ - - dtls_debug_hexdump("send header", sendbuf, sizeof(dtls_record_header_t)); - for (i = 0; i < buf_array_len; i++) { - dtls_debug_hexdump("send unencrypted", buf_array[i], buf_len_array[i]); - overall_len += buf_len_array[i]; - } - - if ((type == DTLS_CT_HANDSHAKE && buf_array[0][0] != DTLS_HT_HELLO_VERIFY_REQUEST) || - type == DTLS_CT_CHANGE_CIPHER_SPEC) { - /* copy handshake messages other than HelloVerify into retransmit buffer */ - netq_t *n = netq_node_new(overall_len); - if (n) { - dtls_tick_t now; - dtls_ticks(&now); - n->t = now + 2 * CLOCK_SECOND; - n->retransmit_cnt = 0; - n->timeout = 2 * CLOCK_SECOND; - n->peer = peer; - n->epoch = (security) ? security->epoch : 0; - n->type = type; - n->length = 0; - for (i = 0; i < buf_array_len; i++) { - memcpy(n->data + n->length, buf_array[i], buf_len_array[i]); - n->length += buf_len_array[i]; - } - - if (!netq_insert_node(ctx->sendqueue, n)) { - dtls_warn("cannot add packet to retransmit buffer\n"); - netq_node_free(n); -#ifdef WITH_CONTIKI - } else { - /* must set timer within the context of the retransmit process */ - PROCESS_CONTEXT_BEGIN(&dtls_retransmit_process); - etimer_set(&ctx->retransmit_timer, n->timeout, - &dtls_retransmit_process); - PROCESS_CONTEXT_END(&dtls_retransmit_process); -#else /* WITH_CONTIKI */ - dtls_debug("copied to sendqueue\n"); -#endif /* WITH_CONTIKI */ - } - } else - dtls_warn("retransmit buffer full\n"); - } - - /* FIXME: copy to peer's sendqueue (after fragmentation if - * necessary) and initialize retransmit timer */ - res = CALL(ctx, write, session, sendbuf, len); - -#ifdef WITH_CONTIKI - net_buf_unref(buf); -#endif - - /* Guess number of bytes application data actually sent: - * dtls_prepare_record() tells us in len the number of bytes to - * send, res will contain the bytes actually sent. */ - return res <= 0 ? res : overall_len - (len - res); -} - -static inline int -dtls_send_alert(dtls_context_t *ctx, dtls_peer_t *peer, dtls_alert_level_t level, - dtls_alert_t description) { - uint8_t msg[] = { level, description }; - - dtls_send(ctx, peer, DTLS_CT_ALERT, msg, sizeof(msg)); - return 0; -} - -int -dtls_close(dtls_context_t *ctx, const session_t *remote) { - int res = -1; - dtls_peer_t *peer; - - peer = dtls_get_peer(ctx, remote); - - if (peer) { - res = dtls_send_alert(ctx, peer, DTLS_ALERT_LEVEL_FATAL, DTLS_ALERT_CLOSE_NOTIFY); - /* indicate tear down */ - peer->state = DTLS_STATE_CLOSING; - } - return res; -} - -static void dtls_destroy_peer(dtls_context_t *ctx, dtls_peer_t *peer, int unlink) -{ - if (peer->state != DTLS_STATE_CLOSED && peer->state != DTLS_STATE_CLOSING) - dtls_close(ctx, &peer->session); - if (unlink) { - list_remove(ctx->peers, peer); - dtls_dsrv_log_addr(DTLS_LOG_DEBUG, "removed peer", &peer->session); - } - dtls_free_peer(peer); -} - -/** - * Checks a received Client Hello message for a valid cookie. When the - * Client Hello contains no cookie, the function fails and a Hello - * Verify Request is sent to the peer (using the write callback function - * registered with \p ctx). The return value is \c -1 on error, \c 0 when - * undecided, and \c 1 if the Client Hello was good. - * - * \param ctx The DTLS context. - * \param peer The remote party we are talking to, if any. - * \param session Transport address of the remote peer. - * \param msg The received datagram. - * \param msglen Length of \p msg. - * \return \c 1 if msg is a Client Hello with a valid cookie, \c 0 or - * \c -1 otherwise. - */ -static int -dtls_verify_peer(dtls_context_t *ctx, - dtls_peer_t *peer, - session_t *session, - uint8 *data, size_t data_length) -{ - uint8 buf[DTLS_HV_LENGTH + DTLS_COOKIE_LENGTH]; - uint8 *p = buf; - int len = DTLS_COOKIE_LENGTH; - uint8 *cookie = NULL; - int err; -#undef mycookie -#define mycookie (buf + DTLS_HV_LENGTH) - - /* Store cookie where we can reuse it for the HelloVerify request. */ - err = dtls_create_cookie(ctx, session, data, data_length, mycookie, &len); - if (err < 0) - return err; - - dtls_debug_dump("create cookie", mycookie, len); - - assert(len == DTLS_COOKIE_LENGTH); - - /* Perform cookie check. */ - len = dtls_get_cookie(data, data_length, &cookie); - if (len < 0) { - dtls_warn("error while fetching the cookie, err: %i\n", err); - return err; - } - - dtls_debug_dump("compare with cookie", cookie, len); - - /* check if cookies match */ - if (len == DTLS_COOKIE_LENGTH && memcmp(cookie, mycookie, len) == 0) { - dtls_debug("found matching cookie\n"); - return 0; - } - - if (len > 0) { - dtls_debug_dump("invalid cookie", cookie, len); - } else { - dtls_debug("cookie len is 0!\n"); - } - - /* ClientHello did not contain any valid cookie, hence we send a - * HelloVerify request. */ - - dtls_int_to_uint16(p, DTLS_VERSION); - p += sizeof(uint16); - - dtls_int_to_uint8(p, DTLS_COOKIE_LENGTH); - p += sizeof(uint8); - - assert(p == mycookie); - - p += DTLS_COOKIE_LENGTH; - - /* TODO use the same record sequence number as in the ClientHello, - see 4.2.1. Denial-of-Service Countermeasures */ - err = dtls_send_handshake_msg_hash(ctx, peer, session, - DTLS_HT_HELLO_VERIFY_REQUEST, - buf, p - buf, 0); - if (err < 0) { - dtls_warn("cannot send HelloVerify request\n"); - } - return err; /* HelloVerify is sent, now we cannot do anything but wait */ - -#undef mycookie -} - -#ifdef DTLS_ECC -static int -dtls_check_ecdsa_signature_elem(uint8 *data, size_t data_length, - unsigned char **result_r, - unsigned char **result_s) -{ - int i; - uint8 *data_orig = data; - - if (dtls_uint8_to_int(data) != TLS_EXT_SIG_HASH_ALGO_SHA256) { - dtls_alert("only sha256 is supported in certificate verify\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - data += sizeof(uint8); - data_length -= sizeof(uint8); - - if (dtls_uint8_to_int(data) != TLS_EXT_SIG_HASH_ALGO_ECDSA) { - dtls_alert("only ecdsa signature is supported in client verify\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - data += sizeof(uint8); - data_length -= sizeof(uint8); - - if (data_length < dtls_uint16_to_int(data)) { - dtls_alert("signature length wrong\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - data += sizeof(uint16); - data_length -= sizeof(uint16); - - if (dtls_uint8_to_int(data) != 0x30) { - dtls_alert("wrong ASN.1 struct, expected SEQUENCE\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - data += sizeof(uint8); - data_length -= sizeof(uint8); - - if (data_length < dtls_uint8_to_int(data)) { - dtls_alert("signature length wrong\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - data += sizeof(uint8); - data_length -= sizeof(uint8); - - if (dtls_uint8_to_int(data) != 0x02) { - dtls_alert("wrong ASN.1 struct, expected Integer\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - data += sizeof(uint8); - data_length -= sizeof(uint8); - - i = dtls_uint8_to_int(data); - data += sizeof(uint8); - data_length -= sizeof(uint8); - - /* Sometimes these values have a leeding 0 byte */ - *result_r = data + i - DTLS_EC_KEY_SIZE; - - data += i; - data_length -= i; - - if (dtls_uint8_to_int(data) != 0x02) { - dtls_alert("wrong ASN.1 struct, expected Integer\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - data += sizeof(uint8); - data_length -= sizeof(uint8); - - i = dtls_uint8_to_int(data); - data += sizeof(uint8); - data_length -= sizeof(uint8); - - /* Sometimes these values have a leeding 0 byte */ - *result_s = data + i - DTLS_EC_KEY_SIZE; - - data += i; - data_length -= i; - - return data - data_orig; -} - -static int -check_client_certificate_verify(dtls_context_t *ctx, - dtls_peer_t *peer, - uint8 *data, size_t data_length) -{ - dtls_handshake_parameters_t *config = peer->handshake_params; - int ret; - unsigned char *result_r; - unsigned char *result_s; - dtls_hash_ctx hs_hash; - unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE]; - - assert(is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(config->cipher)); - - data += DTLS_HS_LENGTH; - - if (data_length < DTLS_HS_LENGTH + DTLS_CV_LENGTH) { - dtls_alert("the packet length does not match the expected\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - - ret = dtls_check_ecdsa_signature_elem(data, data_length, &result_r, &result_s); - if (ret < 0) { - return ret; - } - data += ret; - data_length -= ret; - - copy_hs_hash(peer, &hs_hash); - - dtls_hash_finalize(sha256hash, &hs_hash); - - ret = dtls_ecdsa_verify_sig_hash(config->keyx.ecdsa.other_pub_x, config->keyx.ecdsa.other_pub_y, - sizeof(config->keyx.ecdsa.other_pub_x), - sha256hash, sizeof(sha256hash), - result_r, result_s); - - if (ret < 0) { - dtls_alert("wrong signature err: %i\n", ret); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - return 0; -} -#endif /* DTLS_ECC */ - -static int -dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer) -{ - /* Ensure that the largest message to create fits in our source - * buffer. (The size of the destination buffer is checked by the - * encoding function, so we do not need to guess.) */ - uint8 buf[DTLS_SH_LENGTH + 2 + 5 + 5 + 8 + 6]; - uint8 *p; - int ecdsa; - uint8 extension_size; - dtls_handshake_parameters_t *handshake = peer->handshake_params; - dtls_tick_t now; - - ecdsa = is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher); - - extension_size = (ecdsa) ? 2 + 5 + 5 + 6 : 0; - - /* Handshake header */ - p = buf; - - /* ServerHello */ - dtls_int_to_uint16(p, DTLS_VERSION); - p += sizeof(uint16); - - /* Set server random: First 4 bytes are the server's Unix timestamp, - * followed by 28 bytes of generate random data. */ - dtls_ticks(&now); - dtls_int_to_uint32(handshake->tmp.random.server, now / CLOCK_SECOND); - dtls_prng(handshake->tmp.random.server + 4, 28); - - memcpy(p, handshake->tmp.random.server, DTLS_RANDOM_LENGTH); - p += DTLS_RANDOM_LENGTH; - - *p++ = 0; /* no session id */ - - if (handshake->cipher != TLS_NULL_WITH_NULL_NULL) { - /* selected cipher suite */ - dtls_int_to_uint16(p, handshake->cipher); - p += sizeof(uint16); - - /* selected compression method */ - *p++ = compression_methods[handshake->compression]; - } - - if (extension_size) { - /* length of the extensions */ - dtls_int_to_uint16(p, extension_size - 2); - p += sizeof(uint16); - } - - if (ecdsa) { - /* client certificate type extension */ - dtls_int_to_uint16(p, TLS_EXT_CLIENT_CERTIFICATE_TYPE); - p += sizeof(uint16); - - /* length of this extension type */ - dtls_int_to_uint16(p, 1); - p += sizeof(uint16); - - dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY); - p += sizeof(uint8); - - /* client certificate type extension */ - dtls_int_to_uint16(p, TLS_EXT_SERVER_CERTIFICATE_TYPE); - p += sizeof(uint16); - - /* length of this extension type */ - dtls_int_to_uint16(p, 1); - p += sizeof(uint16); - - dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY); - p += sizeof(uint8); - - /* ec_point_formats */ - dtls_int_to_uint16(p, TLS_EXT_EC_POINT_FORMATS); - p += sizeof(uint16); - - /* length of this extension type */ - dtls_int_to_uint16(p, 2); - p += sizeof(uint16); - - /* number of supported formats */ - dtls_int_to_uint8(p, 1); - p += sizeof(uint8); - - dtls_int_to_uint8(p, TLS_EXT_EC_POINT_FORMATS_UNCOMPRESSED); - p += sizeof(uint8); - } - - assert(p - buf <= sizeof(buf)); - - /* TODO use the same record sequence number as in the ClientHello, - see 4.2.1. Denial-of-Service Countermeasures */ - return dtls_send_handshake_msg(ctx, peer, DTLS_HT_SERVER_HELLO, - buf, p - buf); -} - -#ifdef DTLS_ECC -static int -dtls_send_certificate_ecdsa(dtls_context_t *ctx, dtls_peer_t *peer, - const dtls_ecdsa_key_t *key) -{ - uint8 buf[DTLS_CE_LENGTH]; - uint8 *p; - - /* Certificate - * - * Start message construction at beginning of buffer. */ - p = buf; - - dtls_int_to_uint24(p, 94); /* certificates length */ - p += sizeof(uint24); - - dtls_int_to_uint24(p, 91); /* length of this certificate */ - p += sizeof(uint24); - - memcpy(p, &cert_asn1_header, sizeof(cert_asn1_header)); - p += sizeof(cert_asn1_header); - - memcpy(p, key->pub_key_x, DTLS_EC_KEY_SIZE); - p += DTLS_EC_KEY_SIZE; - - memcpy(p, key->pub_key_y, DTLS_EC_KEY_SIZE); - p += DTLS_EC_KEY_SIZE; - - assert(p - buf <= sizeof(buf)); - - return dtls_send_handshake_msg(ctx, peer, DTLS_HT_CERTIFICATE, - buf, p - buf); -} - -static uint8 * -dtls_add_ecdsa_signature_elem(uint8 *p, uint32_t *point_r, uint32_t *point_s) -{ - int len_r; - int len_s; - -#define R_KEY_OFFSET (1 + 1 + 2 + 1 + 1 + 1 + 1) -#define S_KEY_OFFSET(len_s) (R_KEY_OFFSET + (len_s) + 1 + 1) - /* store the pointer to the r component of the signature and make space */ - len_r = dtls_ec_key_from_uint32_asn1(point_r, DTLS_EC_KEY_SIZE, p + R_KEY_OFFSET); - len_s = dtls_ec_key_from_uint32_asn1(point_s, DTLS_EC_KEY_SIZE, p + S_KEY_OFFSET(len_r)); - -#undef R_KEY_OFFSET -#undef S_KEY_OFFSET - - /* sha256 */ - dtls_int_to_uint8(p, TLS_EXT_SIG_HASH_ALGO_SHA256); - p += sizeof(uint8); - - /* ecdsa */ - dtls_int_to_uint8(p, TLS_EXT_SIG_HASH_ALGO_ECDSA); - p += sizeof(uint8); - - /* length of signature */ - dtls_int_to_uint16(p, len_r + len_s + 2 + 2 + 2); - p += sizeof(uint16); - - /* ASN.1 SEQUENCE */ - dtls_int_to_uint8(p, 0x30); - p += sizeof(uint8); - - dtls_int_to_uint8(p, len_r + len_s + 2 + 2); - p += sizeof(uint8); - - /* ASN.1 Integer r */ - dtls_int_to_uint8(p, 0x02); - p += sizeof(uint8); - - dtls_int_to_uint8(p, len_r); - p += sizeof(uint8); - - /* the pint r was added here */ - p += len_r; - - /* ASN.1 Integer s */ - dtls_int_to_uint8(p, 0x02); - p += sizeof(uint8); - - dtls_int_to_uint8(p, len_s); - p += sizeof(uint8); - - /* the pint s was added here */ - p += len_s; - - return p; -} - -static int -dtls_send_server_key_exchange_ecdh(dtls_context_t *ctx, dtls_peer_t *peer, - const dtls_ecdsa_key_t *key) -{ - /* The ASN.1 Integer representation of an 32 byte unsigned int could be - * 33 bytes long add space for that */ - uint8 buf[DTLS_SKEXEC_LENGTH + 2]; - uint8 *p; - uint8 *key_params; - uint8 *ephemeral_pub_x; - uint8 *ephemeral_pub_y; - uint32_t point_r[9]; - uint32_t point_s[9]; - dtls_handshake_parameters_t *config = peer->handshake_params; - - /* ServerKeyExchange - * - * Start message construction at beginning of buffer. */ - p = buf; - - key_params = p; - /* ECCurveType curve_type: named_curve */ - dtls_int_to_uint8(p, 3); - p += sizeof(uint8); - - /* NamedCurve namedcurve: secp256r1 */ - dtls_int_to_uint16(p, TLS_EXT_ELLIPTIC_CURVES_SECP256R1); - p += sizeof(uint16); - - dtls_int_to_uint8(p, 1 + 2 * DTLS_EC_KEY_SIZE); - p += sizeof(uint8); - - /* This should be an uncompressed point, but I do not have access to the spec. */ - dtls_int_to_uint8(p, 4); - p += sizeof(uint8); - - /* store the pointer to the x component of the pub key and make space */ - ephemeral_pub_x = p; - p += DTLS_EC_KEY_SIZE; - - /* store the pointer to the y component of the pub key and make space */ - ephemeral_pub_y = p; - p += DTLS_EC_KEY_SIZE; - - dtls_ecdsa_generate_key(config->keyx.ecdsa.own_eph_priv, - ephemeral_pub_x, ephemeral_pub_y, - DTLS_EC_KEY_SIZE); - - /* sign the ephemeral and its paramaters */ - dtls_ecdsa_create_sig(key->priv_key, DTLS_EC_KEY_SIZE, - config->tmp.random.client, DTLS_RANDOM_LENGTH, - config->tmp.random.server, DTLS_RANDOM_LENGTH, - key_params, p - key_params, - point_r, point_s); - - p = dtls_add_ecdsa_signature_elem(p, point_r, point_s); - - assert(p - buf <= sizeof(buf)); - - return dtls_send_handshake_msg(ctx, peer, DTLS_HT_SERVER_KEY_EXCHANGE, - buf, p - buf); -} -#endif /* DTLS_ECC */ - -#ifdef DTLS_PSK -static int -dtls_send_server_key_exchange_psk(dtls_context_t *ctx, dtls_peer_t *peer, - const unsigned char *psk_hint, size_t len) -{ - uint8 buf[DTLS_SKEXECPSK_LENGTH_MAX]; - uint8 *p; - - p = buf; - - assert(len <= DTLS_PSK_MAX_CLIENT_IDENTITY_LEN); - if (len > DTLS_PSK_MAX_CLIENT_IDENTITY_LEN) { - /* should never happen */ - dtls_warn("psk identity hint is too long\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - dtls_int_to_uint16(p, len); - p += sizeof(uint16); - - memcpy(p, psk_hint, len); - p += len; - - assert(p - buf <= sizeof(buf)); - - return dtls_send_handshake_msg(ctx, peer, DTLS_HT_SERVER_KEY_EXCHANGE, - buf, p - buf); -} -#endif /* DTLS_PSK */ - -#ifdef DTLS_ECC -static int -dtls_send_server_certificate_request(dtls_context_t *ctx, dtls_peer_t *peer) -{ - uint8 buf[8]; - uint8 *p; - - /* ServerHelloDone - * - * Start message construction at beginning of buffer. */ - p = buf; - - /* certificate_types */ - dtls_int_to_uint8(p, 1); - p += sizeof(uint8); - - /* ecdsa_sign */ - dtls_int_to_uint8(p, TLS_CLIENT_CERTIFICATE_TYPE_ECDSA_SIGN); - p += sizeof(uint8); - - /* supported_signature_algorithms */ - dtls_int_to_uint16(p, 2); - p += sizeof(uint16); - - /* sha256 */ - dtls_int_to_uint8(p, TLS_EXT_SIG_HASH_ALGO_SHA256); - p += sizeof(uint8); - - /* ecdsa */ - dtls_int_to_uint8(p, TLS_EXT_SIG_HASH_ALGO_ECDSA); - p += sizeof(uint8); - - /* certificate_authoritiess */ - dtls_int_to_uint16(p, 0); - p += sizeof(uint16); - - assert(p - buf <= sizeof(buf)); - - return dtls_send_handshake_msg(ctx, peer, DTLS_HT_CERTIFICATE_REQUEST, - buf, p - buf); -} -#endif /* DTLS_ECC */ - -static int -dtls_send_server_hello_done(dtls_context_t *ctx, dtls_peer_t *peer) -{ - - /* ServerHelloDone - * - * Start message construction at beginning of buffer. */ - - return dtls_send_handshake_msg(ctx, peer, DTLS_HT_SERVER_HELLO_DONE, - NULL, 0); -} - -static int -dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer) -{ - int res; - - res = dtls_send_server_hello(ctx, peer); - - if (res < 0) { - dtls_debug("dtls_server_hello: cannot prepare ServerHello record\n"); - return res; - } - -#ifdef DTLS_ECC - if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher)) { - const dtls_ecdsa_key_t *ecdsa_key; - - res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key); - if (res < 0) { - dtls_crit("no ecdsa certificate to send in certificate\n"); - return res; - } - - res = dtls_send_certificate_ecdsa(ctx, peer, ecdsa_key); - - if (res < 0) { - dtls_debug("dtls_server_hello: cannot prepare Certificate record\n"); - return res; - } - - res = dtls_send_server_key_exchange_ecdh(ctx, peer, ecdsa_key); - - if (res < 0) { - dtls_debug("dtls_server_hello: cannot prepare Server Key Exchange record\n"); - return res; - } - - if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher) && - is_ecdsa_client_auth_supported(ctx)) { - res = dtls_send_server_certificate_request(ctx, peer); - - if (res < 0) { - dtls_debug("dtls_server_hello: cannot prepare certificate Request record\n"); - return res; - } - } - } -#endif /* DTLS_ECC */ - -#ifdef DTLS_PSK - if (is_tls_psk_with_aes_128_ccm_8(peer->handshake_params->cipher)) { - unsigned char psk_hint[DTLS_PSK_MAX_CLIENT_IDENTITY_LEN]; - int len; - - /* The identity hint is optional, therefore we ignore the result - * and check psk only. */ - len = CALL(ctx, get_psk_info, &peer->session, DTLS_PSK_HINT, - NULL, 0, psk_hint, DTLS_PSK_MAX_CLIENT_IDENTITY_LEN); - - if (len < 0) { - dtls_debug("dtls_server_hello: cannot create ServerKeyExchange\n"); - return len; - } - - if (len > 0) { - res = dtls_send_server_key_exchange_psk(ctx, peer, psk_hint, (size_t)len); - - if (res < 0) { - dtls_debug("dtls_server_key_exchange_psk: cannot send server key exchange record\n"); - return res; - } - } - } -#endif /* DTLS_PSK */ - - res = dtls_send_server_hello_done(ctx, peer); - - if (res < 0) { - dtls_debug("dtls_server_hello: cannot prepare ServerHelloDone record\n"); - return res; - } - return 0; -} - -static inline int -dtls_send_ccs(dtls_context_t *ctx, dtls_peer_t *peer) { - uint8 buf[1] = {1}; - - return dtls_send(ctx, peer, DTLS_CT_CHANGE_CIPHER_SPEC, buf, 1); -} - - -static int -dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer) -{ - uint8 buf[DTLS_CKXEC_LENGTH]; - uint8 *p; - dtls_handshake_parameters_t *handshake = peer->handshake_params; - - p = buf; - - switch (handshake->cipher) { -#ifdef DTLS_PSK - case TLS_PSK_WITH_AES_128_CCM_8: { - int len; - - len = CALL(ctx, get_psk_info, &peer->session, DTLS_PSK_IDENTITY, - handshake->keyx.psk.identity, handshake->keyx.psk.id_length, - buf + sizeof(uint16), - min(sizeof(buf) - sizeof(uint16), - sizeof(handshake->keyx.psk.identity))); - if (len < 0) { - dtls_crit("no psk identity set in kx\n"); - return len; - } - - if (len + sizeof(uint16) > DTLS_CKXEC_LENGTH) { - memset(&handshake->keyx.psk, 0, sizeof(dtls_handshake_parameters_psk_t)); - dtls_warn("the psk identity is too long\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - handshake->keyx.psk.id_length = (unsigned int)len; - memcpy(handshake->keyx.psk.identity, p + sizeof(uint16), len); - - dtls_int_to_uint16(p, handshake->keyx.psk.id_length); - p += sizeof(uint16); - - memcpy(p, handshake->keyx.psk.identity, handshake->keyx.psk.id_length); - p += handshake->keyx.psk.id_length; - - break; - } -#endif /* DTLS_PSK */ -#ifdef DTLS_ECC - case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: { - uint8 *ephemeral_pub_x; - uint8 *ephemeral_pub_y; - - dtls_int_to_uint8(p, 1 + 2 * DTLS_EC_KEY_SIZE); - p += sizeof(uint8); - - /* This should be an uncompressed point, but I do not have access to the spec. */ - dtls_int_to_uint8(p, 4); - p += sizeof(uint8); - - ephemeral_pub_x = p; - p += DTLS_EC_KEY_SIZE; - ephemeral_pub_y = p; - p += DTLS_EC_KEY_SIZE; - - dtls_ecdsa_generate_key(peer->handshake_params->keyx.ecdsa.own_eph_priv, - ephemeral_pub_x, ephemeral_pub_y, - DTLS_EC_KEY_SIZE); - - break; - } -#endif /* DTLS_ECC */ - default: - dtls_crit("cipher not supported\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - assert(p - buf <= sizeof(buf)); - - return dtls_send_handshake_msg(ctx, peer, DTLS_HT_CLIENT_KEY_EXCHANGE, - buf, p - buf); -} - -#ifdef DTLS_ECC -static int -dtls_send_certificate_verify_ecdh(dtls_context_t *ctx, dtls_peer_t *peer, - const dtls_ecdsa_key_t *key) -{ - /* The ASN.1 Integer representation of an 32 byte unsigned int could be - * 33 bytes long add space for that */ - uint8 buf[DTLS_CV_LENGTH + 2]; - uint8 *p; - uint32_t point_r[9]; - uint32_t point_s[9]; - dtls_hash_ctx hs_hash; - unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE]; - - /* ServerKeyExchange - * - * Start message construction at beginning of buffer. */ - p = buf; - - copy_hs_hash(peer, &hs_hash); - - dtls_hash_finalize(sha256hash, &hs_hash); - - /* sign the ephemeral and its paramaters */ - dtls_ecdsa_create_sig_hash(key->priv_key, DTLS_EC_KEY_SIZE, - sha256hash, sizeof(sha256hash), - point_r, point_s); - - p = dtls_add_ecdsa_signature_elem(p, point_r, point_s); - - assert(p - buf <= sizeof(buf)); - - return dtls_send_handshake_msg(ctx, peer, DTLS_HT_CERTIFICATE_VERIFY, - buf, p - buf); -} -#endif /* DTLS_ECC */ - -static int -dtls_send_finished(dtls_context_t *ctx, dtls_peer_t *peer, - const unsigned char *label, size_t labellen) -{ - int length; - uint8 hash[DTLS_HMAC_MAX]; - uint8 buf[DTLS_FIN_LENGTH]; - dtls_hash_ctx hs_hash; - uint8 *p = buf; - - copy_hs_hash(peer, &hs_hash); - - length = dtls_hash_finalize(hash, &hs_hash); - - dtls_prf(peer->handshake_params->tmp.master_secret, - DTLS_MASTER_SECRET_LENGTH, - label, labellen, - PRF_LABEL(finished), PRF_LABEL_SIZE(finished), - hash, length, - p, DTLS_FIN_LENGTH); - - dtls_debug_dump("server finished MAC", p, DTLS_FIN_LENGTH); - - p += DTLS_FIN_LENGTH; - - assert(p - buf <= sizeof(buf)); - - return dtls_send_handshake_msg(ctx, peer, DTLS_HT_FINISHED, - buf, p - buf); -} - -static int -dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer, - uint8 cookie[], size_t cookie_length) { - uint8 buf[DTLS_CH_LENGTH_MAX]; - uint8 *p = buf; - uint8_t cipher_size; - uint8_t extension_size; - int psk; - int ecdsa; - dtls_handshake_parameters_t *handshake = peer->handshake_params; - dtls_tick_t now; - - psk = is_psk_supported(ctx); - ecdsa = is_ecdsa_supported(ctx, 1); - - cipher_size = 2 + ((ecdsa) ? 2 : 0) + ((psk) ? 2 : 0); - extension_size = (ecdsa) ? 2 + 6 + 6 + 8 + 6: 0; - - if (cipher_size == 0) { - dtls_crit("no cipher callbacks implemented\n"); - } - - dtls_int_to_uint16(p, DTLS_VERSION); - p += sizeof(uint16); - - if (cookie_length > DTLS_COOKIE_LENGTH_MAX) { - dtls_warn("the cookie is too long\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - - if (cookie_length == 0) { - /* Set client random: First 4 bytes are the client's Unix timestamp, - * followed by 28 bytes of generate random data. */ - dtls_ticks(&now); - dtls_int_to_uint32(handshake->tmp.random.client, now / CLOCK_SECOND); - dtls_prng(handshake->tmp.random.client + sizeof(uint32), - DTLS_RANDOM_LENGTH - sizeof(uint32)); - } - /* we must use the same Client Random as for the previous request */ - memcpy(p, handshake->tmp.random.client, DTLS_RANDOM_LENGTH); - p += DTLS_RANDOM_LENGTH; - - /* session id (length 0) */ - dtls_int_to_uint8(p, 0); - p += sizeof(uint8); - - /* cookie */ - dtls_int_to_uint8(p, cookie_length); - p += sizeof(uint8); - if (cookie_length != 0) { - memcpy(p, cookie, cookie_length); - p += cookie_length; - } - - /* add known cipher(s) */ - dtls_int_to_uint16(p, cipher_size - 2); - p += sizeof(uint16); - - if (ecdsa) { - dtls_int_to_uint16(p, TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8); - p += sizeof(uint16); - } - if (psk) { - dtls_int_to_uint16(p, TLS_PSK_WITH_AES_128_CCM_8); - p += sizeof(uint16); - } - - /* compression method */ - dtls_int_to_uint8(p, 1); - p += sizeof(uint8); - - dtls_int_to_uint8(p, TLS_COMPRESSION_NULL); - p += sizeof(uint8); - - if (extension_size) { - /* length of the extensions */ - dtls_int_to_uint16(p, extension_size - 2); - p += sizeof(uint16); - } - - if (ecdsa) { - /* client certificate type extension */ - dtls_int_to_uint16(p, TLS_EXT_CLIENT_CERTIFICATE_TYPE); - p += sizeof(uint16); - - /* length of this extension type */ - dtls_int_to_uint16(p, 2); - p += sizeof(uint16); - - /* length of the list */ - dtls_int_to_uint8(p, 1); - p += sizeof(uint8); - - dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY); - p += sizeof(uint8); - - /* client certificate type extension */ - dtls_int_to_uint16(p, TLS_EXT_SERVER_CERTIFICATE_TYPE); - p += sizeof(uint16); - - /* length of this extension type */ - dtls_int_to_uint16(p, 2); - p += sizeof(uint16); - - /* length of the list */ - dtls_int_to_uint8(p, 1); - p += sizeof(uint8); - - dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY); - p += sizeof(uint8); - - /* elliptic_curves */ - dtls_int_to_uint16(p, TLS_EXT_ELLIPTIC_CURVES); - p += sizeof(uint16); - - /* length of this extension type */ - dtls_int_to_uint16(p, 4); - p += sizeof(uint16); - - /* length of the list */ - dtls_int_to_uint16(p, 2); - p += sizeof(uint16); - - dtls_int_to_uint16(p, TLS_EXT_ELLIPTIC_CURVES_SECP256R1); - p += sizeof(uint16); - - /* ec_point_formats */ - dtls_int_to_uint16(p, TLS_EXT_EC_POINT_FORMATS); - p += sizeof(uint16); - - /* length of this extension type */ - dtls_int_to_uint16(p, 2); - p += sizeof(uint16); - - /* number of supported formats */ - dtls_int_to_uint8(p, 1); - p += sizeof(uint8); - - dtls_int_to_uint8(p, TLS_EXT_EC_POINT_FORMATS_UNCOMPRESSED); - p += sizeof(uint8); - } - - assert(p - buf <= sizeof(buf)); - - if (cookie_length != 0) - clear_hs_hash(peer); - - return dtls_send_handshake_msg_hash(ctx, peer, &peer->session, - DTLS_HT_CLIENT_HELLO, - buf, p - buf, cookie_length != 0); -} - -static int -check_server_hello(dtls_context_t *ctx, - dtls_peer_t *peer, - uint8 *data, size_t data_length) -{ - dtls_handshake_parameters_t *handshake = peer->handshake_params; - - /* This function is called when we expect a ServerHello (i.e. we - * have sent a ClientHello). We might instead receive a HelloVerify - * request containing a cookie. If so, we must repeat the - * ClientHello with the given Cookie. - */ - if (data_length < DTLS_HS_LENGTH + DTLS_HS_LENGTH) - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - - update_hs_hash(peer, data, data_length); - - /* FIXME: check data_length before accessing fields */ - - /* Get the server's random data and store selected cipher suite - * and compression method (like dtls_update_parameters(). - * Then calculate master secret and wait for ServerHelloDone. When received, - * send ClientKeyExchange (?) and ChangeCipherSpec + ClientFinished. */ - - /* check server version */ - data += DTLS_HS_LENGTH; - data_length -= DTLS_HS_LENGTH; - - if (dtls_uint16_to_int(data) != DTLS_VERSION) { - dtls_alert("unknown DTLS version\n"); - return dtls_alert_fatal_create(DTLS_ALERT_PROTOCOL_VERSION); - } - - data += sizeof(uint16); /* skip version field */ - data_length -= sizeof(uint16); - - /* store server random data */ - memcpy(handshake->tmp.random.server, data, DTLS_RANDOM_LENGTH); - /* skip server random */ - data += DTLS_RANDOM_LENGTH; - data_length -= DTLS_RANDOM_LENGTH; - - SKIP_VAR_FIELD(data, data_length, uint8); /* skip session id */ - - /* Check cipher suite. As we offer all we have, it is sufficient - * to check if the cipher suite selected by the server is in our - * list of known cipher suites. Subsets are not supported. */ - handshake->cipher = dtls_uint16_to_int(data); - if (!known_cipher(ctx, handshake->cipher, 1)) { - dtls_alert("unsupported cipher 0x%02x 0x%02x\n", - data[0], data[1]); - return dtls_alert_fatal_create(DTLS_ALERT_INSUFFICIENT_SECURITY); - } - data += sizeof(uint16); - data_length -= sizeof(uint16); - - /* Check if NULL compression was selected. We do not know any other. */ - if (dtls_uint8_to_int(data) != TLS_COMPRESSION_NULL) { - dtls_alert("unsupported compression method 0x%02x\n", data[0]); - return dtls_alert_fatal_create(DTLS_ALERT_INSUFFICIENT_SECURITY); - } - data += sizeof(uint8); - data_length -= sizeof(uint8); - - return dtls_check_tls_extension(peer, data, data_length, 0); - -error: - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); -} - -static int -check_server_hello_verify_request(dtls_context_t *ctx, - dtls_peer_t *peer, - uint8 *data, size_t data_length) -{ - dtls_hello_verify_t *hv; - int res; - - if (data_length < DTLS_HS_LENGTH + DTLS_HV_LENGTH) - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - - hv = (dtls_hello_verify_t *)(data + DTLS_HS_LENGTH); - - res = dtls_send_client_hello(ctx, peer, hv->cookie, hv->cookie_length); - - if (res < 0) - dtls_warn("cannot send ClientHello\n"); - - return res; -} - -#ifdef DTLS_ECC -static int -check_server_certificate(dtls_context_t *ctx, - dtls_peer_t *peer, - uint8 *data, size_t data_length) -{ - int err; - dtls_handshake_parameters_t *config = peer->handshake_params; - - update_hs_hash(peer, data, data_length); - - assert(is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(config->cipher)); - - data += DTLS_HS_LENGTH; - - if (dtls_uint24_to_int(data) != 94) { - dtls_alert("expect length of 94 bytes for server certificate message\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - data += sizeof(uint24); - - if (dtls_uint24_to_int(data) != 91) { - dtls_alert("expect length of 91 bytes for certificate\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - data += sizeof(uint24); - - if (memcmp(data, cert_asn1_header, sizeof(cert_asn1_header))) { - dtls_alert("got an unexpected Subject public key format\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - data += sizeof(cert_asn1_header); - - memcpy(config->keyx.ecdsa.other_pub_x, data, - sizeof(config->keyx.ecdsa.other_pub_x)); - data += sizeof(config->keyx.ecdsa.other_pub_x); - - memcpy(config->keyx.ecdsa.other_pub_y, data, - sizeof(config->keyx.ecdsa.other_pub_y)); - data += sizeof(config->keyx.ecdsa.other_pub_y); - - err = CALL(ctx, verify_ecdsa_key, &peer->session, - config->keyx.ecdsa.other_pub_x, - config->keyx.ecdsa.other_pub_y, - sizeof(config->keyx.ecdsa.other_pub_x)); - if (err < 0) { - dtls_warn("The certificate was not accepted\n"); - return err; - } - - return 0; -} - -static int -check_server_key_exchange_ecdsa(dtls_context_t *ctx, - dtls_peer_t *peer, - uint8 *data, size_t data_length) -{ - dtls_handshake_parameters_t *config = peer->handshake_params; - int ret; - unsigned char *result_r; - unsigned char *result_s; - unsigned char *key_params; - - update_hs_hash(peer, data, data_length); - - assert(is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(config->cipher)); - - data += DTLS_HS_LENGTH; - - if (data_length < DTLS_HS_LENGTH + DTLS_SKEXEC_LENGTH) { - dtls_alert("the packet length does not match the expected\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - key_params = data; - - if (dtls_uint8_to_int(data) != TLS_EC_CURVE_TYPE_NAMED_CURVE) { - dtls_alert("Only named curves supported\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - data += sizeof(uint8); - data_length -= sizeof(uint8); - - if (dtls_uint16_to_int(data) != TLS_EXT_ELLIPTIC_CURVES_SECP256R1) { - dtls_alert("secp256r1 supported\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - data += sizeof(uint16); - data_length -= sizeof(uint16); - - if (dtls_uint8_to_int(data) != 1 + 2 * DTLS_EC_KEY_SIZE) { - dtls_alert("expected 65 bytes long public point\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - data += sizeof(uint8); - data_length -= sizeof(uint8); - - if (dtls_uint8_to_int(data) != 4) { - dtls_alert("expected uncompressed public point\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - data += sizeof(uint8); - data_length -= sizeof(uint8); - - memcpy(config->keyx.ecdsa.other_eph_pub_x, data, sizeof(config->keyx.ecdsa.other_eph_pub_y)); - data += sizeof(config->keyx.ecdsa.other_eph_pub_y); - data_length -= sizeof(config->keyx.ecdsa.other_eph_pub_y); - - memcpy(config->keyx.ecdsa.other_eph_pub_y, data, sizeof(config->keyx.ecdsa.other_eph_pub_y)); - data += sizeof(config->keyx.ecdsa.other_eph_pub_y); - data_length -= sizeof(config->keyx.ecdsa.other_eph_pub_y); - - ret = dtls_check_ecdsa_signature_elem(data, data_length, &result_r, &result_s); - if (ret < 0) { - return ret; - } - data += ret; - data_length -= ret; - - ret = dtls_ecdsa_verify_sig(config->keyx.ecdsa.other_pub_x, config->keyx.ecdsa.other_pub_y, - sizeof(config->keyx.ecdsa.other_pub_x), - config->tmp.random.client, DTLS_RANDOM_LENGTH, - config->tmp.random.server, DTLS_RANDOM_LENGTH, - key_params, - 1 + 2 + 1 + 1 + (2 * DTLS_EC_KEY_SIZE), - result_r, result_s); - - if (ret < 0) { - dtls_alert("wrong signature\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - return 0; -} -#endif /* DTLS_ECC */ - -#ifdef DTLS_PSK -static int -check_server_key_exchange_psk(dtls_context_t *ctx, - dtls_peer_t *peer, - uint8 *data, size_t data_length) -{ - dtls_handshake_parameters_t *config = peer->handshake_params; - uint16_t len; - - update_hs_hash(peer, data, data_length); - - assert(is_tls_psk_with_aes_128_ccm_8(config->cipher)); - - data += DTLS_HS_LENGTH; - - if (data_length < DTLS_HS_LENGTH + DTLS_SKEXECPSK_LENGTH_MIN) { - dtls_alert("the packet length does not match the expected\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - - len = dtls_uint16_to_int(data); - data += sizeof(uint16); - - if (len != data_length - DTLS_HS_LENGTH - sizeof(uint16)) { - dtls_warn("the length of the server identity hint is worng\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - - if (len > DTLS_PSK_MAX_CLIENT_IDENTITY_LEN) { - dtls_warn("please use a smaller server identity hint\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - /* store the psk_identity_hint in config->keyx.psk for later use */ - config->keyx.psk.id_length = len; - memcpy(config->keyx.psk.identity, data, len); - return 0; -} -#endif /* DTLS_PSK */ - -static int -check_certificate_request(dtls_context_t *ctx, - dtls_peer_t *peer, - uint8 *data, size_t data_length) -{ - unsigned int i; - int auth_alg; - int sig_alg; - int hash_alg; - - update_hs_hash(peer, data, data_length); - - assert(is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher)); - - data += DTLS_HS_LENGTH; - - if (data_length < DTLS_HS_LENGTH + 5) { - dtls_alert("the packet length does not match the expected\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - - i = dtls_uint8_to_int(data); - data += sizeof(uint8); - if (i + 1 > data_length) { - dtls_alert("the cerfificate types are too long\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - - auth_alg = 0; - for (; i > 0 ; i -= sizeof(uint8)) { - if (dtls_uint8_to_int(data) == TLS_CLIENT_CERTIFICATE_TYPE_ECDSA_SIGN - && auth_alg == 0) - auth_alg = dtls_uint8_to_int(data); - data += sizeof(uint8); - } - - if (auth_alg != TLS_CLIENT_CERTIFICATE_TYPE_ECDSA_SIGN) { - dtls_alert("the request authentication algorithm is not supproted\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - - i = dtls_uint16_to_int(data); - data += sizeof(uint16); - if (i + 1 > data_length) { - dtls_alert("the signature and hash algorithm list is too long\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - - hash_alg = 0; - sig_alg = 0; - for (; i > 0 ; i -= sizeof(uint16)) { - int current_hash_alg; - int current_sig_alg; - - current_hash_alg = dtls_uint8_to_int(data); - data += sizeof(uint8); - current_sig_alg = dtls_uint8_to_int(data); - data += sizeof(uint8); - - if (current_hash_alg == TLS_EXT_SIG_HASH_ALGO_SHA256 && hash_alg == 0 && - current_sig_alg == TLS_EXT_SIG_HASH_ALGO_ECDSA && sig_alg == 0) { - hash_alg = current_hash_alg; - sig_alg = current_sig_alg; - } - } - - if (hash_alg != TLS_EXT_SIG_HASH_ALGO_SHA256 || - sig_alg != TLS_EXT_SIG_HASH_ALGO_ECDSA) { - dtls_alert("no supported hash and signature algorithem\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - - /* common names are ignored */ - - peer->handshake_params->do_client_auth = 1; - return 0; -} - -static int -check_server_hellodone(dtls_context_t *ctx, - dtls_peer_t *peer, - uint8 *data, size_t data_length) -{ - int res; -#ifdef DTLS_ECC - const dtls_ecdsa_key_t *ecdsa_key; -#endif /* DTLS_ECC */ - - dtls_handshake_parameters_t *handshake = peer->handshake_params; - - /* calculate master key, send CCS */ - - update_hs_hash(peer, data, data_length); - -#ifdef DTLS_ECC - if (handshake->do_client_auth) { - - res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key); - if (res < 0) { - dtls_crit("no ecdsa certificate to send in certificate\n"); - return res; - } - - res = dtls_send_certificate_ecdsa(ctx, peer, ecdsa_key); - - if (res < 0) { - dtls_debug("dtls_server_hello: cannot prepare Certificate record\n"); - return res; - } - } -#endif /* DTLS_ECC */ - - /* send ClientKeyExchange */ - res = dtls_send_client_key_exchange(ctx, peer); - - if (res < 0) { - dtls_debug("cannot send KeyExchange message\n"); - return res; - } - -#ifdef DTLS_ECC - if (handshake->do_client_auth) { - - res = dtls_send_certificate_verify_ecdh(ctx, peer, ecdsa_key); - - if (res < 0) { - dtls_debug("dtls_server_hello: cannot prepare Certificate record\n"); - return res; - } - } -#endif /* DTLS_ECC */ - - res = calculate_key_block(ctx, handshake, peer, - &peer->session, peer->role); - if (res < 0) { - return res; - } - - res = dtls_send_ccs(ctx, peer); - if (res < 0) { - dtls_debug("cannot send CCS message\n"); - return res; - } - - /* and switch cipher suite */ - dtls_security_params_switch(peer); - - /* Client Finished */ - return dtls_send_finished(ctx, peer, PRF_LABEL(client), PRF_LABEL_SIZE(client)); -} - -static int -decrypt_verify(dtls_peer_t *peer, uint8 *packet, size_t length, - uint8 **cleartext) -{ - dtls_record_header_t *header = DTLS_RECORD_HEADER(packet); - dtls_security_parameters_t *security = dtls_security_params_epoch(peer, dtls_get_epoch(header)); - int clen; - - *cleartext = (uint8 *)packet + sizeof(dtls_record_header_t); - clen = length - sizeof(dtls_record_header_t); - - if (!security) { - dtls_alert("No security context for epoch: %i\n", dtls_get_epoch(header)); - return -1; - } - - if (security->cipher == TLS_NULL_WITH_NULL_NULL) { - /* no cipher suite selected */ - return clen; - } else { /* TLS_PSK_WITH_AES_128_CCM_8 or TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 */ - /** - * length of additional_data for the AEAD cipher which consists of - * seq_num(2+6) + type(1) + version(2) + length(2) - */ -#define A_DATA_LEN 13 - unsigned char nonce[DTLS_CCM_BLOCKSIZE]; - unsigned char A_DATA[A_DATA_LEN]; - - if (clen < 16) /* need at least IV and MAC */ - return -1; - - memset(nonce, 0, DTLS_CCM_BLOCKSIZE); - memcpy(nonce, dtls_kb_remote_iv(security, peer->role), - dtls_kb_iv_size(security, peer->role)); - - /* read epoch and seq_num from message */ - memcpy(nonce + dtls_kb_iv_size(security, peer->role), *cleartext, 8); - *cleartext += 8; - clen -= 8; - - dtls_debug_dump("nonce", nonce, DTLS_CCM_BLOCKSIZE); - dtls_debug_dump("key", dtls_kb_remote_write_key(security, peer->role), - dtls_kb_key_size(security, peer->role)); - dtls_debug_dump("ciphertext", *cleartext, clen); - - /* re-use N to create additional data according to RFC 5246, Section 6.2.3.3: - * - * additional_data = seq_num + TLSCompressed.type + - * TLSCompressed.version + TLSCompressed.length; - */ - memcpy(A_DATA, &DTLS_RECORD_HEADER(packet)->epoch, 8); /* epoch and seq_num */ - memcpy(A_DATA + 8, &DTLS_RECORD_HEADER(packet)->content_type, 3); /* type and version */ - dtls_int_to_uint16(A_DATA + 11, clen - 8); /* length without nonce_explicit */ - - clen = dtls_decrypt(*cleartext, clen, *cleartext, nonce, - dtls_kb_remote_write_key(security, peer->role), - dtls_kb_key_size(security, peer->role), - A_DATA, A_DATA_LEN); - if (clen < 0) - dtls_warn("decryption failed\n"); - else { -#ifndef NDEBUG - printf("decrypt_verify(): found %i bytes cleartext\n", clen); -#endif - dtls_security_params_free_other(peer); - dtls_debug_dump("cleartext", *cleartext, clen); - } - } - return clen; -} - -static int -dtls_send_hello_request(dtls_context_t *ctx, dtls_peer_t *peer) -{ - return dtls_send_handshake_msg_hash(ctx, peer, &peer->session, - DTLS_HT_HELLO_REQUEST, - NULL, 0, 0); -} - -int -dtls_renegotiate(dtls_context_t *ctx, const session_t *dst) -{ - dtls_peer_t *peer = NULL; - int err; - - peer = dtls_get_peer(ctx, dst); - - if (!peer) { - return -1; - } - if (peer->state != DTLS_STATE_CONNECTED) - return -1; - - peer->handshake_params = dtls_handshake_new(); - if (!peer->handshake_params) - return -1; - - peer->handshake_params->hs_state.mseq_r = 0; - peer->handshake_params->hs_state.mseq_s = 0; - - if (peer->role == DTLS_CLIENT) { - /* send ClientHello with empty Cookie */ - err = dtls_send_client_hello(ctx, peer, NULL, 0); - if (err < 0) - dtls_warn("cannot send ClientHello\n"); - else - peer->state = DTLS_STATE_CLIENTHELLO; - return err; - } else if (peer->role == DTLS_SERVER) { - return dtls_send_hello_request(ctx, peer); - } - - return -1; -} - -static int -handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session, - const dtls_peer_type role, const dtls_state_t state, - uint8 *data, size_t data_length) { - - int err = 0; - - /* This will clear the retransmission buffer if we get an expected - * handshake message. We have to make sure that no handshake message - * should get expected when we still should retransmit something, when - * we do everything accordingly to the DTLS 1.2 standard this should - * not be a problem. */ - if (peer) { - dtls_stop_retransmission(ctx, peer); - } - - /* The following switch construct handles the given message with - * respect to the current internal state for this peer. In case of - * error, it is left with return 0. */ - - dtls_debug("handle handshake packet of type: %s (%i)\n", - dtls_handshake_type_to_name(data[0]), data[0]); - switch (data[0]) { - - /************************************************************************ - * Client states - ************************************************************************/ - case DTLS_HT_HELLO_VERIFY_REQUEST: - - if (state != DTLS_STATE_CLIENTHELLO) { - return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); - } - - err = check_server_hello_verify_request(ctx, peer, data, data_length); - if (err < 0) { - dtls_warn("error in check_server_hello_verify_request err: %i\n", err); - return err; - } - - break; - case DTLS_HT_SERVER_HELLO: - - if (state != DTLS_STATE_CLIENTHELLO) { - return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); - } - - err = check_server_hello(ctx, peer, data, data_length); - if (err < 0) { - dtls_warn("error in check_server_hello err: %i\n", err); - return err; - } - if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher)) - peer->state = DTLS_STATE_WAIT_SERVERCERTIFICATE; - else - peer->state = DTLS_STATE_WAIT_SERVERHELLODONE; - /* update_hs_hash(peer, data, data_length); */ - - break; - -#ifdef DTLS_ECC - case DTLS_HT_CERTIFICATE: - - if ((role == DTLS_CLIENT && state != DTLS_STATE_WAIT_SERVERCERTIFICATE) || - (role == DTLS_SERVER && state != DTLS_STATE_WAIT_CLIENTCERTIFICATE)) { - return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); - } - err = check_server_certificate(ctx, peer, data, data_length); - if (err < 0) { - dtls_warn("error in check_server_certificate err: %i\n", err); - return err; - } - if (role == DTLS_CLIENT) { - peer->state = DTLS_STATE_WAIT_SERVERKEYEXCHANGE; - } else if (role == DTLS_SERVER){ - peer->state = DTLS_STATE_WAIT_CLIENTKEYEXCHANGE; - } - /* update_hs_hash(peer, data, data_length); */ - - break; -#endif /* DTLS_ECC */ - - case DTLS_HT_SERVER_KEY_EXCHANGE: - -#ifdef DTLS_ECC - if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher)) { - if (state != DTLS_STATE_WAIT_SERVERKEYEXCHANGE) { - return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); - } - err = check_server_key_exchange_ecdsa(ctx, peer, data, data_length); - } -#endif /* DTLS_ECC */ -#ifdef DTLS_PSK - if (is_tls_psk_with_aes_128_ccm_8(peer->handshake_params->cipher)) { - if (state != DTLS_STATE_WAIT_SERVERHELLODONE) { - return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); - } - err = check_server_key_exchange_psk(ctx, peer, data, data_length); - } -#endif /* DTLS_PSK */ - - if (err < 0) { - dtls_warn("error in check_server_key_exchange err: %i\n", err); - return err; - } - peer->state = DTLS_STATE_WAIT_SERVERHELLODONE; - /* update_hs_hash(peer, data, data_length); */ - - break; - - case DTLS_HT_SERVER_HELLO_DONE: - - if (state != DTLS_STATE_WAIT_SERVERHELLODONE) { - return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); - } - - err = check_server_hellodone(ctx, peer, data, data_length); - if (err < 0) { - dtls_warn("error in check_server_hellodone err: %i\n", err); - return err; - } - peer->state = DTLS_STATE_WAIT_CHANGECIPHERSPEC; - /* update_hs_hash(peer, data, data_length); */ - - break; - - case DTLS_HT_CERTIFICATE_REQUEST: - - if (state != DTLS_STATE_WAIT_SERVERHELLODONE) { - return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); - } - - err = check_certificate_request(ctx, peer, data, data_length); - if (err < 0) { - dtls_warn("error in check_certificate_request err: %i\n", err); - return err; - } - - break; - - case DTLS_HT_FINISHED: - /* expect a Finished message from server */ - - if (state != DTLS_STATE_WAIT_FINISHED) { - return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); - } - - err = check_finished(ctx, peer, data, data_length); - if (err < 0) { - dtls_warn("error in check_finished err: %i\n", err); - return err; - } - if (role == DTLS_SERVER) { - /* send ServerFinished */ - update_hs_hash(peer, data, data_length); - - /* send change cipher spec message and switch to new configuration */ - err = dtls_send_ccs(ctx, peer); - if (err < 0) { - dtls_warn("cannot send CCS message\n"); - return err; - } - - dtls_security_params_switch(peer); - - err = dtls_send_finished(ctx, peer, PRF_LABEL(server), PRF_LABEL_SIZE(server)); - if (err < 0) { - dtls_warn("sending server Finished failed\n"); - return err; - } - } - dtls_handshake_free(peer->handshake_params); - peer->handshake_params = NULL; - dtls_debug("Handshake complete\n"); - check_stack(); - peer->state = DTLS_STATE_CONNECTED; - - /* return here to not increase the message receive counter */ - return err; - - /************************************************************************ - * Server states - ************************************************************************/ - - case DTLS_HT_CLIENT_KEY_EXCHANGE: - /* handle ClientHello, update msg and msglen and goto next if not finished */ - - if (state != DTLS_STATE_WAIT_CLIENTKEYEXCHANGE) { - return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); - } - - err = check_client_keyexchange(ctx, peer->handshake_params, data, data_length); - if (err < 0) { - dtls_warn("error in check_client_keyexchange err: %i\n", err); - return err; - } - update_hs_hash(peer, data, data_length); - - if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher) && - is_ecdsa_client_auth_supported(ctx)) - peer->state = DTLS_STATE_WAIT_CERTIFICATEVERIFY; - else - peer->state = DTLS_STATE_WAIT_CHANGECIPHERSPEC; - break; - -#ifdef DTLS_ECC - case DTLS_HT_CERTIFICATE_VERIFY: - - if (state != DTLS_STATE_WAIT_CERTIFICATEVERIFY) { - return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); - } - - err = check_client_certificate_verify(ctx, peer, data, data_length); - if (err < 0) { - dtls_warn("error in check_client_certificate_verify err: %i\n", err); - return err; - } - - update_hs_hash(peer, data, data_length); - peer->state = DTLS_STATE_WAIT_CHANGECIPHERSPEC; - break; -#endif /* DTLS_ECC */ - - case DTLS_HT_CLIENT_HELLO: - - if ((peer && state != DTLS_STATE_CONNECTED) || - (!peer && state != DTLS_STATE_WAIT_CLIENTHELLO)) { - return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); - } - - /* When no DTLS state exists for this peer, we only allow a - Client Hello message with - - a) a valid cookie, or - b) no cookie. - - Anything else will be rejected. Fragementation is not allowed - here as it would require peer state as well. - */ - err = dtls_verify_peer(ctx, peer, session, data, data_length); - if (err < 0) { - dtls_warn("error in dtls_verify_peer err: %i\n", err); - return err; - } - - if (err > 0) { - dtls_debug("server hello verify was sent\n"); - break; - } - - /* At this point, we have a good relationship with this peer. This - * state is left for re-negotiation of key material. */ - if (!peer) { - dtls_security_parameters_t *security; - - /* msg contains a Client Hello with a valid cookie, so we can - * safely create the server state machine and continue with - * the handshake. */ - peer = dtls_new_peer(session); - if (!peer) { - dtls_alert("cannot create peer\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - peer->role = DTLS_SERVER; - - /* Initialize record sequence number to 1 for new peers. The first - * record with sequence number 0 is a stateless Hello Verify Request. - */ - security = dtls_security_params(peer); - security->rseq = 1; - dtls_add_peer(ctx, peer); - } - if (peer && !peer->handshake_params) { - dtls_handshake_header_t *hs_header = DTLS_HANDSHAKE_HEADER(data); - - peer->handshake_params = dtls_handshake_new(); - if (!peer->handshake_params) - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - - LIST_STRUCT_INIT(peer->handshake_params, reorder_queue); - peer->handshake_params->hs_state.mseq_r = dtls_uint16_to_int(hs_header->message_seq); - peer->handshake_params->hs_state.mseq_s = 1; - } - - clear_hs_hash(peer); - - /* First negotiation step: check for PSK - * - * Note that we already have checked that msg is a Handshake - * message containing a ClientHello. dtls_get_cipher() therefore - * does not check again. - */ - err = dtls_update_parameters(ctx, peer, data, data_length); - if (err < 0) { - dtls_warn("error updating security parameters\n"); - return err; - } - - /* update finish MAC */ - update_hs_hash(peer, data, data_length); - - err = dtls_send_server_hello_msgs(ctx, peer); - if (err < 0) { - return err; - } - if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher) && - is_ecdsa_client_auth_supported(ctx)) - peer->state = DTLS_STATE_WAIT_CLIENTCERTIFICATE; - else - peer->state = DTLS_STATE_WAIT_CLIENTKEYEXCHANGE; - - /* after sending the ServerHelloDone, we expect the - * ClientKeyExchange (possibly containing the PSK id), - * followed by a ChangeCipherSpec and an encrypted Finished. - */ - - break; - - case DTLS_HT_HELLO_REQUEST: - - if (state != DTLS_STATE_CONNECTED) { - /* we should just ignore such packets when in handshake */ - return 0; - } - - if (peer && !peer->handshake_params) { - peer->handshake_params = dtls_handshake_new(); - if (!peer->handshake_params) - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - - LIST_STRUCT_INIT(peer->handshake_params, reorder_queue); - peer->handshake_params->hs_state.mseq_r = 0; - peer->handshake_params->hs_state.mseq_s = 0; - } - - /* send ClientHello with empty Cookie */ - err = dtls_send_client_hello(ctx, peer, NULL, 0); - if (err < 0) { - dtls_warn("cannot send ClientHello\n"); - return err; - } - peer->state = DTLS_STATE_CLIENTHELLO; - break; - - default: - dtls_crit("unhandled message %d\n", data[0]); - return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); - } - - if (peer && peer->handshake_params && err >= 0) { - peer->handshake_params->hs_state.mseq_r++; - } - - return err; -} - -static int -handle_handshake(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session, - const dtls_peer_type role, const dtls_state_t state, - uint8 *data, size_t data_length) -{ - dtls_handshake_header_t *hs_header; - int res; - - if (data_length < DTLS_HS_LENGTH) { - dtls_warn("handshake message too short\n"); - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - } - hs_header = DTLS_HANDSHAKE_HEADER(data); - - dtls_debug("received handshake packet of type: %s (%i)\n", - dtls_handshake_type_to_name(hs_header->msg_type), hs_header->msg_type); - - if (!peer || !peer->handshake_params) { - /* This is the initial ClientHello */ - if (hs_header->msg_type != DTLS_HT_CLIENT_HELLO && !peer) { - dtls_warn("If there is no peer only ClientHello is allowed\n"); - return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); - } - - /* This is a ClientHello or Hello Request send when doing TLS renegotiation */ - if (hs_header->msg_type == DTLS_HT_CLIENT_HELLO || - hs_header->msg_type == DTLS_HT_HELLO_REQUEST) { - return handle_handshake_msg(ctx, peer, session, role, state, data, - data_length); - } else { - dtls_warn("ignore unexpected handshake message\n"); - return 0; - } - } - - if (dtls_uint16_to_int(hs_header->message_seq) < peer->handshake_params->hs_state.mseq_r) { - dtls_warn("The message sequence number is too small, expected %i, got: %i\n", - peer->handshake_params->hs_state.mseq_r, dtls_uint16_to_int(hs_header->message_seq)); - return 0; - } else if (dtls_uint16_to_int(hs_header->message_seq) > peer->handshake_params->hs_state.mseq_r) { - /* A packet in between is missing, buffer this packet. */ - netq_t *n; - - /* TODO: only add packet that are not too new. */ - if (data_length > DTLS_MAX_BUF) { - dtls_warn("the packet is too big to buffer for reoder\n"); - return 0; - } - - netq_t *node = netq_head(peer->handshake_params->reorder_queue); - while (node) { - dtls_handshake_header_t *node_header = DTLS_HANDSHAKE_HEADER(node->data); - if (dtls_uint16_to_int(node_header->message_seq) == dtls_uint16_to_int(hs_header->message_seq)) { - dtls_warn("a packet with this sequence number is already stored\n"); - return 0; - } - node = netq_next(node); - } - - n = netq_node_new(data_length); - if (!n) { - dtls_warn("no space in reoder buffer\n"); - return 0; - } - - n->peer = peer; - n->length = data_length; - memcpy(n->data, data, data_length); - - if (!netq_insert_node(peer->handshake_params->reorder_queue, n)) { - dtls_warn("cannot add packet to reoder buffer\n"); - netq_node_free(n); - } - dtls_info("Added packet for reordering\n"); - return 0; - } else if (dtls_uint16_to_int(hs_header->message_seq) == peer->handshake_params->hs_state.mseq_r) { - /* Found the expected packet, use this and all the buffered packet */ - int next = 1; - - res = handle_handshake_msg(ctx, peer, session, role, state, data, data_length); - if (res < 0) - return res; - - /* We do not know in which order the packet are in the list just search the list for every packet. */ - while (next && peer->handshake_params) { - next = 0; - netq_t *node = netq_head(peer->handshake_params->reorder_queue); - while (node) { - dtls_handshake_header_t *node_header = DTLS_HANDSHAKE_HEADER(node->data); - - if (dtls_uint16_to_int(node_header->message_seq) == peer->handshake_params->hs_state.mseq_r) { - netq_remove(peer->handshake_params->reorder_queue, node); - next = 1; - res = handle_handshake_msg(ctx, peer, session, role, peer->state, node->data, node->length); - if (res < 0) { - return res; - } - - break; - } else { - node = netq_next(node); - } - } - } - return res; - } - assert(0); - return 0; -} - -static int -handle_ccs(dtls_context_t *ctx, dtls_peer_t *peer, - uint8 *record_header, uint8 *data, size_t data_length) -{ - int err; - dtls_handshake_parameters_t *handshake = peer->handshake_params; - - /* A CCS message is handled after a KeyExchange message was - * received from the client. When security parameters have been - * updated successfully and a ChangeCipherSpec message was sent - * by ourself, the security context is switched and the record - * sequence number is reset. */ - - if (!peer || peer->state != DTLS_STATE_WAIT_CHANGECIPHERSPEC) { - dtls_warn("expected ChangeCipherSpec during handshake\n"); - return 0; - } - - if (data_length < 1 || data[0] != 1) - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - - /* Just change the cipher when we are on the same epoch */ - if (peer->role == DTLS_SERVER) { - err = calculate_key_block(ctx, handshake, peer, - &peer->session, peer->role); - if (err < 0) { - return err; - } - } - - peer->state = DTLS_STATE_WAIT_FINISHED; - - return 0; -} - -/** - * Handles incoming Alert messages. This function returns \c 1 if the - * connection should be closed and the peer is to be invalidated. - */ -static int -handle_alert(dtls_context_t *ctx, dtls_peer_t *peer, - uint8 *record_header, uint8 *data, size_t data_length) { - int free_peer = 0; /* indicates whether to free peer */ - - if (data_length < 2) - return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); - - dtls_info("** Alert: level %d, description %d\n", data[0], data[1]); - - if (!peer) { - dtls_warn("got an alert for an unknown peer, we probably already removed it, ignore it\n"); - return 0; - } - - /* The peer object is invalidated for FATAL alerts and close - * notifies. This is done in two steps.: First, remove the object - * from our list of peers. After that, the event handler callback is - * invoked with the still existing peer object. Finally, the storage - * used by peer is released. - */ - if (data[0] == DTLS_ALERT_LEVEL_FATAL || data[1] == DTLS_ALERT_CLOSE_NOTIFY) { - dtls_alert("%d invalidate peer\n", data[1]); - - list_remove(ctx->peers, peer); - -#ifdef WITH_CONTIKI -#ifndef NDEBUG - PRINTF("removed peer ["); - PRINT6ADDR(&peer->session.addr.ipaddr); - PRINTF("]:%d\n", uip_ntohs(peer->session.addr.port)); -#endif -#endif /* WITH_CONTIKI */ - - free_peer = 1; - - } - - (void)CALL(ctx, event, &peer->session, - (dtls_alert_level_t)data[0], (unsigned short)data[1]); - switch (data[1]) { - case DTLS_ALERT_CLOSE_NOTIFY: - /* If state is DTLS_STATE_CLOSING, we have already sent a - * close_notify so, do not send that again. */ - if (peer->state != DTLS_STATE_CLOSING) { - peer->state = DTLS_STATE_CLOSING; - dtls_send_alert(ctx, peer, DTLS_ALERT_LEVEL_FATAL, DTLS_ALERT_CLOSE_NOTIFY); - } else - peer->state = DTLS_STATE_CLOSED; - break; - default: - ; - } - - if (free_peer) { - dtls_stop_retransmission(ctx, peer); - dtls_destroy_peer(ctx, peer, 0); - } - - return free_peer; -} - -static int dtls_alert_send_from_err(dtls_context_t *ctx, dtls_peer_t *peer, - session_t *session, int err) -{ - int level; - int desc; - - if (err < -(1 << 8) && err > -(3 << 8)) { - level = ((-err) & 0xff00) >> 8; - desc = (-err) & 0xff; - if (!peer) { - peer = dtls_get_peer(ctx, session); - } - if (peer) { - peer->state = DTLS_STATE_CLOSING; - return dtls_send_alert(ctx, peer, level, desc); - } - } else if (err == -1) { - if (!peer) { - peer = dtls_get_peer(ctx, session); - } - if (peer) { - peer->state = DTLS_STATE_CLOSING; - return dtls_send_alert(ctx, peer, DTLS_ALERT_LEVEL_FATAL, DTLS_ALERT_INTERNAL_ERROR); - } - } - return -1; -} - -/** - * Handles incoming data as DTLS message from given peer. - */ -int -dtls_handle_message(dtls_context_t *ctx, - session_t *session, - uint8 *msg, int msglen) { - dtls_peer_t *peer = NULL; - unsigned int rlen; /* record length */ - uint8 *data; /* (decrypted) payload */ - int data_length; /* length of decrypted payload - (without MAC and padding) */ - int err; - - /* check if we have DTLS state for addr/port/ifindex */ - peer = dtls_get_peer(ctx, session); - - if (!peer) { - dtls_debug("dtls_handle_message: PEER NOT FOUND\n"); - dtls_dsrv_log_addr(DTLS_LOG_DEBUG, "peer addr", session); - } else { - dtls_debug("dtls_handle_message: FOUND PEER\n"); - } - - while ((rlen = is_record(msg,msglen))) { - dtls_peer_type role; - dtls_state_t state; - - dtls_debug("got packet %d (%d bytes)\n", msg[0], rlen); - if (peer) { - data_length = decrypt_verify(peer, msg, rlen, &data); - if (data_length < 0) { - int err = dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR); - dtls_info("decrypt_verify() failed\n"); - if (peer->state < DTLS_STATE_CONNECTED) { - dtls_alert_send_from_err(ctx, peer, &peer->session, err); - peer->state = DTLS_STATE_CLOSED; - /* dtls_stop_retransmission(ctx, peer); */ - dtls_destroy_peer(ctx, peer, 1); - } - return err; - } - role = peer->role; - state = peer->state; - } else { - /* is_record() ensures that msg contains at least a record header */ - data = msg + DTLS_RH_LENGTH; - data_length = rlen - DTLS_RH_LENGTH; - state = DTLS_STATE_WAIT_CLIENTHELLO; - role = DTLS_SERVER; - } - - dtls_debug_hexdump("receive header", msg, sizeof(dtls_record_header_t)); - dtls_debug_hexdump("receive unencrypted", data, data_length); - - /* Handle received record according to the first byte of the - * message, i.e. the subprotocol. We currently do not support - * combining multiple fragments of one type into a single - * record. */ - - switch (msg[0]) { - - case DTLS_CT_CHANGE_CIPHER_SPEC: - if (peer) { - dtls_stop_retransmission(ctx, peer); - } - err = handle_ccs(ctx, peer, msg, data, data_length); - if (err < 0) { - dtls_warn("error while handling ChangeCipherSpec message\n"); - dtls_alert_send_from_err(ctx, peer, session, err); - - /* invalidate peer */ - dtls_destroy_peer(ctx, peer, 1); - peer = NULL; - - return err; - } - break; - - case DTLS_CT_ALERT: - if (peer) { - dtls_stop_retransmission(ctx, peer); - } - err = handle_alert(ctx, peer, msg, data, data_length); - if (err < 0 || err == 1) { - dtls_warn("received alert, peer has been invalidated\n"); - /* handle alert has invalidated peer */ - peer = NULL; - return err < 0 ?err:-1; - } - break; - - case DTLS_CT_HANDSHAKE: - /* Handshake messages other than Finish must use the current - * epoch, Finish has epoch + 1. */ - - if (peer) { - uint16_t expected_epoch = dtls_security_params(peer)->epoch; - uint16_t msg_epoch = - dtls_uint16_to_int(DTLS_RECORD_HEADER(msg)->epoch); - - /* The new security parameters must be used for all messages - * that are sent after the ChangeCipherSpec message. This - * means that the client's Finished message uses epoch + 1 - * while the server is still in the old epoch. - */ - if (role == DTLS_SERVER && state == DTLS_STATE_WAIT_FINISHED) { - expected_epoch++; - } - - if (expected_epoch != msg_epoch) { - dtls_warn("Wrong epoch, expected %i, got: %i\n", - expected_epoch, msg_epoch); - break; - } - } - - err = handle_handshake(ctx, peer, session, role, state, data, data_length); - if (err < 0) { - dtls_warn("error while handling handshake packet\n"); - dtls_alert_send_from_err(ctx, peer, session, err); - return err; - } - if (peer && peer->state == DTLS_STATE_CONNECTED) { - /* stop retransmissions */ - dtls_stop_retransmission(ctx, peer); - CALL(ctx, event, &peer->session, 0, DTLS_EVENT_CONNECTED); - } - break; - - case DTLS_CT_APPLICATION_DATA: - dtls_info("** application data:\n"); - if (!peer) { - dtls_warn("no peer available, send an alert\n"); - // TODO: should we send a alert here? - return -1; - } - dtls_stop_retransmission(ctx, peer); - CALL(ctx, read, &peer->session, data, data_length); - break; - default: - dtls_info("dropped unknown message of type %d\n",msg[0]); - } - - /* advance msg by length of ciphertext */ - msg += rlen; - msglen -= rlen; - } - - return 0; -} - -dtls_context_t * -dtls_new_context(void *app_data) { - dtls_context_t *c; - dtls_tick_t now; -#ifndef WITH_CONTIKI - FILE *urandom = fopen("/dev/urandom", "r"); - unsigned char buf[sizeof(unsigned long)]; -#endif /* WITH_CONTIKI */ - - dtls_ticks(&now); -#ifdef WITH_CONTIKI - /* FIXME: need something better to init PRNG here */ - dtls_prng_init(now); -#else /* WITH_CONTIKI */ - if (!urandom) { - dtls_emerg("cannot initialize PRNG\n"); - return NULL; - } - - if (fread(buf, 1, sizeof(buf), urandom) != sizeof(buf)) { - dtls_emerg("cannot initialize PRNG\n"); - return NULL; - } - - fclose(urandom); - dtls_prng_init((unsigned long)*buf); -#endif /* WITH_CONTIKI */ - - c = malloc_context(); - if (!c) - goto error; - - memset(c, 0, sizeof(dtls_context_t)); - c->app = app_data; - - LIST_STRUCT_INIT(c, sendqueue); - -#ifdef WITH_CONTIKI - LIST_STRUCT_INIT(c, peers); - /* LIST_STRUCT_INIT(c, key_store); */ - - process_start(&dtls_retransmit_process, (char *)c, NULL); - PROCESS_CONTEXT_BEGIN(&dtls_retransmit_process); - /* the retransmit timer must be initialized to some large value */ - etimer_set(&c->retransmit_timer, 0xFFFF, &dtls_retransmit_process); - PROCESS_CONTEXT_END(&dtls_retransmit_process); -#endif /* WITH_CONTIKI */ - - if (dtls_prng(c->cookie_secret, DTLS_COOKIE_SECRET_LENGTH)) - c->cookie_secret_age = now; - else - goto error; - - return c; - - error: - dtls_alert("cannot create DTLS context\n"); - if (c) - dtls_free_context(c); - return NULL; -} - -void -dtls_free_context(dtls_context_t *ctx) { - dtls_peer_t *p; - - if (!ctx) { - return; - } - - for (p = list_head(ctx->peers); p; p = list_item_next(p)) - dtls_destroy_peer(ctx, p, 1); - - free_context(ctx); -} - -int -dtls_connect_peer(dtls_context_t *ctx, dtls_peer_t *peer) { - int res; - - assert(peer); - if (!peer) - return -1; - - /* check if the same peer is already in our list */ - if (peer == dtls_get_peer(ctx, &peer->session)) { - dtls_debug("found peer, try to re-connect\n"); - return dtls_renegotiate(ctx, &peer->session); - } - - /* set local peer role to client, remote is server */ - peer->role = DTLS_CLIENT; - - dtls_add_peer(ctx, peer); - - /* send ClientHello with empty Cookie */ - peer->handshake_params = dtls_handshake_new(); - if (!peer->handshake_params) - return -1; - - peer->handshake_params->hs_state.mseq_r = 0; - peer->handshake_params->hs_state.mseq_s = 0; - LIST_STRUCT_INIT(peer->handshake_params, reorder_queue); - res = dtls_send_client_hello(ctx, peer, NULL, 0); - if (res < 0) - dtls_warn("cannot send ClientHello\n"); - else - peer->state = DTLS_STATE_CLIENTHELLO; - - return res; -} - -int -dtls_connect(dtls_context_t *ctx, const session_t *dst) { - dtls_peer_t *peer; - int res; - - peer = dtls_get_peer(ctx, dst); - - if (!peer) - peer = dtls_new_peer(dst); - - if (!peer) { - dtls_crit("cannot create new peer\n"); - return -1; - } - - res = dtls_connect_peer(ctx, peer); - - /* Invoke event callback to indicate connection attempt or - * re-negotiation. */ - if (res > 0) { - CALL(ctx, event, &peer->session, 0, DTLS_EVENT_CONNECT); - } else if (res == 0) { - CALL(ctx, event, &peer->session, 0, DTLS_EVENT_RENEGOTIATE); - } - - return res; -} - -static void -dtls_retransmit(dtls_context_t *context, netq_t *node) { - if (!context || !node) - return; - - /* re-initialize timeout when maximum number of retransmissions are not reached yet */ - if (node->retransmit_cnt < DTLS_DEFAULT_MAX_RETRANSMIT) { -#ifdef WITH_CONTIKI - /* Prepare to receive max. IPv6 frame size packets. */ - struct net_buf *buf = net_buf_get(&free_tx_bufs, 0); - unsigned char *sendbuf = buf->data; - size_t len = net_buf_tailroom(buf); /* max application data len */ -#else - unsigned char sendbuf[DTLS_MAX_BUF]; - size_t len = sizeof(sendbuf); -#endif - int err; - unsigned char *data = node->data; - size_t length = node->length; - dtls_tick_t now; - dtls_security_parameters_t *security = dtls_security_params_epoch(node->peer, node->epoch); - - dtls_ticks(&now); - node->retransmit_cnt++; - node->t = now + (node->timeout << node->retransmit_cnt); - netq_insert_node(context->sendqueue, node); - - if (node->type == DTLS_CT_HANDSHAKE) { - dtls_handshake_header_t *hs_header = DTLS_HANDSHAKE_HEADER(data); - - dtls_debug("** retransmit handshake packet of type: %s (%i)\n", - dtls_handshake_type_to_name(hs_header->msg_type), hs_header->msg_type); - } else { - dtls_debug("** retransmit packet\n"); - } - - err = dtls_prepare_record(node->peer, security, node->type, &data, &length, - 1, sendbuf, &len); - if (err < 0) { - dtls_warn("can not retransmit packet, err: %i\n", err); -#ifdef WITH_CONTIKI - net_buf_unref(buf); -#endif - return; - } - dtls_debug_hexdump("retransmit header", sendbuf, - sizeof(dtls_record_header_t)); - dtls_debug_hexdump("retransmit unencrypted", node->data, node->length); - - (void)CALL(context, write, &node->peer->session, sendbuf, len); - -#ifdef WITH_CONTIKI - net_buf_unref(buf); -#endif - - return; - } - - /* no more retransmissions, remove node from system */ - - dtls_debug("** removed transaction\n"); - - /* And finally delete the node */ - netq_node_free(node); -} - -static void -dtls_stop_retransmission(dtls_context_t *context, dtls_peer_t *peer) { - netq_t *node; - node = list_head(context->sendqueue); - - while (node) { - if (dtls_session_equals(&node->peer->session, &peer->session)) { - netq_t *tmp = node; - node = list_item_next(node); - list_remove(context->sendqueue, tmp); - netq_node_free(tmp); - } else - node = list_item_next(node); - } -} - -void -dtls_check_retransmit(dtls_context_t *context, clock_time_t *next) { - dtls_tick_t now; - netq_t *node = netq_head(context->sendqueue); - - dtls_ticks(&now); - while (node && node->t <= now) { - netq_pop_first(context->sendqueue); - dtls_retransmit(context, node); - node = netq_head(context->sendqueue); - } - - if (next && node) - *next = node->t; -} - -#ifdef WITH_CONTIKI -/*---------------------------------------------------------------------------*/ -/* message retransmission */ -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(dtls_retransmit_process, ev, data, buf, user_data) -{ - clock_time_t now; - netq_t *node; - - PROCESS_BEGIN(); - - dtls_debug("Started DTLS retransmit process\r\n"); - - while(1) { - PROCESS_YIELD(); - if (ev == PROCESS_EVENT_TIMER) { - if (etimer_expired(&the_dtls_context.retransmit_timer)) { - - node = list_head(the_dtls_context.sendqueue); - - now = clock_time(); - if (node && node->t <= now) { - dtls_retransmit(&the_dtls_context, list_pop(the_dtls_context.sendqueue)); - node = list_head(the_dtls_context.sendqueue); - } - - /* need to set timer to some value even if no nextpdu is available */ - if (node) { - etimer_set(&the_dtls_context.retransmit_timer, - node->t <= now ? 1 : node->t - now, - &dtls_retransmit_process); - } else { - etimer_set(&the_dtls_context.retransmit_timer, 0xFFFF, - &dtls_retransmit_process); - } - } - } - } - - PROCESS_END(); -} -#endif /* WITH_CONTIKI */ diff --git a/net/ip/tinydtls/dtls.h b/net/ip/tinydtls/dtls.h deleted file mode 100644 index 0b6d38ce4dc7cf58cbbde05d1970aadf8a14eba4..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/dtls.h +++ /dev/null @@ -1,733 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2013 Olaf Bergmann - * Copyright (C) 2013 Hauke Mehrtens - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * @file dtls.h - * @brief High level DTLS API and visible structures. - */ - -#ifndef _DTLS_DTLS_H_ -#define _DTLS_DTLS_H_ - -#include - -#include "t_list.h" -#include "state.h" -#include "peer.h" - -#include "alert.h" -#include "crypto.h" -#include "hmac.h" - -#include "global.h" -#include "dtls_time.h" - -#ifndef DTLSv12 -#define DTLS_VERSION 0xfeff /* DTLS v1.1 */ -#else -#define DTLS_VERSION 0xfefd /* DTLS v1.2 */ -#endif - -typedef enum dtls_credentials_type_t { - DTLS_PSK_HINT, DTLS_PSK_IDENTITY, DTLS_PSK_KEY -} dtls_credentials_type_t; - -typedef struct dtls_ecdsa_key_t { - dtls_ecdh_curve curve; - const unsigned char *priv_key; /** < private key as bytes > */ - const unsigned char *pub_key_x; /** < x part of the public key for the given private key > */ - const unsigned char *pub_key_y; /** < y part of the public key for the given private key > */ -} dtls_ecdsa_key_t; - -/** Length of the secret that is used for generating Hello Verify cookies. */ -#define DTLS_COOKIE_SECRET_LENGTH 12 - -struct dtls_context_t; - -/** - * This structure contains callback functions used by tinydtls to - * communicate with the application. At least the write function must - * be provided. It is called by the DTLS state machine to send packets - * over the network. The read function is invoked to deliver decrypted - * and verfified application data. The third callback is an event - * handler function that is called when alert messages are encountered - * or events generated by the library have occured. - */ -typedef struct { - /** - * Called from dtls_handle_message() to send DTLS packets over the - * network. The callback function must use the network interface - * denoted by session->ifindex to send the data. - * - * @param ctx The current DTLS context. - * @param session The session object, including the address of the - * remote peer where the data shall be sent. - * @param buf The data to send. - * @param len The actual length of @p buf. - * @return The callback function must return the number of bytes - * that were sent, or a value less than zero to indicate an - * error. - */ - int (*write)(struct dtls_context_t *ctx, - session_t *session, uint8 *buf, size_t len); - - /** - * Called from dtls_handle_message() deliver application data that was - * received on the given session. The data is delivered only after - * decryption and verification have succeeded. - * - * @param ctx The current DTLS context. - * @param session The session object, including the address of the - * data's origin. - * @param buf The received data packet. - * @param len The actual length of @p buf. - * @return ignored - */ - int (*read)(struct dtls_context_t *ctx, - session_t *session, uint8 *buf, size_t len); - - /** - * The event handler is called when a message from the alert - * protocol is received or the state of the DTLS session changes. - * - * @param ctx The current dtls context. - * @param session The session object that was affected. - * @param level The alert level or @c 0 when an event ocurred that - * is not an alert. - * @param code Values less than @c 256 indicate alerts, while - * @c 256 or greater indicate internal DTLS session changes. - * @return ignored - */ - int (*event)(struct dtls_context_t *ctx, session_t *session, - dtls_alert_level_t level, unsigned short code); - -#ifdef DTLS_PSK - /** - * Called during handshake to get information related to the - * psk key exchange. The type of information requested is - * indicated by @p type which will be one of DTLS_PSK_HINT, - * DTLS_PSK_IDENTITY, or DTLS_PSK_KEY. The called function - * must store the requested item in the buffer @p result of - * size @p result_length. On success, the function must return - * the actual number of bytes written to @p result, of a - * value less than zero on error. The parameter @p desc may - * contain additional request information (e.g. the psk_identity - * for which a key is requested when @p type == @c DTLS_PSK_KEY. - * - * @param ctx The current dtls context. - * @param session The session where the key will be used. - * @param type The type of the requested information. - * @param desc Additional request information - * @param desc_len The actual length of desc. - * @param result Must be filled with the requested information. - * @param result_length Maximum size of @p result. - * @return The number of bytes written to @p result or a value - * less than zero on error. - */ - int (*get_psk_info)(struct dtls_context_t *ctx, - const session_t *session, - dtls_credentials_type_t type, - const unsigned char *desc, size_t desc_len, - unsigned char *result, size_t result_length); - -#endif /* DTLS_PSK */ - -#ifdef DTLS_ECC - /** - * Called during handshake to get the server's or client's ecdsa - * key used to authenticate this server or client in this - * session. If found, the key must be stored in @p result and - * the return value must be @c 0. If not found, @p result is - * undefined and the return value must be less than zero. - * - * If ECDSA should not be supported, set this pointer to NULL. - * - * Implement this if you want to provide your own certificate to - * the other peer. This is mandatory for a server providing ECDSA - * support and optional for a client. A client doing DTLS client - * authentication has to implementing this callback. - * - * @param ctx The current dtls context. - * @param session The session where the key will be used. - * @param result Must be set to the key object to used for the given - * session. - * @return @c 0 if result is set, or less than zero on error. - */ - int (*get_ecdsa_key)(struct dtls_context_t *ctx, - const session_t *session, - const dtls_ecdsa_key_t **result); - - /** - * Called during handshake to check the peer's pubic key in this - * session. If the public key matches the session and should be - * considerated valid the return value must be @c 0. If not valid, - * the return value must be less than zero. - * - * If ECDSA should not be supported, set this pointer to NULL. - * - * Implement this if you want to verify the other peers public key. - * This is mandatory for a DTLS client doing based ECDSA - * authentication. A server implementing this will request the - * client to do DTLS client authentication. - * - * @param ctx The current dtls context. - * @param session The session where the key will be used. - * @param other_pub_x x component of the public key. - * @param other_pub_y y component of the public key. - * @return @c 0 if public key matches, or less than zero on error. - * error codes: - * return dtls_alert_fatal_create(DTLS_ALERT_BAD_CERTIFICATE); - * return dtls_alert_fatal_create(DTLS_ALERT_UNSUPPORTED_CERTIFICATE); - * return dtls_alert_fatal_create(DTLS_ALERT_CERTIFICATE_REVOKED); - * return dtls_alert_fatal_create(DTLS_ALERT_CERTIFICATE_EXPIRED); - * return dtls_alert_fatal_create(DTLS_ALERT_CERTIFICATE_UNKNOWN); - * return dtls_alert_fatal_create(DTLS_ALERT_UNKNOWN_CA); - */ - int (*verify_ecdsa_key)(struct dtls_context_t *ctx, - const session_t *session, - const unsigned char *other_pub_x, - const unsigned char *other_pub_y, - size_t key_size); -#endif /* DTLS_ECC */ -} dtls_handler_t; - -/** Holds global information of the DTLS engine. */ -typedef struct dtls_context_t { - unsigned char cookie_secret[DTLS_COOKIE_SECRET_LENGTH]; - clock_time_t cookie_secret_age; /**< the time the secret has been generated */ - - LIST_STRUCT(peers); - -#ifdef WITH_CONTIKI - struct etimer retransmit_timer; /**< fires when the next packet must be sent */ -#endif /* WITH_CONTIKI */ - - LIST_STRUCT(sendqueue); /**< the packets to send */ - - void *app; /**< application-specific data */ - - dtls_handler_t *h; /**< callback handlers */ - - unsigned char readbuf[DTLS_MAX_BUF]; -} dtls_context_t; - -/** - * This function initializes the tinyDTLS memory management and must - * be called first. - */ -void dtls_init(); - -/** - * Creates a new context object. The storage allocated for the new - * object must be released with dtls_free_context(). */ -dtls_context_t *dtls_new_context(void *app_data); - -/** Releases any storage that has been allocated for \p ctx. */ -void dtls_free_context(dtls_context_t *ctx); - -#define dtls_set_app_data(CTX,DATA) ((CTX)->app = (DATA)) -#define dtls_get_app_data(CTX) ((CTX)->app) - -/** Sets the callback handler object for @p ctx to @p h. */ -static inline void dtls_set_handler(dtls_context_t *ctx, dtls_handler_t *h) { - ctx->h = h; -} - -/** - * Establishes a DTLS channel with the specified remote peer @p dst. - * This function returns @c 0 if that channel already exists, a value - * greater than zero when a new ClientHello message was sent, and - * a value less than zero on error. - * - * @param ctx The DTLS context to use. - * @param dst The remote party to connect to. - * @return A value less than zero on error, greater or equal otherwise. - */ -int dtls_connect(dtls_context_t *ctx, const session_t *dst); - -/** - * Establishes a DTLS channel with the specified remote peer. - * This function returns @c 0 if that channel already exists, a value - * greater than zero when a new ClientHello message was sent, and - * a value less than zero on error. - * - * @param ctx The DTLS context to use. - * @param peer The peer object that describes the session. - * @return A value less than zero on error, greater or equal otherwise. - */ -int dtls_connect_peer(dtls_context_t *ctx, dtls_peer_t *peer); - -/** - * Closes the DTLS connection associated with @p remote. This function - * returns zero on success, and a value less than zero on error. - */ -int dtls_close(dtls_context_t *ctx, const session_t *remote); - -int dtls_renegotiate(dtls_context_t *ctx, const session_t *dst); - -/** - * Writes the application data given in @p buf to the peer specified - * by @p session. - * - * @param ctx The DTLS context to use. - * @param session The remote transport address and local interface. - * @param buf The data to write. - * @param len The actual length of @p data. - * - * @return The number of bytes written or @c -1 on error. - */ -int dtls_write(struct dtls_context_t *ctx, session_t *session, - uint8 *buf, size_t len); - -/** - * Checks sendqueue of given DTLS context object for any outstanding - * packets to be transmitted. - * - * @param context The DTLS context object to use. - * @param next If not NULL, @p next is filled with the timestamp - * of the next scheduled retransmission, or @c 0 when no packets are - * waiting. - */ -void dtls_check_retransmit(dtls_context_t *context, clock_time_t *next); - -#define DTLS_COOKIE_LENGTH 16 - -#define DTLS_CT_CHANGE_CIPHER_SPEC 20 -#define DTLS_CT_ALERT 21 -#define DTLS_CT_HANDSHAKE 22 -#define DTLS_CT_APPLICATION_DATA 23 - -/** Generic header structure of the DTLS record layer. */ -typedef struct __attribute__((__packed__)) { - uint8 content_type; /**< content type of the included message */ - uint16 version; /**< Protocol version */ - uint16 epoch; /**< counter for cipher state changes */ - uint48 sequence_number; /**< sequence number */ - uint16 length; /**< length of the following fragment */ - /* fragment */ -} dtls_record_header_t; - -/* Handshake types */ - -#define DTLS_HT_HELLO_REQUEST 0 -#define DTLS_HT_CLIENT_HELLO 1 -#define DTLS_HT_SERVER_HELLO 2 -#define DTLS_HT_HELLO_VERIFY_REQUEST 3 -#define DTLS_HT_CERTIFICATE 11 -#define DTLS_HT_SERVER_KEY_EXCHANGE 12 -#define DTLS_HT_CERTIFICATE_REQUEST 13 -#define DTLS_HT_SERVER_HELLO_DONE 14 -#define DTLS_HT_CERTIFICATE_VERIFY 15 -#define DTLS_HT_CLIENT_KEY_EXCHANGE 16 -#define DTLS_HT_FINISHED 20 - -/** Header structure for the DTLS handshake protocol. */ -typedef struct __attribute__((__packed__)) { - uint8 msg_type; /**< Type of handshake message (one of DTLS_HT_) */ - uint24 length; /**< length of this message */ - uint16 message_seq; /**< Message sequence number */ - uint24 fragment_offset; /**< Fragment offset. */ - uint24 fragment_length; /**< Fragment length. */ - /* body */ -} dtls_handshake_header_t; - -/** Structure of the Client Hello message. */ -typedef struct __attribute__((__packed__)) { - uint16 version; /**< Client version */ - uint32 gmt_random; /**< GMT time of the random byte creation */ - unsigned char random[28]; /**< Client random bytes */ - /* session id (up to 32 bytes) */ - /* cookie (up to 32 bytes) */ - /* cipher suite (2 to 2^16 -1 bytes) */ - /* compression method */ -} dtls_client_hello_t; - -/** Structure of the Hello Verify Request. */ -typedef struct __attribute__((__packed__)) { - uint16 version; /**< Server version */ - uint8 cookie_length; /**< Length of the included cookie */ - uint8 cookie[]; /**< up to 32 bytes making up the cookie */ -} dtls_hello_verify_t; - -#if 0 -/** - * Checks a received DTLS record for consistency and eventually decrypt, - * verify, decompress and reassemble the contained fragment for - * delivery to high-lever clients. - * - * \param state The DTLS record state for the current session. - * \param - */ -int dtls_record_read(dtls_state_t *state, uint8 *msg, int msglen); -#endif - -/** - * Handles incoming data as DTLS message from given peer. - * - * @param ctx The dtls context to use. - * @param session The current session - * @param msg The received data - * @param msglen The actual length of @p msg. - * @return A value less than zero on error, zero on success. - */ -int dtls_handle_message(dtls_context_t *ctx, session_t *session, - uint8 *msg, int msglen); - -/** - * Check if @p session is associated with a peer object in @p context. - * This function returns a pointer to the peer if found, NULL otherwise. - * - * @param context The DTLS context to search. - * @param session The remote address and local interface - * @return A pointer to the peer associated with @p session or NULL if - * none exists. - */ -dtls_peer_t *dtls_get_peer(const dtls_context_t *context, - const session_t *session); - - -#endif /* _DTLS_DTLS_H_ */ - -/** - * @mainpage - * - * @author Olaf Bergmann, TZI Uni Bremen - * - * This library provides a very simple datagram server with DTLS - * support. It is designed to support session multiplexing in - * single-threaded applications and thus targets specifically on - * embedded systems. - * - * @section license License - * - * This software is under the MIT License. - * - * @subsection sha256 Aaron D. Gifford's SHA256 Implementation - * - * tinyDTLS provides HMAC-SHA256 with BSD-licensed code from Aaron D. Gifford, - * see www.aarongifford.com. - * - * @subsection aes Rijndael Implementation From OpenBSD - * - * The AES implementation is taken from rijndael.{c,h} contained in the crypto - * sub-system of the OpenBSD operating system. It is copyright by Vincent Rijmen, * - * Antoon Bosselaers and Paulo Barreto. See rijndael.c - * for License info. - * - * @section download Getting the Files - * - * You can get the sources either from the downloads section or - * through git from the project develop page. - * - * @section config Configuration - * - * Use @c configure to set up everything for a successful build. For Contiki, use the - * option @c --with-contiki. - * - * @section build Building - * - * After configuration, just type - * @code -make - * @endcode - * optionally followed by - * @code -make install - * @endcode - * The Contiki version is integrated with the Contiki build system, hence you do not - * need to invoke @c make explicitely. Just add @c tinydtls to the variable @c APPS - * in your @c Makefile. - * - * @addtogroup dtls_usage DTLS Usage - * - * @section dtls_server_example DTLS Server Example - * - * This section shows how to use the DTLS library functions to setup a - * simple secure UDP echo server. The application is responsible for the - * entire network communication and thus will look like a usual UDP - * server with socket creation and binding and a typical select-loop as - * shown below. The minimum configuration required for DTLS is the - * creation of the dtls_context_t using dtls_new_context(), and a callback - * for sending data. Received packets are read by the application and - * passed to dtls_handle_message() as shown in @ref dtls_read_cb. - * For any useful communication to happen, read and write call backs - * and a key management function should be registered as well. - * - * @code - dtls_context_t *the_context = NULL; - int fd, result; - - static dtls_handler_t cb = { - .write = send_to_peer, - .read = read_from_peer, - .event = NULL, - .get_psk_key = get_psk_key - }; - - fd = socket(...); - if (fd < 0 || bind(fd, ...) < 0) - exit(-1); - - the_context = dtls_new_context(&fd); - dtls_set_handler(the_context, &cb); - - while (1) { - ...initialize fd_set rfds and timeout ... - result = select(fd+1, &rfds, NULL, 0, NULL); - - if (FD_ISSET(fd, &rfds)) - dtls_handle_read(the_context); - } - - dtls_free_context(the_context); - * @endcode - * - * @subsection dtls_read_cb The Read Callback - * - * The DTLS library expects received raw data to be passed to - * dtls_handle_message(). The application is responsible for - * filling a session_t structure with the address data of the - * remote peer as illustrated by the following example: - * - * @code -int dtls_handle_read(struct dtls_context_t *ctx) { - int *fd; - session_t session; - static uint8 buf[DTLS_MAX_BUF]; - int len; - - fd = dtls_get_app_data(ctx); - - assert(fd); - - session.size = sizeof(session.addr); - len = recvfrom(*fd, buf, sizeof(buf), 0, &session.addr.sa, &session.size); - - return len < 0 ? len : dtls_handle_message(ctx, &session, buf, len); -} - * @endcode - * - * Once a new DTLS session was established and DTLS ApplicationData has been - * received, the DTLS server invokes the read callback with the MAC-verified - * cleartext data as its argument. A read callback for a simple echo server - * could look like this: - * @code -int read_from_peer(struct dtls_context_t *ctx, session_t *session, uint8 *data, size_t len) { - return dtls_write(ctx, session, data, len); -} - * @endcode - * - * @subsection dtls_send_cb The Send Callback - * - * The callback function send_to_peer() is called whenever data must be - * sent over the network. Here, the sendto() system call is used to - * transmit data within the given session. The socket descriptor required - * by sendto() has been registered as application data when the DTLS context - * was created with dtls_new_context(). - * Note that it is on the application to buffer the data when it cannot be - * sent at the time this callback is invoked. The following example thus - * is incomplete as it would have to deal with EAGAIN somehow. - * @code -int send_to_peer(struct dtls_context_t *ctx, session_t *session, uint8 *data, size_t len) { - int fd = *(int *)dtls_get_app_data(ctx); - return sendto(fd, data, len, MSG_DONTWAIT, &session->addr.sa, session->size); -} - * @endcode - * - * @subsection dtls_get_psk_info The Key Storage - * - * When a new DTLS session is created, the library must ask the application - * for keying material. To do so, it invokes the registered call-back function - * get_psk_info() with the current context and session information as parameter. - * When the call-back function is invoked with the parameter @p type set to - * @c DTLS_PSK_IDENTITY, the result parameter @p result must be filled with - * the psk_identity_hint in case of a server, or the actual psk_identity in - * case of a client. When @p type is @c DTLS_PSK_KEY, the result parameter - * must be filled with a key for the given identity @p id. The function must - * return the number of bytes written to @p result which must not exceed - * @p result_length. - * In case of an error, the function must return a negative value that - * corresponds to a valid error code defined in alert.h. - * - * @code -int get_psk_info(struct dtls_context_t *ctx UNUSED_PARAM, - const session_t *session UNUSED_PARAM, - dtls_credentials_type_t type, - const unsigned char *id, size_t id_len, - unsigned char *result, size_t result_length) { - - switch (type) { - case DTLS_PSK_IDENTITY: - if (result_length < psk_id_length) { - dtls_warn("cannot set psk_identity -- buffer too small\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - memcpy(result, psk_id, psk_id_length); - return psk_id_length; - case DTLS_PSK_KEY: - if (id_len != psk_id_length || memcmp(psk_id, id, id_len) != 0) { - dtls_warn("PSK for unknown id requested, exiting\n"); - return dtls_alert_fatal_create(DTLS_ALERT_ILLEGAL_PARAMETER); - } else if (result_length < psk_key_length) { - dtls_warn("cannot set psk -- buffer too small\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - memcpy(result, psk_key, psk_key_length); - return psk_key_length; - default: - dtls_warn("unsupported request type: %d\n", type); - } - - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); -} - * @endcode - * - * @subsection dtls_events The Event Notifier - * - * Applications that want to be notified whenever the status of a DTLS session - * has changed can register an event handling function with the field @c event - * in the dtls_handler_t structure (see \ref dtls_server_example). The call-back - * function is called for alert messages and internal state changes. For alert - * messages, the argument @p level will be set to a value greater than zero, and - * @p code will indicate the notification code. For internal events, @p level - * is @c 0, and @p code a value greater than @c 255. - * - * Internal events are DTLS_EVENT_CONNECTED, @c DTLS_EVENT_CONNECT, and - * @c DTLS_EVENT_RENEGOTIATE. - * - * @code -int handle_event(struct dtls_context_t *ctx, session_t *session, - dtls_alert_level_t level, unsigned short code) { - ... do something with event ... - return 0; -} - * @endcode - * - * @section dtls_client_example DTLS Client Example - * - * A DTLS client is constructed like a server but needs to actively setup - * a new session by calling dtls_connect() at some point. As this function - * usually returns before the new DTLS channel is established, the application - * must register an event handler and wait for @c DTLS_EVENT_CONNECT before - * it can send data over the DTLS channel. - * - */ - -/** - * @addtogroup contiki Contiki - * - * To use tinyDTLS as Contiki application, place the source code in the directory - * @c apps/tinydtls in the Contiki source tree and invoke configure with the option - * @c --with-contiki. This will define WITH_CONTIKI in tinydtls.h and include - * @c Makefile.contiki in the main Makefile. To cross-compile for another platform - * you will need to set your host and build system accordingly. For example, - * when configuring for ARM, you would invoke - * @code -./configure --with-contiki --build=x86_64-linux-gnu --host=arm-none-eabi - * @endcode - * on an x86_64 linux host. - * - * Then, create a Contiki project with @c APPS += tinydtls in its Makefile. A sample - * server could look like this (with read_from_peer() and get_psk_key() as shown above). - * - * @code -#include "contiki.h" - -#include "tinydtls.h" -#include "dtls.h" - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN]) - -int send_to_peer(struct dtls_context_t *, session_t *, uint8 *, size_t); - -static struct uip_udp_conn *server_conn; -static dtls_context_t *dtls_context; - -static dtls_handler_t cb = { - .write = send_to_peer, - .read = read_from_peer, - .event = NULL, - .get_psk_key = get_psk_key -}; - -PROCESS(server_process, "DTLS server process"); -AUTOSTART_PROCESSES(&server_process); - -PROCESS_THREAD(server_process, ev, data, user_data) -{ - PROCESS_BEGIN(); - - dtls_init(); - - server_conn = udp_new(NULL, 0, NULL); - udp_bind(server_conn, UIP_HTONS(5684)); - - dtls_context = dtls_new_context(server_conn); - if (!dtls_context) { - dtls_emerg("cannot create context\n"); - PROCESS_EXIT(); - } - - dtls_set_handler(dtls_context, &cb); - - while(1) { - PROCESS_WAIT_EVENT(); - if(ev == tcpip_event && uip_newdata()) { - session_t session; - - uip_ipaddr_copy(&session.addr, &UIP_IP_BUF->srcipaddr); - session.port = UIP_UDP_BUF->srcport; - session.size = sizeof(session.addr) + sizeof(session.port); - - dtls_handle_message(ctx, &session, uip_appdata, uip_datalen()); - } - } - - PROCESS_END(); -} - -int send_to_peer(struct dtls_context_t *ctx, session_t *session, uint8 *data, size_t len) { - struct uip_udp_conn *conn = (struct uip_udp_conn *)dtls_get_app_data(ctx); - - uip_ipaddr_copy(&conn->ripaddr, &session->addr); - conn->rport = session->port; - - uip_udp_packet_send(conn, data, len); - - memset(&conn->ripaddr, 0, sizeof(server_conn->ripaddr)); - memset(&conn->rport, 0, sizeof(conn->rport)); - - return len; -} - * @endcode - */ diff --git a/net/ip/tinydtls/dtls_config.h b/net/ip/tinydtls/dtls_config.h deleted file mode 100644 index 3c3edc5371aee184a177e4a19d9420c13c2346ff..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/dtls_config.h +++ /dev/null @@ -1,153 +0,0 @@ -/* dtls_config.h. Generated from dtls_config.h.in by configure. */ -/* dtls_config.h.in. Generated from configure.in by autoheader. */ - -/* Define if building universal (internal helper macro) */ -/* #undef AC_APPLE_UNIVERSAL_BUILD */ - -/* Define to 1 if building with ECC support. */ -#define DTLS_ECC 1 - -/* Define to 1 if building with PSK support */ -#define DTLS_PSK 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ARPA_INET_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ASSERT_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_FCNTL_H */ - -/* Define to 1 if you have the `fls' function. */ -/* #undef HAVE_FLS */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_INTTYPES_H */ - -/* Define to 1 if your system has a GNU libc compatible `malloc' function, and - to 0 otherwise. */ -/* #undef HAVE_MALLOC */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_MEMORY_H */ - -/* Define to 1 if you have the `memset' function. */ -/* #undef HAVE_MEMSET */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NETDB_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NETINET_IN_H */ - -/* Define to 1 if you have the `select' function. */ -/* #undef HAVE_SELECT */ - -/* Define to 1 if struct sockaddr_in6 has a member sin6_len. */ -/* #undef HAVE_SOCKADDR_IN6_SIN6_LEN */ - -/* Define to 1 if you have the `socket' function. */ -/* #undef HAVE_SOCKET */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STDDEF_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STDINT_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STDLIB_H */ - -/* Define to 1 if you have the `strdup' function. */ -/* #undef HAVE_STRDUP */ - -/* Define to 1 if you have the `strerror' function. */ -/* #undef HAVE_STRERROR */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STRINGS_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STRING_H */ - -/* Define to 1 if you have the `strnlen' function. */ -/* #undef HAVE_STRNLEN */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_PARAM_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SOCKET_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_STAT_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_TIME_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_TYPES_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_TIME_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_UNISTD_H */ - -/* Define to 1 if you have the `vprintf' function. */ -/* #undef HAVE_VPRINTF */ - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "tinydtls" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "tinydtls 0.8.2" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "tinydtls" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "0.8.2" - -/* Define to 1 if you have the ANSI C header files. */ -/* #undef STDC_HEADERS */ - -/* Define to 1 if building for Contiki. */ -#define WITH_CONTIKI 1 -#define CONTIKI 1 - -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -/* # undef WORDS_BIGENDIAN */ -# endif -#endif - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to rpl_malloc if the replacement function should be used. */ -/* #undef malloc */ - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ - - -#ifdef WITH_CONTIKI -#include "platform-specific/platform.h" -#endif diff --git a/net/ip/tinydtls/dtls_time.c b/net/ip/tinydtls/dtls_time.c deleted file mode 100644 index 32c69e57f2837cd89ce88dfaba5955a6992774a8..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/dtls_time.c +++ /dev/null @@ -1,79 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2013 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * @file dtls_time.c - * @brief Clock Handling - */ - -#include "tinydtls.h" -#include "dtls_config.h" -#include "dtls_time.h" - -#ifdef WITH_CONTIKI -clock_time_t dtls_clock_offset; - -void -dtls_clock_init(void) { - dtls_clock_offset = clock_time(); -} - -void -dtls_ticks(dtls_tick_t *t) { - *t = clock_time(); -} - -#else /* WITH_CONTIKI */ - -time_t dtls_clock_offset; - -void -dtls_clock_init(void) { -#ifdef HAVE_TIME_H - dtls_clock_offset = time(NULL); -#else -# ifdef __GNUC__ - /* Issue a warning when using gcc. Other prepropressors do - * not seem to have a similar feature. */ -# warning "cannot initialize clock" -# endif - dtls_clock_offset = 0; -#endif -} - -void dtls_ticks(dtls_tick_t *t) { -#ifdef HAVE_SYS_TIME_H - struct timeval tv; - gettimeofday(&tv, NULL); - *t = (tv.tv_sec - dtls_clock_offset) * DTLS_TICKS_PER_SECOND - + (tv.tv_usec * DTLS_TICKS_PER_SECOND / 1000000); -#else -#error "clock not implemented" -#endif -} - -#endif /* WITH_CONTIKI */ - - diff --git a/net/ip/tinydtls/dtls_time.h b/net/ip/tinydtls/dtls_time.h deleted file mode 100644 index 933d2ceb4ef6f313e1d20dcd4cb353cd8e9146e6..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/dtls_time.h +++ /dev/null @@ -1,69 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2013 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * @file dtls_time.h - * @brief Clock Handling - */ - -#ifndef _DTLS_DTLS_TIME_H_ -#define _DTLS_DTLS_TIME_H_ - -#include -#include - -#include "tinydtls.h" - -/** - * @defgroup clock Clock Handling - * Default implementation of internal clock. You should redefine this if - * you do not have time() and gettimeofday(). - * @{ - */ - -#ifdef WITH_CONTIKI -#include -#else /* WITH_CONTIKI */ -#include - -#ifndef CLOCK_SECOND -# define CLOCK_SECOND 1000 -#endif - -typedef uint32_t clock_time_t; -#endif /* WITH_CONTIKI */ - -typedef clock_time_t dtls_tick_t; - -#ifndef DTLS_TICKS_PER_SECOND -#define DTLS_TICKS_PER_SECOND CLOCK_SECOND -#endif /* DTLS_TICKS_PER_SECOND */ - -void dtls_clock_init(void); -void dtls_ticks(dtls_tick_t *t); - -/** @} */ - -#endif /* _DTLS_DTLS_TIME_H_ */ diff --git a/net/ip/tinydtls/ecc/Makefile.contiki b/net/ip/tinydtls/ecc/Makefile.contiki deleted file mode 100644 index 7787d2d46e71c6e8a1d7e015529a2e207a1d6cc5..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/ecc/Makefile.contiki +++ /dev/null @@ -1,7 +0,0 @@ -CONTIKI=../../.. - -APPS += ecc - -CFLAGS += -DTEST_INCLUDE - -include $(CONTIKI)/Makefile.include diff --git a/net/ip/tinydtls/ecc/Makefile.ecc b/net/ip/tinydtls/ecc/Makefile.ecc deleted file mode 100644 index 382e48fdabd661c7bf5eb18e176c919e73bd53b0..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/ecc/Makefile.ecc +++ /dev/null @@ -1,3 +0,0 @@ -# This is a -*- Makefile -*- - -ecc_src = ecc.c test_helper.c diff --git a/net/ip/tinydtls/ecc/Makefile.in b/net/ip/tinydtls/ecc/Makefile.in deleted file mode 100644 index 4631cbb18b16865f6fe218087960f697492b849e..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/ecc/Makefile.in +++ /dev/null @@ -1,90 +0,0 @@ -# Makefile for tinydtls -# -# Copyright (C) 2011 Olaf Bergmann -# Copyright (C) 2013 Hauke Mehrtens -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, copy, -# modify, merge, publish, distribute, sublicense, and/or sell copies -# of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# the library's version -VERSION:=@PACKAGE_VERSION@ - -# tools -@SET_MAKE@ -SHELL = /bin/sh -MKDIR = mkdir - -abs_builddir = @abs_builddir@ -top_builddir = @top_builddir@ -top_srcdir:= @top_srcdir@ - -ECC_SOURCES:= ecc.c testecc.c testfield.c test_helper.c -ECC_HEADERS:= ecc.h test_helper.h -FILES:=Makefile.in Makefile.contiki $(ECC_SOURCES) $(ECC_HEADERS) -DISTDIR=$(top_builddir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@ - -ifeq ("@WITH_CONTIKI@", "1") -include Makefile.contiki -else -ECC_OBJECTS:= $(patsubst %.c, %.o, $(ECC_SOURCES)) ecc_test.o -PROGRAMS:= testecc testfield -CPPFLAGS=@CPPFLAGS@ -CFLAGS=-Wall -std=c99 -pedantic @CFLAGS@ -DTEST_INCLUDE -LDLIBS=@LIBS@ - -.PHONY: all dirs clean install distclean .gitignore doc - -.SUFFIXES: -.SUFFIXES: .c .o - -all: $(PROGRAMS) - -ecc_test.o: ecc.c ecc.h - $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< - -testecc: ecc_test.o test_helper.o - -testfield: ecc_test.o test_helper.o - -check: - echo DISTDIR: $(DISTDIR) - echo top_builddir: $(top_builddir) - -clean: - @rm -f $(PROGRAMS) main.o $(LIB) $(OBJECTS) - for dir in $(SUBDIRS); do \ - $(MAKE) -C $$dir clean ; \ - done - -distclean: clean - @rm -rf $(DISTDIR) - @rm -f *~ $(DISTDIR).tar.gz -endif # WITH_CONTIKI - -dist: $(FILES) - test -d $(DISTDIR)/ecc || mkdir $(DISTDIR)/ecc - cp -p $(FILES) $(DISTDIR)/ecc - -install: $(HEADERS) - test -d $(includedir)/ecc || mkdir -p $(includedir)/ecc - $(install) $(HEADERS) $(includedir)/ecc - -.gitignore: - echo "core\n*~\n*.[oa]\n*.gz\n*.cap\n$(PROGRAM)\n$(DISTDIR)\n.gitignore" >$@ diff --git a/net/ip/tinydtls/ecc/ecc.c b/net/ip/tinydtls/ecc/ecc.c deleted file mode 100644 index c6c8497d5fc782745eebdcfe4856578a6d709487..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/ecc/ecc.c +++ /dev/null @@ -1,707 +0,0 @@ -/* - * Copyright (c) 2009 Chris K Cockrum - * - * Copyright (c) 2013 Jens Trillmann - * Copyright (c) 2013 Marc Müller-Weinhardt - * Copyright (c) 2013 Lars Schmertmann - * Copyright (c) 2013 Hauke Mehrtens - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * - * This implementation is based in part on the paper Implementation of an - * Elliptic Curve Cryptosystem on an 8-bit Microcontroller [0] by - * Chris K Cockrum . - * - * [0]: http://cockrum.net/Implementation_of_ECC_on_an_8-bit_microcontroller.pdf - * - * This is a efficient ECC implementation on the secp256r1 curve for 32 Bit CPU - * architectures. It provides basic operations on the secp256r1 curve and support - * for ECDH and ECDSA. - */ - -//big number functions -#include "ecc.h" -#include - -static uint32_t add( const uint32_t *x, const uint32_t *y, uint32_t *result, uint8_t length){ - uint64_t d = 0; //carry - int v = 0; - for(v = 0;v>32; //save carry - } - - return (uint32_t)d; -} - -static uint32_t sub( const uint32_t *x, const uint32_t *y, uint32_t *result, uint8_t length){ - uint64_t d = 0; - int v; - for(v = 0;v < length; v++){ - d = (uint64_t) x[v] - (uint64_t) y[v] - d; - result[v] = d & 0xFFFFFFFF; - d = d>>32; - d &= 0x1; - } - return (uint32_t)d; -} - -static void rshiftby(const uint32_t *in, uint8_t in_size, uint32_t *out, uint8_t out_size, uint8_t shift) { - int i; - - for (i = 0; i < (in_size - shift) && i < out_size; i++) - out[i] = in[i + shift]; - for (/* reuse i */; i < out_size; i++) - out[i] = 0; -} - -//finite field functions -//FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF -static const uint32_t ecc_prime_m[8] = {0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, - 0x00000000, 0x00000000, 0x00000001, 0xffffffff}; - - -/* This is added after an static byte addition if the answer has a carry in MSB*/ -static const uint32_t ecc_prime_r[8] = {0x00000001, 0x00000000, 0x00000000, 0xffffffff, - 0xffffffff, 0xffffffff, 0xfffffffe, 0x00000000}; - -// ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 -static const uint32_t ecc_order_m[9] = {0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, - 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, - 0x00000000}; - -static const uint32_t ecc_order_r[8] = {0x039CDAAF, 0x0C46353D, 0x58E8617B, 0x43190552, - 0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000}; - -static const uint32_t ecc_order_mu[9] = {0xEEDF9BFE, 0x012FFD85, 0xDF1A6C21, 0x43190552, - 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x00000000, - 0x00000001}; - -static const uint8_t ecc_order_k = 8; - -const uint32_t ecc_g_point_x[8] = { 0xD898C296, 0xF4A13945, 0x2DEB33A0, 0x77037D81, - 0x63A440F2, 0xF8BCE6E5, 0xE12C4247, 0x6B17D1F2}; -const uint32_t ecc_g_point_y[8] = { 0x37BF51F5, 0xCBB64068, 0x6B315ECE, 0x2BCE3357, - 0x7C0F9E16, 0x8EE7EB4A, 0xFE1A7F9B, 0x4FE342E2}; - - -static void setZero(uint32_t *A, const int length){ - memset(A, 0x0, length * sizeof(uint32_t)); -} - -/* - * copy one array to another - */ -static void copy(const uint32_t *from, uint32_t *to, uint8_t length){ - memcpy(to, from, length * sizeof(uint32_t)); -} - -static int isSame(const uint32_t *A, const uint32_t *B, uint8_t length){ - return !memcmp(A, B, length * sizeof(uint32_t)); -} - -//is A greater than B? -static int isGreater(const uint32_t *A, const uint32_t *B, uint8_t length){ - int i; - for (i = length-1; i >= 0; --i) - { - if(A[i] > B[i]) - return 1; - if(A[i] < B[i]) - return -1; - } - return 0; -} - - -static int fieldAdd(const uint32_t *x, const uint32_t *y, const uint32_t *reducer, uint32_t *result){ - if(add(x, y, result, arrayLength)){ //add prime if carry is still set! - uint32_t tempas[8]; - setZero(tempas, 8); - add(result, reducer, tempas, arrayLength); - copy(tempas, result, arrayLength); - } - return 0; -} - -static int fieldSub(const uint32_t *x, const uint32_t *y, const uint32_t *modulus, uint32_t *result){ - if(sub(x, y, result, arrayLength)){ //add modulus if carry is set - uint32_t tempas[8]; - setZero(tempas, 8); - add(result, modulus, tempas, arrayLength); - copy(tempas, result, arrayLength); - } - return 0; -} - -//finite Field multiplication -//32bit * 32bit = 64bit -static int fieldMult(const uint32_t *x, const uint32_t *y, uint32_t *result, uint8_t length){ - uint32_t temp[length * 2]; - setZero(temp, length * 2); - setZero(result, length * 2); - uint8_t k, n; - uint64_t l; - for (k = 0; k < length; k++){ - for (n = 0; n < length; n++){ - l = (uint64_t)x[n]*(uint64_t)y[k]; - temp[n+k] = l&0xFFFFFFFF; - temp[n+k+1] = l>>32; - add(&temp[n+k], &result[n+k], &result[n+k], (length * 2) - (n + k)); - - setZero(temp, length * 2); - } - } - return 0; -} - -//TODO: maximum: -//fffffffe00000002fffffffe0000000100000001fffffffe00000001fffffffe00000001fffffffefffffffffffffffffffffffe000000000000000000000001_16 -static void fieldModP(uint32_t *A, const uint32_t *B) -{ - uint32_t tempm[8]; - uint32_t tempm2[8]; - uint8_t n; - setZero(tempm, 8); - setZero(tempm2, 8); - /* A = T */ - copy(B,A,arrayLength); - - /* Form S1 */ - for(n=0;n<3;n++) tempm[n]=0; - for(n=3;n<8;n++) tempm[n]=B[n+8]; - - /* tempm2=T+S1 */ - fieldAdd(A,tempm,ecc_prime_r,tempm2); - /* A=T+S1+S1 */ - fieldAdd(tempm2,tempm,ecc_prime_r,A); - /* Form S2 */ - for(n=0;n<3;n++) tempm[n]=0; - for(n=3;n<7;n++) tempm[n]=B[n+9]; - for(n=7;n<8;n++) tempm[n]=0; - /* tempm2=T+S1+S1+S2 */ - fieldAdd(A,tempm,ecc_prime_r,tempm2); - /* A=T+S1+S1+S2+S2 */ - fieldAdd(tempm2,tempm,ecc_prime_r,A); - /* Form S3 */ - for(n=0;n<3;n++) tempm[n]=B[n+8]; - for(n=3;n<6;n++) tempm[n]=0; - for(n=6;n<8;n++) tempm[n]=B[n+8]; - /* tempm2=T+S1+S1+S2+S2+S3 */ - fieldAdd(A,tempm,ecc_prime_r,tempm2); - /* Form S4 */ - for(n=0;n<3;n++) tempm[n]=B[n+9]; - for(n=3;n<6;n++) tempm[n]=B[n+10]; - for(n=6;n<7;n++) tempm[n]=B[n+7]; - for(n=7;n<8;n++) tempm[n]=B[n+1]; - /* A=T+S1+S1+S2+S2+S3+S4 */ - fieldAdd(tempm2,tempm,ecc_prime_r,A); - /* Form D1 */ - for(n=0;n<3;n++) tempm[n]=B[n+11]; - for(n=3;n<6;n++) tempm[n]=0; - for(n=6;n<7;n++) tempm[n]=B[n+2]; - for(n=7;n<8;n++) tempm[n]=B[n+3]; - /* tempm2=T+S1+S1+S2+S2+S3+S4-D1 */ - fieldSub(A,tempm,ecc_prime_m,tempm2); - /* Form D2 */ - for(n=0;n<4;n++) tempm[n]=B[n+12]; - for(n=4;n<6;n++) tempm[n]=0; - for(n=6;n<7;n++) tempm[n]=B[n+3]; - for(n=7;n<8;n++) tempm[n]=B[n+4]; - /* A=T+S1+S1+S2+S2+S3+S4-D1-D2 */ - fieldSub(tempm2,tempm,ecc_prime_m,A); - /* Form D3 */ - for(n=0;n<3;n++) tempm[n]=B[n+13]; - for(n=3;n<6;n++) tempm[n]=B[n+5]; - for(n=6;n<7;n++) tempm[n]=0; - for(n=7;n<8;n++) tempm[n]=B[n+5]; - /* tempm2=T+S1+S1+S2+S2+S3+S4-D1-D2-D3 */ - fieldSub(A,tempm,ecc_prime_m,tempm2); - /* Form D4 */ - for(n=0;n<2;n++) tempm[n]=B[n+14]; - for(n=2;n<3;n++) tempm[n]=0; - for(n=3;n<6;n++) tempm[n]=B[n+6]; - for(n=6;n<7;n++) tempm[n]=0; - for(n=7;n<8;n++) tempm[n]=B[n+6]; - /* A=T+S1+S1+S2+S2+S3+S4-D1-D2-D3-D4 */ - fieldSub(tempm2,tempm,ecc_prime_m,A); - if(isGreater(A, ecc_prime_m, arrayLength) >= 0){ - fieldSub(A, ecc_prime_m, ecc_prime_m, tempm); - copy(tempm, A, arrayLength); - } -} - -/** - * calculate the result = A mod n. - * n is the order of the eliptic curve. - * A and result could point to the same value - * - * A: input value (max size * 4 bytes) - * result: result of modulo calculation (max 36 bytes) - * size: size of A - * - * This uses the Barrett modular reduction as described in the Handbook - * of Applied Cryptography 14.42 Algorithm Barrett modular reduction, - * see http://cacr.uwaterloo.ca/hac/about/chap14.pdf and - * http://everything2.com/title/Barrett+Reduction - * - * b = 32 (bite size of the processor architecture) - * mu (ecc_order_mu) was precomputed in a java program - */ -static void fieldModO(const uint32_t *A, uint32_t *result, uint8_t length) { - // This is used for value q1 and q3 - uint32_t q1_q3[9]; - // This is used for q2 and a temp var - uint32_t q2_tmp[18]; - - // return if the given value is smaller than the modulus - if (length == arrayLength && isGreater(A, ecc_order_m, arrayLength) <= 0) { - if (A != result) - copy(A, result, length); - return; - } - - rshiftby(A, length, q1_q3, 9, ecc_order_k - 1); - - fieldMult(ecc_order_mu, q1_q3, q2_tmp, 9); - - rshiftby(q2_tmp, 18, q1_q3, 8, ecc_order_k + 1); - - // r1 = first 9 blocks of A - - fieldMult(q1_q3, ecc_order_m, q2_tmp, 8); - - // r2 = first 9 blocks of q2_tmp - - sub(A, q2_tmp, result, 9); - - while (isGreater(result, ecc_order_m, 9) >= 0) - sub(result, ecc_order_m, result, 9); -} - -static int isOne(const uint32_t* A){ - uint8_t n; - for(n=1;n<8;n++) - if (A[n]!=0) - break; - - if ((n==8)&&(A[0]==1)) - return 1; - else - return 0; -} - -static int isZero(const uint32_t* A){ - uint8_t n, r=0; - for(n=0;n<8;n++){ - if (A[n] == 0) r++; - } - return r==8; -} - -static void rshift(uint32_t* A){ - int n, i; - uint32_t nOld = 0; - for (i = 8; i--;) - { - n = A[i]&0x1; - A[i] = A[i]>>1 | nOld<<31; - nOld = n; - } -} - -static int fieldAddAndDivide(const uint32_t *x, const uint32_t *modulus, const uint32_t *reducer, uint32_t* result){ - uint32_t n = add(x, modulus, result, arrayLength); - rshift(result); - if(n){ //add prime if carry is still set! - result[7] |= 0x80000000;//add the carry - if (isGreater(result, modulus, arrayLength) == 1) - { - uint32_t tempas[8]; - setZero(tempas, 8); - add(result, reducer, tempas, 8); - copy(tempas, result, arrayLength); - } - - } - return 0; -} - -/* - * Inverse A and output to B - */ -static void fieldInv(const uint32_t *A, const uint32_t *modulus, const uint32_t *reducer, uint32_t *B){ - uint32_t u[8],v[8],x1[8],x2[8]; - uint32_t tempm[8]; - uint32_t tempm2[8]; - setZero(tempm, 8); - setZero(tempm2, 8); - setZero(u, 8); - setZero(v, 8); - - uint8_t t; - copy(A,u,arrayLength); - copy(modulus,v,arrayLength); - setZero(x1, 8); - setZero(x2, 8); - x1[0]=1; - /* While u !=1 and v !=1 */ - while ((isOne(u) || isOne(v))==0) { - while(!(u[0]&1)) { /* While u is even */ - rshift(u); /* divide by 2 */ - if (!(x1[0]&1)) /*ifx1iseven*/ - rshift(x1); /* Divide by 2 */ - else { - fieldAddAndDivide(x1,modulus,reducer,tempm); /* tempm=x1+p */ - copy(tempm,x1,arrayLength); /* x1=tempm */ - //rshift(x1); /* Divide by 2 */ - } - } - while(!(v[0]&1)) { /* While v is even */ - rshift(v); /* divide by 2 */ - if (!(x2[0]&1)) /*ifx1iseven*/ - rshift(x2); /* Divide by 2 */ - else - { - fieldAddAndDivide(x2,modulus,reducer,tempm); /* tempm=x1+p */ - copy(tempm,x2,arrayLength); /* x1=tempm */ - //rshift(x2); /* Divide by 2 */ - } - - } - t=sub(u,v,tempm,arrayLength); /* tempm=u-v */ - if (t==0) { /* If u > 0 */ - copy(tempm,u,arrayLength); /* u=u-v */ - fieldSub(x1,x2,modulus,tempm); /* tempm=x1-x2 */ - copy(tempm,x1,arrayLength); /* x1=x1-x2 */ - } else { - sub(v,u,tempm,arrayLength); /* tempm=v-u */ - copy(tempm,v,arrayLength); /* v=v-u */ - fieldSub(x2,x1,modulus,tempm); /* tempm=x2-x1 */ - copy(tempm,x2,arrayLength); /* x2=x2-x1 */ - } - } - if (isOne(u)) { - copy(x1,B,arrayLength); - } else { - copy(x2,B,arrayLength); - } -} - -void static ec_double(const uint32_t *px, const uint32_t *py, uint32_t *Dx, uint32_t *Dy){ - uint32_t tempA[8]; - uint32_t tempB[8]; - uint32_t tempC[8]; - uint32_t tempD[16]; - - if(isZero(px) && isZero(py)){ - copy(px, Dx,arrayLength); - copy(py, Dy,arrayLength); - return; - } - - fieldMult(px, px, tempD, arrayLength); - fieldModP(tempA, tempD); - setZero(tempB, 8); - tempB[0] = 0x00000001; - fieldSub(tempA, tempB, ecc_prime_m, tempC); //tempC = (qx^2-1) - tempB[0] = 0x00000003; - fieldMult(tempC, tempB, tempD, arrayLength); - fieldModP(tempA, tempD);//tempA = 3*(qx^2-1) - fieldAdd(py, py, ecc_prime_r, tempB); //tempB = 2*qy - fieldInv(tempB, ecc_prime_m, ecc_prime_r, tempC); //tempC = 1/(2*qy) - fieldMult(tempA, tempC, tempD, arrayLength); //tempB = lambda = (3*(qx^2-1))/(2*qy) - fieldModP(tempB, tempD); - - fieldMult(tempB, tempB, tempD, arrayLength); //tempC = lambda^2 - fieldModP(tempC, tempD); - fieldSub(tempC, px, ecc_prime_m, tempA); //lambda^2 - Px - fieldSub(tempA, px, ecc_prime_m, Dx); //lambda^2 - Px - Qx - - fieldSub(px, Dx, ecc_prime_m, tempA); //tempA = qx-dx - fieldMult(tempB, tempA, tempD, arrayLength); //tempC = lambda * (qx-dx) - fieldModP(tempC, tempD); - fieldSub(tempC, py, ecc_prime_m, Dy); //Dy = lambda * (qx-dx) - px -} - -void static ec_add(const uint32_t *px, const uint32_t *py, const uint32_t *qx, const uint32_t *qy, uint32_t *Sx, uint32_t *Sy){ - uint32_t tempA[8]; - uint32_t tempB[8]; - uint32_t tempC[8]; - uint32_t tempD[16]; - - if(isZero(px) && isZero(py)){ - copy(qx, Sx,arrayLength); - copy(qy, Sy,arrayLength); - return; - } else if(isZero(qx) && isZero(qy)) { - copy(px, Sx,arrayLength); - copy(py, Sy,arrayLength); - return; - } - - if(isSame(px, qx, arrayLength)){ - if(!isSame(py, qy, arrayLength)){ - setZero(Sx, 8); - setZero(Sy, 8); - return; - } else { - ec_double(px, py, Sx, Sy); - return; - } - } - - fieldSub(py, qy, ecc_prime_m, tempA); - fieldSub(px, qx, ecc_prime_m, tempB); - fieldInv(tempB, ecc_prime_m, ecc_prime_r, tempB); - fieldMult(tempA, tempB, tempD, arrayLength); - fieldModP(tempC, tempD); //tempC = lambda - - fieldMult(tempC, tempC, tempD, arrayLength); //tempA = lambda^2 - fieldModP(tempA, tempD); - fieldSub(tempA, px, ecc_prime_m, tempB); //lambda^2 - Px - fieldSub(tempB, qx, ecc_prime_m, Sx); //lambda^2 - Px - Qx - - fieldSub(qx, Sx, ecc_prime_m, tempB); - fieldMult(tempC, tempB, tempD, arrayLength); - fieldModP(tempC, tempD); - fieldSub(tempC, qy, ecc_prime_m, Sy); -} - -void ecc_ec_mult(const uint32_t *px, const uint32_t *py, const uint32_t *secret, uint32_t *resultx, uint32_t *resulty){ - uint32_t Qx[8]; - uint32_t Qy[8]; - setZero(Qx, 8); - setZero(Qy, 8); - - uint32_t tempx[8]; - uint32_t tempy[8]; - - int i; - for (i = 256;i--;){ - ec_double(Qx, Qy, tempx, tempy); - copy(tempx, Qx,arrayLength); - copy(tempy, Qy,arrayLength); - if (((secret[i / 32]) & ((uint32_t)1 << (i % 32)))) { - ec_add(Qx, Qy, px, py, tempx, tempy); //eccAdd - copy(tempx, Qx,arrayLength); - copy(tempy, Qy,arrayLength); - } - } - copy(Qx, resultx,arrayLength); - copy(Qy, resulty,arrayLength); -} - -/** - * Calculate the ecdsa signature. - * - * For a description of this algorithm see - * https://en.wikipedia.org/wiki/Elliptic_Curve_DSA#Signature_generation_algorithm - * - * input: - * d: private key on the curve secp256r1 (32 bytes) - * e: hash to sign (32 bytes) - * k: random data, this must be changed for every signature (32 bytes) - * - * output: - * r: r value of the signature (36 bytes) - * s: s value of the signature (36 bytes) - * - * return: - * 0: everything is ok - * -1: can not create signature, try again with different k. - */ -int ecc_ecdsa_sign(const uint32_t *d, const uint32_t *e, const uint32_t *k, uint32_t *r, uint32_t *s) -{ - uint32_t tmp1[16]; - uint32_t tmp2[9]; - uint32_t tmp3[9]; - - if (isZero(k)) - return -1; - - // 4. Calculate the curve point (x_1, y_1) = k * G. - ecc_ec_mult(ecc_g_point_x, ecc_g_point_y, k, r, tmp1); - - // 5. Calculate r = x_1 \pmod{n}. - fieldModO(r, r, 8); - - // 5. If r = 0, go back to step 3. - if (isZero(r)) - return -1; - - // 6. Calculate s = k^{-1}(z + r d_A) \pmod{n}. - // 6. r * d - fieldMult(r, d, tmp1, arrayLength); - fieldModO(tmp1, tmp2, 16); - - // 6. z + (r d) - tmp1[8] = add(e, tmp2, tmp1, 8); - fieldModO(tmp1, tmp3, 9); - - // 6. k^{-1} - fieldInv(k, ecc_order_m, ecc_order_r, tmp2); - - // 6. (k^{-1}) (z + (r d)) - fieldMult(tmp2, tmp3, tmp1, arrayLength); - fieldModO(tmp1, s, 16); - - // 6. If s = 0, go back to step 3. - if (isZero(s)) - return -1; - - return 0; -} - -/** - * Verifies a ecdsa signature. - * - * For a description of this algorithm see - * https://en.wikipedia.org/wiki/Elliptic_Curve_DSA#Signature_verification_algorithm - * - * input: - * x: x coordinate of the public key (32 bytes) - * y: y coordinate of the public key (32 bytes) - * e: hash to verify the signature of (32 bytes) - * r: r value of the signature (32 bytes) - * s: s value of the signature (32 bytes) - * - * return: - * 0: signature is ok - * -1: signature check failed the signature is invalid - */ -int ecc_ecdsa_validate(const uint32_t *x, const uint32_t *y, const uint32_t *e, const uint32_t *r, const uint32_t *s) -{ - uint32_t w[8]; - uint32_t tmp[16]; - uint32_t u1[9]; - uint32_t u2[9]; - uint32_t tmp1_x[8]; - uint32_t tmp1_y[8]; - uint32_t tmp2_x[8]; - uint32_t tmp2_y[8]; - uint32_t tmp3_x[8]; - uint32_t tmp3_y[8]; - - // 3. Calculate w = s^{-1} \pmod{n} - fieldInv(s, ecc_order_m, ecc_order_r, w); - - // 4. Calculate u_1 = zw \pmod{n} - fieldMult(e, w, tmp, arrayLength); - fieldModO(tmp, u1, 16); - - // 4. Calculate u_2 = rw \pmod{n} - fieldMult(r, w, tmp, arrayLength); - fieldModO(tmp, u2, 16); - - // 5. Calculate the curve point (x_1, y_1) = u_1 * G + u_2 * Q_A. - // tmp1 = u_1 * G - ecc_ec_mult(ecc_g_point_x, ecc_g_point_y, u1, tmp1_x, tmp1_y); - - // tmp2 = u_2 * Q_A - ecc_ec_mult(x, y, u2, tmp2_x, tmp2_y); - - // tmp3 = tmp1 + tmp2 - ec_add(tmp1_x, tmp1_y, tmp2_x, tmp2_y, tmp3_x, tmp3_y); - // TODO: this u_1 * G + u_2 * Q_A could be optimiced with Straus's algorithm. - - return isSame(tmp3_x, r, arrayLength) ? 0 : -1; -} - -int ecc_is_valid_key(const uint32_t * priv_key) -{ - return isGreater(ecc_order_m, priv_key, arrayLength) == 1; -} - -/* - * This exports the low level functions so the tests can use them. - * In real use the compiler is now bale to optimice the code better. - */ -#ifdef TEST_INCLUDE -uint32_t ecc_add( const uint32_t *x, const uint32_t *y, uint32_t *result, uint8_t length) -{ - return add(x, y, result, length); -} -uint32_t ecc_sub( const uint32_t *x, const uint32_t *y, uint32_t *result, uint8_t length) -{ - return sub(x, y, result, length); -} -int ecc_fieldAdd(const uint32_t *x, const uint32_t *y, const uint32_t *reducer, uint32_t *result) -{ - return fieldAdd(x, y, reducer, result); -} -int ecc_fieldSub(const uint32_t *x, const uint32_t *y, const uint32_t *modulus, uint32_t *result) -{ - return fieldSub(x, y, modulus, result); -} -int ecc_fieldMult(const uint32_t *x, const uint32_t *y, uint32_t *result, uint8_t length) -{ - return fieldMult(x, y, result, length); -} -void ecc_fieldModP(uint32_t *A, const uint32_t *B) -{ - fieldModP(A, B); -} -void ecc_fieldModO(const uint32_t *A, uint32_t *result, uint8_t length) -{ - fieldModO(A, result, length); -} -void ecc_fieldInv(const uint32_t *A, const uint32_t *modulus, const uint32_t *reducer, uint32_t *B) -{ - fieldInv(A, modulus, reducer, B); -} -void ecc_copy(const uint32_t *from, uint32_t *to, uint8_t length) -{ - copy(from, to, length); -} -int ecc_isSame(const uint32_t *A, const uint32_t *B, uint8_t length) -{ - return isSame(A, B, length); -} -void ecc_setZero(uint32_t *A, const int length) -{ - setZero(A, length); -} -int ecc_isOne(const uint32_t* A) -{ - return isOne(A); -} -void ecc_rshift(uint32_t* A) -{ - rshift(A); -} -int ecc_isGreater(const uint32_t *A, const uint32_t *B, uint8_t length) -{ - return isGreater(A, B , length); -} - -void ecc_ec_add(const uint32_t *px, const uint32_t *py, const uint32_t *qx, const uint32_t *qy, uint32_t *Sx, uint32_t *Sy) -{ - ec_add(px, py, qx, qy, Sx, Sy); -} -void ecc_ec_double(const uint32_t *px, const uint32_t *py, uint32_t *Dx, uint32_t *Dy) -{ - ec_double(px, py, Dx, Dy); -} - -#endif /* TEST_INCLUDE */ diff --git a/net/ip/tinydtls/ecc/ecc.h b/net/ip/tinydtls/ecc/ecc.h deleted file mode 100644 index 3c0d9b1dc6cda204500488273a70ebff23e9e8c3..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/ecc/ecc.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2009 Chris K Cockrum - * - * Copyright (c) 2013 Jens Trillmann - * Copyright (c) 2013 Marc Müller-Weinhardt - * Copyright (c) 2013 Lars Schmertmann - * Copyright (c) 2013 Hauke Mehrtens - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * - * This implementation is based in part on the paper Implementation of an - * Elliptic Curve Cryptosystem on an 8-bit Microcontroller [0] by - * Chris K Cockrum . - * - * [0]: http://cockrum.net/Implementation_of_ECC_on_an_8-bit_microcontroller.pdf - * - * This is a efficient ECC implementation on the secp256r1 curve for 32 Bit CPU - * architectures. It provides basic operations on the secp256r1 curve and support - * for ECDH and ECDSA. - */ -#include - -#define keyLengthInBytes 32 -#define arrayLength 8 - -extern const uint32_t ecc_g_point_x[8]; -extern const uint32_t ecc_g_point_y[8]; - -//ec Functions -void ecc_ec_mult(const uint32_t *px, const uint32_t *py, const uint32_t *secret, uint32_t *resultx, uint32_t *resulty); - -static inline void ecc_ecdh(const uint32_t *px, const uint32_t *py, const uint32_t *secret, uint32_t *resultx, uint32_t *resulty) { - ecc_ec_mult(px, py, secret, resultx, resulty); -} -int ecc_ecdsa_validate(const uint32_t *x, const uint32_t *y, const uint32_t *e, const uint32_t *r, const uint32_t *s); -int ecc_ecdsa_sign(const uint32_t *d, const uint32_t *e, const uint32_t *k, uint32_t *r, uint32_t *s); - -int ecc_is_valid_key(const uint32_t * priv_key); -static inline void ecc_gen_pub_key(const uint32_t *priv_key, uint32_t *pub_x, uint32_t *pub_y) -{ - ecc_ec_mult(ecc_g_point_x, ecc_g_point_y, priv_key, pub_x, pub_y); -} - -#ifdef TEST_INCLUDE -//ec Functions -void ecc_ec_add(const uint32_t *px, const uint32_t *py, const uint32_t *qx, const uint32_t *qy, uint32_t *Sx, uint32_t *Sy); -void ecc_ec_double(const uint32_t *px, const uint32_t *py, uint32_t *Dx, uint32_t *Dy); - -//simple Functions for addition and substraction of big numbers -uint32_t ecc_add( const uint32_t *x, const uint32_t *y, uint32_t *result, uint8_t length); -uint32_t ecc_sub( const uint32_t *x, const uint32_t *y, uint32_t *result, uint8_t length); - -//field functions for big numbers -int ecc_fieldAdd(const uint32_t *x, const uint32_t *y, const uint32_t *reducer, uint32_t *result); -int ecc_fieldSub(const uint32_t *x, const uint32_t *y, const uint32_t *modulus, uint32_t *result); -int ecc_fieldMult(const uint32_t *x, const uint32_t *y, uint32_t *result, uint8_t length); -void ecc_fieldModP(uint32_t *A, const uint32_t *B); -void ecc_fieldModO(const uint32_t *A, uint32_t *result, uint8_t length); -void ecc_fieldInv(const uint32_t *A, const uint32_t *modulus, const uint32_t *reducer, uint32_t *B); - -//simple functions to work with the big numbers -void ecc_copy(const uint32_t *from, uint32_t *to, uint8_t length); -int ecc_isSame(const uint32_t *A, const uint32_t *B, uint8_t length); -void ecc_setZero(uint32_t *A, const int length); -int ecc_isOne(const uint32_t* A); -void ecc_rshift(uint32_t* A); -int ecc_isGreater(const uint32_t *A, const uint32_t *B, uint8_t length); - -#endif /* TEST_INCLUDE */ diff --git a/net/ip/tinydtls/ecc/test_helper.c b/net/ip/tinydtls/ecc/test_helper.c deleted file mode 100644 index bda44ba9e3d73abe9e63fd6c206d156500c6e88d..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/ecc/test_helper.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2009 Chris K Cockrum - * - * Copyright (c) 2013 Jens Trillmann - * Copyright (c) 2013 Marc Müller-Weinhardt - * Copyright (c) 2013 Lars Schmertmann - * Copyright (c) 2013 Hauke Mehrtens - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * - * This implementation is based in part on the paper Implementation of an - * Elliptic Curve Cryptosystem on an 8-bit Microcontroller [0] by - * Chris K Cockrum . - * - * [0]: http://cockrum.net/Implementation_of_ECC_on_an_8-bit_microcontroller.pdf - * - * This is a efficient ECC implementation on the secp256r1 curve for 32 Bit CPU - * architectures. It provides basic operations on the secp256r1 curve and support - * for ECDH and ECDSA. - */ -#include "test_helper.h" -#include "ecc.h" -#include -#include -#include - -void ecc_printNumber(const uint32_t *x, int numberLength){ //here the values are turned to MSB! - int n; - - for(n = numberLength - 1; n >= 0; n--){ - printf("%08x", x[n]); - } - printf("\n"); -} - -void ecc_setRandom(uint32_t *secret){ - int i; - - for (i = 0; i < arrayLength; ++i) - { - secret[i] = rand(); - } -} -const uint32_t ecc_prime_m[8] = {0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, - 0x00000000, 0x00000000, 0x00000001, 0xffffffff}; - - -/* This is added after an static byte addition if the answer has a carry in MSB*/ -const uint32_t ecc_prime_r[8] = {0x00000001, 0x00000000, 0x00000000, 0xffffffff, - 0xffffffff, 0xffffffff, 0xfffffffe, 0x00000000}; - -#ifdef CONTIKI -void -test_assert(const char *file, int lineno) -{ - printf("Assertion failed: file %s, line %d.\n", file, lineno); - /* - * loop for a while; - * call _reset_vector__(); - */ -} -#endif diff --git a/net/ip/tinydtls/ecc/test_helper.h b/net/ip/tinydtls/ecc/test_helper.h deleted file mode 100644 index 38a194e458f31314ddf46c26800cd8220ccb9e51..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/ecc/test_helper.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2009 Chris K Cockrum - * - * Copyright (c) 2013 Jens Trillmann - * Copyright (c) 2013 Marc Müller-Weinhardt - * Copyright (c) 2013 Lars Schmertmann - * Copyright (c) 2013 Hauke Mehrtens - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * - * This implementation is based in part on the paper Implementation of an - * Elliptic Curve Cryptosystem on an 8-bit Microcontroller [0] by - * Chris K Cockrum . - * - * [0]: http://cockrum.net/Implementation_of_ECC_on_an_8-bit_microcontroller.pdf - * - * This is a efficient ECC implementation on the secp256r1 curve for 32 Bit CPU - * architectures. It provides basic operations on the secp256r1 curve and support - * for ECDH and ECDSA. - */ -#include - -extern const uint32_t ecc_prime_m[8]; -extern const uint32_t ecc_prime_r[8]; - -//debug function to print long numbers -void ecc_printNumber(const uint32_t *x, int numberLength); -void ecc_setRandom(uint32_t *secret); - -#ifdef CONTIKI -#undef assert -#define assert(e) ((e) ? (void)0 : test_assert(__FILE__, __LINE__)) -void test_assert(const char *, int); -#endif diff --git a/net/ip/tinydtls/ecc/testecc.c b/net/ip/tinydtls/ecc/testecc.c deleted file mode 100644 index b36d46b7e89f81bb352cebc47b0491a11482761e..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/ecc/testecc.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2009 Chris K Cockrum - * - * Copyright (c) 2013 Jens Trillmann - * Copyright (c) 2013 Marc Müller-Weinhardt - * Copyright (c) 2013 Lars Schmertmann - * Copyright (c) 2013 Hauke Mehrtens - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * - * This implementation is based in part on the paper Implementation of an - * Elliptic Curve Cryptosystem on an 8-bit Microcontroller [0] by - * Chris K Cockrum . - * - * [0]: http://cockrum.net/Implementation_of_ECC_on_an_8-bit_microcontroller.pdf - * - * This is a efficient ECC implementation on the secp256r1 curve for 32 Bit CPU - * architectures. It provides basic operations on the secp256r1 curve and support - * for ECDH and ECDSA. - */ - -#include -#include -#include -#include - -#include "ecc.h" -#include "test_helper.h" - -#ifdef CONTIKI -#include "contiki.h" -#else -#include -#endif /* CONTIKI */ - -//These are testvalues taken from the NIST P-256 definition -//6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296 -uint32_t BasePointx[8] = { 0xd898c296, 0xf4a13945, 0x2deb33a0, 0x77037d81, - 0x63a440f2, 0xf8bce6e5, 0xe12c4247, 0x6b17d1f2}; - -//4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5 -uint32_t BasePointy[8] = { 0x37bf51f5, 0xcbb64068, 0x6b315ece, 0x2bce3357, - 0x7c0f9e16, 0x8ee7eb4a, 0xfe1a7f9b, 0x4fe342e2}; - -//de2444be bc8d36e6 82edd27e 0f271508 617519b3 221a8fa0 b77cab39 89da97c9 -uint32_t Sx[8] = { 0x89da97c9, 0xb77cab39, 0x221a8fa0, 0x617519b3, - 0x0f271508, 0x82edd27e, 0xbc8d36e6, 0xde2444be}; - -//c093ae7f f36e5380 fc01a5aa d1e66659 702de80f 53cec576 b6350b24 3042a256 -uint32_t Sy[8] = { 0x3042a256, 0xb6350b24, 0x53cec576, 0x702de80f, - 0xd1e66659, 0xfc01a5aa, 0xf36e5380, 0xc093ae7f}; - -//55a8b00f 8da1d44e 62f6b3b2 5316212e 39540dc8 61c89575 bb8cf92e 35e0986b -uint32_t Tx[8] = { 0x35e0986b, 0xbb8cf92e, 0x61c89575, 0x39540dc8, - 0x5316212e, 0x62f6b3b2, 0x8da1d44e, 0x55a8b00f}; - -//5421c320 9c2d6c70 4835d82a c4c3dd90 f61a8a52 598b9e7a b656e9d8 c8b24316 -uint32_t Ty[8] = { 0xc8b24316, 0xb656e9d8, 0x598b9e7a, 0xf61a8a52, - 0xc4c3dd90, 0x4835d82a, 0x9c2d6c70, 0x5421c320}; - -//c51e4753 afdec1e6 b6c6a5b9 92f43f8d d0c7a893 3072708b 6522468b 2ffb06fd -uint32_t secret[8] = { 0x2ffb06fd, 0x6522468b, 0x3072708b, 0xd0c7a893, - 0x92f43f8d, 0xb6c6a5b9, 0xafdec1e6, 0xc51e4753}; - -//72b13dd4 354b6b81 745195e9 8cc5ba69 70349191 ac476bd4 553cf35a 545a067e -uint32_t resultAddx[8] = { 0x545a067e, 0x553cf35a, 0xac476bd4, 0x70349191, - 0x8cc5ba69, 0x745195e9, 0x354b6b81, 0x72b13dd4}; - -//8d585cbb 2e1327d7 5241a8a1 22d7620d c33b1331 5aa5c9d4 6d013011 744ac264 -uint32_t resultAddy[8] = { 0x744ac264, 0x6d013011, 0x5aa5c9d4, 0xc33b1331, - 0x22d7620d, 0x5241a8a1, 0x2e1327d7, 0x8d585cbb}; - -//7669e690 1606ee3b a1a8eef1 e0024c33 df6c22f3 b17481b8 2a860ffc db6127b0 -uint32_t resultDoublex[8] = { 0xdb6127b0, 0x2a860ffc, 0xb17481b8, 0xdf6c22f3, - 0xe0024c33, 0xa1a8eef1, 0x1606ee3b, 0x7669e690}; - -//fa878162 187a54f6 c39f6ee0 072f33de 389ef3ee cd03023d e10ca2c1 db61d0c7 -uint32_t resultDoubley[8] = { 0xdb61d0c7, 0xe10ca2c1, 0xcd03023d, 0x389ef3ee, - 0x072f33de, 0xc39f6ee0, 0x187a54f6, 0xfa878162}; - -//51d08d5f 2d427888 2946d88d 83c97d11 e62becc3 cfc18bed acc89ba3 4eeca03f -uint32_t resultMultx[8] = { 0x4eeca03f, 0xacc89ba3, 0xcfc18bed, 0xe62becc3, - 0x83c97d11, 0x2946d88d, 0x2d427888, 0x51d08d5f}; - -//75ee68eb 8bf626aa 5b673ab5 1f6e744e 06f8fcf8 a6c0cf30 35beca95 6a7b41d5 -uint32_t resultMulty[8] = { 0x6a7b41d5, 0x35beca95, 0xa6c0cf30, 0x06f8fcf8, - 0x1f6e744e, 0x5b673ab5, 0x8bf626aa, 0x75ee68eb}; - -static const uint32_t ecdsaTestMessage[] = { 0x65637572, 0x20612073, 0x68206F66, 0x20686173, 0x69732061, 0x68697320, 0x6F2C2054, 0x48616C6C}; - -static const uint32_t ecdsaTestSecret[] = {0x94A949FA, 0x401455A1, 0xAD7294CA, 0x896A33BB, 0x7A80E714, 0x4321435B, 0x51247A14, 0x41C1CB6B}; - -static const uint32_t ecdsaTestRand1[] = { 0x1D1E1F20, 0x191A1B1C, 0x15161718, 0x11121314, 0x0D0E0F10, 0x090A0B0C, 0x05060708, 0x01020304}; -static const uint32_t ecdsaTestresultR1[] = { 0xC3B4035F, 0x515AD0A6, 0xBF375DCA, 0x0CC1E997, 0x7F54FDCD, 0x04D3FECA, 0xB9E396B9, 0x515C3D6E}; -static const uint32_t ecdsaTestresultS1[] = { 0x5366B1AB, 0x0F1DBF46, 0xB0C8D3C4, 0xDB755B6F, 0xB9BF9243, 0xE644A8BE, 0x55159A59, 0x6F9E52A6}; - -static const uint32_t ecdsaTestRand2[] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x01FFFFFF}; -static const uint32_t ecdsaTestresultR2[] = { 0x14146C91, 0xE878724D, 0xCD4FF928, 0xCC24BC04, 0xAC403390, 0x650C0060, 0x4A30B3F1, 0x9C69B726}; -static const uint32_t ecdsaTestresultS2[] = { 0x433AAB6F, 0x808250B1, 0xE46F90F4, 0xB342E972, 0x18B2F7E4, 0x2DB981A2, 0x6A288FA4, 0x41CF59DB}; - -void addTest(){ - uint32_t tempx[8]; - uint32_t tempy[8]; - - ecc_ec_add(Tx, Ty, Sx, Sy, tempx, tempy); - assert(ecc_isSame(tempx, resultAddx, arrayLength)); - assert(ecc_isSame(tempy, resultAddy, arrayLength)); -} - -void doubleTest(){ - uint32_t tempx[8]; - uint32_t tempy[8]; - - ecc_ec_double(Sx, Sy, tempx, tempy); - assert(ecc_isSame(tempx, resultDoublex, arrayLength)); - assert(ecc_isSame(tempy, resultDoubley, arrayLength)); -} - -void multTest(){ - uint32_t tempx[8]; - uint32_t tempy[8]; - - ecc_ec_mult(Sx, Sy, secret, tempx, tempy); - assert(ecc_isSame(tempx, resultMultx, arrayLength)); - assert(ecc_isSame(tempy, resultMulty, arrayLength)); -} - -void eccdhTest(){ - uint32_t tempx[8]; - uint32_t tempy[8]; - uint32_t tempAx2[8]; - uint32_t tempAy2[8]; - uint32_t tempBx1[8]; - uint32_t tempBy1[8]; - uint32_t tempBx2[8]; - uint32_t tempBy2[8]; - uint32_t secretA[8]; - uint32_t secretB[8]; - ecc_setRandom(secretA); - ecc_printNumber(secretA, 8); - ecc_setRandom(secretB); - ecc_printNumber(secretB, 8); - ecc_ec_mult(BasePointx, BasePointy, secretA, tempx, tempy); - ecc_ec_mult(BasePointx, BasePointy, secretB, tempBx1, tempBy1); - //public key exchange - ecc_ec_mult(tempBx1, tempBy1, secretA, tempAx2, tempAy2); - ecc_ec_mult(tempx, tempy, secretB, tempBx2, tempBy2); - assert(ecc_isSame(tempAx2, tempBx2, arrayLength)); - assert(ecc_isSame(tempAy2, tempBy2, arrayLength)); - -} - -void ecdsaTest() { - int ret __attribute__((unused)); - uint32_t tempx[9]; - uint32_t tempy[9]; - uint32_t pub_x[8]; - uint32_t pub_y[8]; - - ecc_ec_mult(BasePointx, BasePointy, ecdsaTestSecret, pub_x, pub_y); - - ret = ecc_ecdsa_sign(ecdsaTestSecret, ecdsaTestMessage, ecdsaTestRand1, tempx, tempy); - assert(ecc_isSame(tempx, ecdsaTestresultR1, arrayLength)); - assert(ecc_isSame(tempy, ecdsaTestresultS1, arrayLength)); - assert(ret == 0); - - ret = ecc_ecdsa_validate(pub_x, pub_y, ecdsaTestMessage, tempx, tempy); - assert(!ret); - - - ret = ecc_ecdsa_sign(ecdsaTestSecret, ecdsaTestMessage, ecdsaTestRand2, tempx, tempy); - assert(ecc_isSame(tempx, ecdsaTestresultR2, arrayLength)); - assert(ecc_isSame(tempy, ecdsaTestresultS2, arrayLength)); - assert(ret == 0); - - ret = ecc_ecdsa_validate(pub_x, pub_y, ecdsaTestMessage, tempx, tempy); - assert(!ret); -} - -#ifdef CONTIKI -PROCESS(ecc_filed_test, "ECC test"); -AUTOSTART_PROCESSES(&ecc_filed_test); -PROCESS_THREAD(ecc_filed_test, ev, d) -{ - PROCESS_BEGIN(); - - srand(1234); - addTest(); - doubleTest(); - multTest(); - eccdhTest(); - ecdsaTest(); - printf("%s\n", "All Tests successful."); - - PROCESS_END(); -} -#else /* CONTIKI */ -int main(int argc, char const *argv[]) -{ - srand(time(NULL)); - addTest(); - doubleTest(); - multTest(); - eccdhTest(); - ecdsaTest(); - printf("%s\n", "All Tests successful."); - return 0; -} -#endif /* CONTIKI */ diff --git a/net/ip/tinydtls/ecc/testfield.c b/net/ip/tinydtls/ecc/testfield.c deleted file mode 100644 index 30a690e574344a11ba81779569063333f54323ee..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/ecc/testfield.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (c) 2009 Chris K Cockrum - * - * Copyright (c) 2013 Jens Trillmann - * Copyright (c) 2013 Marc Müller-Weinhardt - * Copyright (c) 2013 Lars Schmertmann - * Copyright (c) 2013 Hauke Mehrtens - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * - * This implementation is based in part on the paper Implementation of an - * Elliptic Curve Cryptosystem on an 8-bit Microcontroller [0] by - * Chris K Cockrum . - * - * [0]: http://cockrum.net/Implementation_of_ECC_on_an_8-bit_microcontroller.pdf - * - * This is a efficient ECC implementation on the secp256r1 curve for 32 Bit CPU - * architectures. It provides basic operations on the secp256r1 curve and support - * for ECDH and ECDSA. - */ -#include -#include -#include -#include "ecc.h" -#include "test_helper.h" - -#ifdef CONTIKI -#include "contiki.h" -#endif /* CONTIKI */ - -//arbitrary test values and results -uint32_t null[8] = { 0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}; -uint32_t null64[16] = { 0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}; -uint32_t one[8] = { 0x00000001,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}; -uint32_t one64[16] = { 0x00000001,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}; -uint32_t two[8] = { 0x00000002,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}; -uint32_t two64[16] = { 0x00000002,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}; -uint32_t three[8] = { 0x00000003,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}; -uint32_t four[8] = {0x00000004,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}; -uint32_t four64[16] = { 0x00000004,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}; -uint32_t six[8] = { 0x00000006,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}; -uint32_t eight[8] = { 0x00000008,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}; -uint32_t full[8] = { 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, - 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; -//00000000fffffffeffffffffffffffffffffffff000000000000000000000001_16 -uint32_t resultFullAdd[8] = { 0x00000001,0x00000000,0x00000000,0xFFFFFFFF, - 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0x00000000}; -uint32_t primeMinusOne[8]= { 0xfffffffe,0xffffffff,0xffffffff,0x00000000, - 0x00000000,0x00000000,0x00000001,0xffffffff}; -uint32_t resultDoubleMod[8] = { 0xfffffffd,0xffffffff,0xffffffff,0x00000000, - 0x00000000,0x00000000,0x00000001,0xffffffff}; -//fffffffe00000002fffffffe0000000100000001fffffffe00000001fffffffc00000003fffffffcfffffffffffffffffffffffc000000000000000000000004_16 -uint32_t resultQuadMod[16] = { 0x00000004,0x00000000,0x00000000,0xFFFFFFFC, - 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFC,0x00000003, - 0xFFFFFFFC,0x00000001,0xFFFFFFFE,0x00000001, - 0x00000001,0xFFFFFFFE,0x00000002,0xFFFFFFFE}; -//00000002fffffffffffffffffffffffefffffffdffffffff0000000000000002_16 -uint32_t resultFullMod[8] = { 0x00000002,0x00000000,0xFFFFFFFF,0xFFFFFFFD, - 0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0x00000002}; - -static const uint32_t orderMinusOne[8] = {0xFC632550, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, - 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF}; -static const uint32_t orderResultDoubleMod[8] = {0xFC63254F, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF}; - -uint32_t temp[8]; -uint32_t temp2[16]; - -void nullEverything(){ - memset(temp, 0, sizeof(temp)); - memset(temp2, 0, sizeof(temp)); -} - -void fieldAddTest(){ - assert(ecc_isSame(one, one, arrayLength)); - ecc_fieldAdd(one, null, ecc_prime_r, temp); - assert(ecc_isSame(temp, one, arrayLength)); - nullEverything(); - ecc_fieldAdd(one, one, ecc_prime_r, temp); - assert(ecc_isSame(temp, two, arrayLength)); - nullEverything(); - ecc_add(full, one, temp, 32); - assert(ecc_isSame(null, temp, arrayLength)); - nullEverything(); - ecc_fieldAdd(full, one, ecc_prime_r, temp); - assert(ecc_isSame(temp, resultFullAdd, arrayLength)); -} - -void fieldSubTest(){ - assert(ecc_isSame(one, one, arrayLength)); - ecc_fieldSub(one, null, ecc_prime_m, temp); - assert(ecc_isSame(one, temp, arrayLength)); - nullEverything(); - ecc_fieldSub(one, one, ecc_prime_m, temp); - assert(ecc_isSame(null, temp, arrayLength)); - nullEverything(); - ecc_fieldSub(null, one, ecc_prime_m, temp); - assert(ecc_isSame(primeMinusOne, temp, arrayLength)); -} - -void fieldMultTest(){ - ecc_fieldMult(one, null, temp2, arrayLength); - assert(ecc_isSame(temp2, null64, arrayLength * 2)); - nullEverything(); - ecc_fieldMult(one, two, temp2, arrayLength); - assert(ecc_isSame(temp2, two64, arrayLength * 2)); - nullEverything(); - ecc_fieldMult(two, two, temp2, arrayLength); - assert(ecc_isSame(temp2, four64, arrayLength * 2)); - nullEverything(); - ecc_fieldMult(primeMinusOne, primeMinusOne, temp2, arrayLength); - assert(ecc_isSame(temp2, resultQuadMod, arrayLength * 2)); - nullEverything(); - ecc_fieldInv(two, ecc_prime_m, ecc_prime_r, temp); - ecc_fieldMult(temp, two, temp2, arrayLength); - ecc_fieldModP(temp, temp2); - assert(ecc_isSame(temp, one, arrayLength)); -} - -void fieldModPTest(){ - ecc_fieldMult(primeMinusOne, primeMinusOne, temp2, arrayLength); - ecc_fieldModP(temp, temp2); - assert(ecc_isSame(temp, one, arrayLength)); - nullEverything(); - ecc_fieldModP(temp, one64); - assert(ecc_isSame(temp, one, arrayLength)); - nullEverything(); - ecc_fieldMult(two, primeMinusOne, temp2, arrayLength); - ecc_fieldModP(temp, temp2); - assert(ecc_isSame(temp, resultDoubleMod, arrayLength)); - nullEverything(); - /*fieldMult(full, full, temp2, arrayLength); //not working, maybe because of the number bigger than p^2? - fieldModP(temp, temp2); - assert(ecc_isSame(temp, resultFullMod, arrayLength));*/ -} - -void fieldModOTest(){ - ecc_fieldMult(orderMinusOne, orderMinusOne, temp2, arrayLength); - ecc_fieldModO(temp2, temp, arrayLength * 2); - assert(ecc_isSame(temp, one, arrayLength)); - nullEverything(); - ecc_fieldModO(one64, temp, arrayLength * 2); - assert(ecc_isSame(temp, one, arrayLength)); - nullEverything(); - ecc_fieldMult(two, orderMinusOne, temp2, arrayLength); - ecc_fieldModO(temp2, temp, arrayLength * 2); - assert(ecc_isSame(temp, orderResultDoubleMod, arrayLength)); - nullEverything(); -} - - -// void rShiftTest(){ -// printNumber(full, 32); -// rshift(full); -// printNumber(full, 32); -// printNumber(two, 32); -// rshift(two); -// printNumber(two, 32); -// printNumber(four, 32); -// rshift(four); -// printNumber(four, 32); -// } - -// void isOneTest(){ -// printf("%d\n", isone(one)); -// printf("%d\n", isone(two)); -// printf("%d\n", isone(four)); -// printf("%d\n", isone(full)); -// printf("%d\n", isone(null)); -// } - -void fieldInvTest(){ - nullEverything(); - ecc_fieldInv(two, ecc_prime_m, ecc_prime_r, temp); - ecc_fieldMult(temp, two, temp2, arrayLength); - ecc_fieldModP(temp, temp2); - assert(ecc_isSame(one, temp, arrayLength)); - nullEverything(); - ecc_fieldInv(eight, ecc_prime_m, ecc_prime_r, temp); - ecc_fieldMult(temp, eight, temp2, arrayLength); - ecc_fieldModP(temp, temp2); - assert(ecc_isSame(one, temp, arrayLength)); - nullEverything(); - ecc_fieldInv(three, ecc_prime_m, ecc_prime_r, temp); - ecc_fieldMult(temp, three, temp2, arrayLength); - ecc_fieldModP(temp, temp2); - assert(ecc_isSame(one, temp, arrayLength)); - nullEverything(); - ecc_fieldInv(six, ecc_prime_m, ecc_prime_r, temp); - ecc_fieldMult(temp, six, temp2, arrayLength); - ecc_fieldModP(temp, temp2); - assert(ecc_isSame(one, temp, arrayLength)); - nullEverything(); - ecc_fieldInv(primeMinusOne, ecc_prime_m, ecc_prime_r, temp); - ecc_fieldMult(temp, primeMinusOne, temp2, arrayLength); - ecc_fieldModP(temp, temp2); - assert(ecc_isSame(one, temp, arrayLength)); -} - -// void randomStuff(){ - -// } - -#ifdef CONTIKI -PROCESS(ecc_filed_test, "ECC field test"); -AUTOSTART_PROCESSES(&ecc_filed_test); -PROCESS_THREAD(ecc_filed_test, ev, d) -{ - PROCESS_BEGIN(); - - nullEverything(); - //randomStuff(); - nullEverything(); - fieldAddTest(); - nullEverything(); - fieldSubTest(); - nullEverything(); - fieldMultTest(); - nullEverything(); - fieldModPTest(); - nullEverything(); - fieldModOTest(); - nullEverything(); - fieldInvTest(); - nullEverything(); - //rShiftTest(); - //isOneTest(); - printf("%s\n", "All Tests succesfull!"); - - PROCESS_END(); -} -#else /* CONTIKI */ -int main(int argc, char const *argv[]) -{ - nullEverything(); - //randomStuff(); - nullEverything(); - fieldAddTest(); - nullEverything(); - fieldSubTest(); - nullEverything(); - fieldMultTest(); - nullEverything(); - fieldModPTest(); - nullEverything(); - fieldModOTest(); - nullEverything(); - fieldInvTest(); - nullEverything(); - //rShiftTest(); - //isOneTest(); - printf("%s\n", "All Tests succesfull!"); - return 0; -} -#endif /* CONTIKI */ diff --git a/net/ip/tinydtls/examples/contiki/Makefile.in b/net/ip/tinydtls/examples/contiki/Makefile.in deleted file mode 100644 index 84d85b8dd86ba971b5f0043145c2ebf4c1198482..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/examples/contiki/Makefile.in +++ /dev/null @@ -1,59 +0,0 @@ -######################################################################## -# platform-specific options - -ifeq ($(TARGET), econotag) -CFLAGS += -DUIP_CONF_TCP=0 -endif - -ifeq ($(TARGET), minimal-net) -CONTIKI_WITH_RPL=0 -endif - -# usually, you should not need changing anything beyond this line -######################################################################## - -# the library's version -VERSION:=@PACKAGE_VERSION@ - -# tools -@SET_MAKE@ -SHELL = /bin/sh -MKDIR = mkdir - -abs_builddir = @abs_builddir@ -top_builddir = @top_builddir@ -top_srcdir:= @top_srcdir@ -DISTDIR=$(top_builddir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@ -DTLS_SOURCES:=dtls-server.c dtls-client.c -FILES:=Makefile.in $(DTLS_SOURCES) - -all: dtls-server dtls-client - $(MAKE) $(MAKEFLAGS) ROLE=server dtls-server - $(MAKE) $(MAKEFLAGS) clean - $(MAKE) $(MAKEFLAGS) ROLE=client dtls-client - -CONTIKI=$(top_srcdir)/../.. - -CONTIKI_WITH_IPV6 = 1 - -ifneq ($(ROLE),client) - CFLAGS+= -DHARD_CODED_ADDRESS=\"aaaa::02:232\" -else - CFLAGS+= -DUDP_CONNECTION_ADDR="fe80::ff:fe02:232" \ - -DHARD_CODED_ADDRESS=\"aaaa::02:230\" -endif - -CFLAGS += -ffunction-sections -LDFLAGS += -Wl,--gc-sections,--undefined=_reset_vector__,--undefined=InterruptVectors,--undefined=_copy_data_init__,--undefined=_clear_bss_init__,--undefined=_end_of_init__ - -APPS += tinydtls/aes tinydtls/sha2 tinydtls/ecc tinydtls - -ccm-test: tests/ccm-test - -dist: $(FILES) - test -d $(DISTDIR)/examples/contiki || $(MKDIR) -p $(DISTDIR)/examples/contiki - cp $(FILES) $(DISTDIR)/examples/contiki - -ifeq ("@WITH_CONTIKI@", "1") -include $(CONTIKI)/Makefile.include -endif diff --git a/net/ip/tinydtls/examples/contiki/dtls-client.c b/net/ip/tinydtls/examples/contiki/dtls-client.c deleted file mode 100644 index 5b3d7c75ac2f5e1e4e76fd6208abe4e341c00150..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/examples/contiki/dtls-client.c +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" - -#include "dev/serial-line.h" - -#include - -#include "tinydtls.h" - -#ifndef DEBUG -#define DEBUG DEBUG_PRINT -#endif -#include "contiki/ip/uip-debug.h" - -#include "debug.h" -#include "dtls.h" - -#ifdef DTLS_PSK -/* The PSK information for DTLS */ -/* make sure that default identity and key fit into buffer, i.e. - * sizeof(PSK_DEFAULT_IDENTITY) - 1 <= PSK_ID_MAXLEN and - * sizeof(PSK_DEFAULT_KEY) - 1 <= PSK_MAXLEN -*/ - -#define PSK_ID_MAXLEN 32 -#define PSK_MAXLEN 32 -#define PSK_DEFAULT_IDENTITY "Client_identity" -#define PSK_DEFAULT_KEY "secretPSK" -#endif /* DTLS_PSK */ - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN]) - -#define MAX_PAYLOAD_LEN 120 - -static struct uip_udp_conn *client_conn; -static dtls_context_t *dtls_context; -static char buf[200]; -static size_t buflen = 0; - -static const unsigned char ecdsa_priv_key[] = { - 0x41, 0xC1, 0xCB, 0x6B, 0x51, 0x24, 0x7A, 0x14, - 0x43, 0x21, 0x43, 0x5B, 0x7A, 0x80, 0xE7, 0x14, - 0x89, 0x6A, 0x33, 0xBB, 0xAD, 0x72, 0x94, 0xCA, - 0x40, 0x14, 0x55, 0xA1, 0x94, 0xA9, 0x49, 0xFA}; - -static const unsigned char ecdsa_pub_key_x[] = { - 0x36, 0xDF, 0xE2, 0xC6, 0xF9, 0xF2, 0xED, 0x29, - 0xDA, 0x0A, 0x9A, 0x8F, 0x62, 0x68, 0x4E, 0x91, - 0x63, 0x75, 0xBA, 0x10, 0x30, 0x0C, 0x28, 0xC5, - 0xE4, 0x7C, 0xFB, 0xF2, 0x5F, 0xA5, 0x8F, 0x52}; - -static const unsigned char ecdsa_pub_key_y[] = { - 0x71, 0xA0, 0xD4, 0xFC, 0xDE, 0x1A, 0xB8, 0x78, - 0x5A, 0x3C, 0x78, 0x69, 0x35, 0xA7, 0xCF, 0xAB, - 0xE9, 0x3F, 0x98, 0x72, 0x09, 0xDA, 0xED, 0x0B, - 0x4F, 0xAB, 0xC3, 0x6F, 0xC7, 0x72, 0xF8, 0x29}; - -static void -try_send(struct dtls_context_t *ctx, session_t *dst) { - int res; - res = dtls_write(ctx, dst, (uint8 *)buf, buflen); - if (res >= 0) { - memmove(buf, buf + res, buflen - res); - buflen -= res; - } -} - -static int -read_from_peer(struct dtls_context_t *ctx, - session_t *session, uint8 *data, size_t len) { - size_t i; - for (i = 0; i < len; i++) - PRINTF("%c", data[i]); - return 0; -} - -static int -send_to_peer(struct dtls_context_t *ctx, - session_t *session, uint8 *data, size_t len) { - - struct uip_udp_conn *conn = (struct uip_udp_conn *)dtls_get_app_data(ctx); - - uip_ipaddr_copy(&conn->ripaddr, &session->addr); - conn->rport = session->port; - - PRINTF("send to "); - PRINT6ADDR(&conn->ripaddr); - PRINTF(":%u\n", uip_ntohs(conn->rport)); - - uip_udp_packet_send(conn, data, len); - - /* Restore server connection to allow data from any node */ - /* FIXME: do we want this at all? */ - memset(&conn->ripaddr, 0, sizeof(conn->ripaddr)); - memset(&conn->rport, 0, sizeof(conn->rport)); - - return len; -} - -#ifdef DTLS_PSK -static unsigned char psk_id[PSK_ID_MAXLEN] = PSK_DEFAULT_IDENTITY; -static size_t psk_id_length = sizeof(PSK_DEFAULT_IDENTITY) - 1; -static unsigned char psk_key[PSK_MAXLEN] = PSK_DEFAULT_KEY; -static size_t psk_key_length = sizeof(PSK_DEFAULT_KEY) - 1; - -#ifdef __GNUC__ -#define UNUSED_PARAM __attribute__((unused)) -#else -#define UNUSED_PARAM -#endif /* __GNUC__ */ - -/* This function is the "key store" for tinyDTLS. It is called to - * retrieve a key for the given identity within this particular - * session. */ -static int -get_psk_info(struct dtls_context_t *ctx UNUSED_PARAM, - const session_t *session UNUSED_PARAM, - dtls_credentials_type_t type, - const unsigned char *id, size_t id_len, - unsigned char *result, size_t result_length) { - - switch (type) { - case DTLS_PSK_IDENTITY: - if (result_length < psk_id_length) { - dtls_warn("cannot set psk_identity -- buffer too small\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - memcpy(result, psk_id, psk_id_length); - return psk_id_length; - case DTLS_PSK_KEY: - if (id_len != psk_id_length || memcmp(psk_id, id, id_len) != 0) { - dtls_warn("PSK for unknown id requested, exiting\n"); - return dtls_alert_fatal_create(DTLS_ALERT_ILLEGAL_PARAMETER); - } else if (result_length < psk_key_length) { - dtls_warn("cannot set psk -- buffer too small\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - memcpy(result, psk_key, psk_key_length); - return psk_key_length; - default: - dtls_warn("unsupported request type: %d\n", type); - } - - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); -} -#endif /* DTLS_PSK */ - -#ifdef DTLS_ECC -static int -get_ecdsa_key(struct dtls_context_t *ctx, - const session_t *session, - const dtls_ecdsa_key_t **result) { - static const dtls_ecdsa_key_t ecdsa_key = { - .curve = DTLS_ECDH_CURVE_SECP256R1, - .priv_key = ecdsa_priv_key, - .pub_key_x = ecdsa_pub_key_x, - .pub_key_y = ecdsa_pub_key_y - }; - - *result = &ecdsa_key; - return 0; -} - -static int -verify_ecdsa_key(struct dtls_context_t *ctx, - const session_t *session, - const unsigned char *other_pub_x, - const unsigned char *other_pub_y, - size_t key_size) { - return 0; -} -#endif /* DTLS_ECC */ - -PROCESS(udp_server_process, "UDP server process"); -AUTOSTART_PROCESSES(&udp_server_process); -/*---------------------------------------------------------------------------*/ -static void -dtls_handle_read(dtls_context_t *ctx) { - static session_t session; - - if(uip_newdata()) { - uip_ipaddr_copy(&session.addr, &UIP_IP_BUF->srcipaddr); - session.port = UIP_UDP_BUF->srcport; - session.size = sizeof(session.addr) + sizeof(session.port); - - ((char *)uip_appdata)[uip_datalen()] = 0; - PRINTF("Client received message from "); - PRINT6ADDR(&session.addr); - PRINTF(":%d\n", uip_ntohs(session.port)); - - dtls_handle_message(ctx, &session, uip_appdata, uip_datalen()); - } -} -/*---------------------------------------------------------------------------*/ -static void -print_local_addresses(void) -{ - int i; - uint8_t state; - - PRINTF("Client IPv6 addresses: "); - for(i = 0; i < UIP_DS6_ADDR_NB; i++) { - state = uip_ds6_if.addr_list[i].state; - if(uip_ds6_if.addr_list[i].isused && - (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { - PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); - PRINTF("\n"); - } - } -} - -static void -set_connection_address(uip_ipaddr_t *ipaddr) -{ -#define _QUOTEME(x) #x -#define QUOTEME(x) _QUOTEME(x) -#ifdef UDP_CONNECTION_ADDR - if(uiplib_ipaddrconv(QUOTEME(UDP_CONNECTION_ADDR), ipaddr) == 0) { - PRINTF("UDP client failed to parse address '%s'\n", QUOTEME(UDP_CONNECTION_ADDR)); - } -#elif UIP_CONF_ROUTER - uip_ip6addr(ipaddr,0xaaaa,0,0,0,0x0200,0x0000,0x0000,0x0001); -#else - uip_ip6addr(ipaddr,0xfe80,0,0,0,0x6466,0x6666,0x6666,0x6666); -#endif /* UDP_CONNECTION_ADDR */ -} - -void -init_dtls(session_t *dst) { - static dtls_handler_t cb = { - .write = send_to_peer, - .read = read_from_peer, - .event = NULL, -#ifdef DTLS_PSK - .get_psk_info = get_psk_info, -#endif /* DTLS_PSK */ -#ifdef DTLS_ECC - .get_ecdsa_key = get_ecdsa_key, - .verify_ecdsa_key = verify_ecdsa_key -#endif /* DTLS_ECC */ - }; - PRINTF("DTLS client started\n"); - - print_local_addresses(); - - dst->size = sizeof(dst->addr) + sizeof(dst->port); - dst->port = UIP_HTONS(20220); - - set_connection_address(&dst->addr); - client_conn = udp_new(&dst->addr, 0, NULL); - udp_bind(client_conn, dst->port); - - PRINTF("set connection address to "); - PRINT6ADDR(&dst->addr); - PRINTF(":%d\n", uip_ntohs(dst->port)); - - dtls_set_log_level(DTLS_LOG_DEBUG); - - dtls_context = dtls_new_context(client_conn); - if (dtls_context) - dtls_set_handler(dtls_context, &cb); -} - -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(udp_server_process, ev, data) -{ - static int connected = 0; - static session_t dst; - - PROCESS_BEGIN(); - - dtls_init(); - - init_dtls(&dst); - serial_line_init(); - - if (!dtls_context) { - dtls_emerg("cannot create context\n"); - PROCESS_EXIT(); - } - - while(1) { - PROCESS_YIELD(); - if(ev == tcpip_event) { - dtls_handle_read(dtls_context); - } else if (ev == serial_line_event_message) { - register size_t len = min(strlen(data), sizeof(buf) - buflen); - memcpy(buf + buflen, data, len); - buflen += len; - if (buflen < sizeof(buf) - 1) - buf[buflen++] = '\n'; /* serial event does not contain LF */ - } - - if (buflen) { - if (!connected) - connected = dtls_connect(dtls_context, &dst) >= 0; - - try_send(dtls_context, &dst); - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/tinydtls/examples/contiki/dtls-server.c b/net/ip/tinydtls/examples/contiki/dtls-server.c deleted file mode 100644 index d1e481202642c48d98796144648feb41cc27268b..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/examples/contiki/dtls-server.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" - -#if UIP_CONF_IPV6_RPL -#include "contiki/rpl/rpl.h" -#endif /* UIP_CONF_IPV6_RPL */ - -#include - -#include "tinydtls.h" - -#ifndef DEBUG -#define DEBUG DEBUG_PRINT -#endif -#include "contiki/ip/uip-debug.h" - -#include "debug.h" -#include "dtls.h" - -#ifdef ENABLE_POWERTRACE -#include "powertrace.h" -#endif - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN]) - -#define MAX_PAYLOAD_LEN 120 - -static struct uip_udp_conn *server_conn; - -static dtls_context_t *dtls_context; - -static const unsigned char ecdsa_priv_key[] = { - 0xD9, 0xE2, 0x70, 0x7A, 0x72, 0xDA, 0x6A, 0x05, - 0x04, 0x99, 0x5C, 0x86, 0xED, 0xDB, 0xE3, 0xEF, - 0xC7, 0xF1, 0xCD, 0x74, 0x83, 0x8F, 0x75, 0x70, - 0xC8, 0x07, 0x2D, 0x0A, 0x76, 0x26, 0x1B, 0xD4}; - -static const unsigned char ecdsa_pub_key_x[] = { - 0xD0, 0x55, 0xEE, 0x14, 0x08, 0x4D, 0x6E, 0x06, - 0x15, 0x59, 0x9D, 0xB5, 0x83, 0x91, 0x3E, 0x4A, - 0x3E, 0x45, 0x26, 0xA2, 0x70, 0x4D, 0x61, 0xF2, - 0x7A, 0x4C, 0xCF, 0xBA, 0x97, 0x58, 0xEF, 0x9A}; - -static const unsigned char ecdsa_pub_key_y[] = { - 0xB4, 0x18, 0xB6, 0x4A, 0xFE, 0x80, 0x30, 0xDA, - 0x1D, 0xDC, 0xF4, 0xF4, 0x2E, 0x2F, 0x26, 0x31, - 0xD0, 0x43, 0xB1, 0xFB, 0x03, 0xE2, 0x2F, 0x4D, - 0x17, 0xDE, 0x43, 0xF9, 0xF9, 0xAD, 0xEE, 0x70}; - -static int -read_from_peer(struct dtls_context_t *ctx, - session_t *session, uint8 *data, size_t len) { - size_t i; - for (i = 0; i < len; i++) - PRINTF("%c", data[i]); - - /* echo incoming application data */ - dtls_write(ctx, session, data, len); - return 0; -} - -static int -send_to_peer(struct dtls_context_t *ctx, - session_t *session, uint8 *data, size_t len) { - - struct uip_udp_conn *conn = (struct uip_udp_conn *)dtls_get_app_data(ctx); - - uip_ipaddr_copy(&conn->ripaddr, &session->addr); - conn->rport = session->port; - - PRINTF("send to "); - PRINT6ADDR(&conn->ripaddr); - PRINTF(":%u\n", uip_ntohs(conn->rport)); - - uip_udp_packet_send(conn, data, len); - - /* Restore server connection to allow data from any node */ - memset(&conn->ripaddr, 0, sizeof(conn->ripaddr)); - memset(&conn->rport, 0, sizeof(conn->rport)); - - return len; -} - -#ifdef DTLS_PSK -/* This function is the "key store" for tinyDTLS. It is called to - * retrieve a key for the given identity within this particular - * session. */ -static int -get_psk_info(struct dtls_context_t *ctx, const session_t *session, - dtls_credentials_type_t type, - const unsigned char *id, size_t id_len, - unsigned char *result, size_t result_length) { - - struct keymap_t { - unsigned char *id; - size_t id_length; - unsigned char *key; - size_t key_length; - } psk[3] = { - { (unsigned char *)"Client_identity", 15, - (unsigned char *)"secretPSK", 9 }, - { (unsigned char *)"default identity", 16, - (unsigned char *)"\x11\x22\x33", 3 }, - { (unsigned char *)"\0", 2, - (unsigned char *)"", 1 } - }; - - if (type != DTLS_PSK_KEY) { - return 0; - } - - if (id) { - int i; - for (i = 0; i < sizeof(psk)/sizeof(struct keymap_t); i++) { - if (id_len == psk[i].id_length && memcmp(id, psk[i].id, id_len) == 0) { - if (result_length < psk[i].key_length) { - dtls_warn("buffer too small for PSK"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - memcpy(result, psk[i].key, psk[i].key_length); - return psk[i].key_length; - } - } - } - - return dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR); -} -#endif /* DTLS_PSK */ - -#ifdef DTLS_ECC -static int -get_ecdsa_key(struct dtls_context_t *ctx, - const session_t *session, - const dtls_ecdsa_key_t **result) { - static const dtls_ecdsa_key_t ecdsa_key = { - .curve = DTLS_ECDH_CURVE_SECP256R1, - .priv_key = ecdsa_priv_key, - .pub_key_x = ecdsa_pub_key_x, - .pub_key_y = ecdsa_pub_key_y - }; - - *result = &ecdsa_key; - return 0; -} - -static int -verify_ecdsa_key(struct dtls_context_t *ctx, - const session_t *session, - const unsigned char *other_pub_x, - const unsigned char *other_pub_y, - size_t key_size) { - return 0; -} -#endif /* DTLS_ECC */ - -PROCESS(udp_server_process, "UDP server process"); -AUTOSTART_PROCESSES(&udp_server_process); -/*---------------------------------------------------------------------------*/ -static void -dtls_handle_read(dtls_context_t *ctx) { - session_t session; - - if(uip_newdata()) { - uip_ipaddr_copy(&session.addr, &UIP_IP_BUF->srcipaddr); - session.port = UIP_UDP_BUF->srcport; - session.size = sizeof(session.addr) + sizeof(session.port); - - dtls_handle_message(ctx, &session, uip_appdata, uip_datalen()); - } -} -/*---------------------------------------------------------------------------*/ -static void -print_local_addresses(void) -{ - int i; - uint8_t state; - - PRINTF("Server IPv6 addresses: \n"); - for(i = 0; i < UIP_DS6_ADDR_NB; i++) { - state = uip_ds6_if.addr_list[i].state; - if(uip_ds6_if.addr_list[i].isused && - (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { - PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); - PRINTF("\n"); - } - } -} - -#if 0 -static void -create_rpl_dag(uip_ipaddr_t *ipaddr) -{ - struct uip_ds6_addr *root_if; - - root_if = uip_ds6_addr_lookup(ipaddr); - if(root_if != NULL) { - rpl_dag_t *dag; - uip_ipaddr_t prefix; - - rpl_set_root(RPL_DEFAULT_INSTANCE, ipaddr); - dag = rpl_get_any_dag(); - uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); - rpl_set_prefix(dag, &prefix, 64); - PRINTF("created a new RPL dag\n"); - } else { - PRINTF("failed to create a new RPL DAG\n"); - } -} -#endif - -void -init_dtls() { - static dtls_handler_t cb = { - .write = send_to_peer, - .read = read_from_peer, - .event = NULL, -#ifdef DTLS_PSK - .get_psk_info = get_psk_info, -#endif /* DTLS_PSK */ -#ifdef DTLS_ECC - .get_ecdsa_key = get_ecdsa_key, - .verify_ecdsa_key = verify_ecdsa_key -#endif /* DTLS_ECC */ - }; -#if 0 - uip_ipaddr_t ipaddr; - /* struct uip_ds6_addr *root_if; */ -#endif /* UIP_CONF_ROUTER */ - - PRINTF("DTLS server started\n"); - -#if 0 /* TEST */ - memset(&tmp_addr, 0, sizeof(rimeaddr_t)); - if(get_eui64_from_eeprom(tmp_addr.u8)); -#if NETSTACK_CONF_WITH_IPV6 - memcpy(&uip_lladdr.addr, &tmp_addr.u8, 8); -#endif -#endif /* TEST */ - -#if 0 -/* uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); */ -/* uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); */ -/* uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); */ - -/* create_rpl_dag(&ipaddr); */ -/* #else */ - /* uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); */ - - uip_ip6addr(&ipaddr, 0xaaaa, 0,0,0,0x0200,0,0,0x0003); - uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL); - - create_rpl_dag(&ipaddr); -#endif /* UIP_CONF_ROUTER */ - - server_conn = udp_new(NULL, 0, NULL); - udp_bind(server_conn, UIP_HTONS(20220)); - - dtls_set_log_level(DTLS_LOG_DEBUG); - - dtls_context = dtls_new_context(server_conn); - if (dtls_context) - dtls_set_handler(dtls_context, &cb); -} - -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(udp_server_process, ev, data) -{ - PROCESS_BEGIN(); - - dtls_init(); - init_dtls(); - - print_local_addresses(); - - if (!dtls_context) { - dtls_emerg("cannot create context\n"); - PROCESS_EXIT(); - } - -#ifdef ENABLE_POWERTRACE - powertrace_start(CLOCK_SECOND * 2); -#endif - - while(1) { - PROCESS_WAIT_EVENT(); - if(ev == tcpip_event) { - dtls_handle_read(dtls_context); - } -#if 0 - if (bytes_read > 0) { - /* dtls_handle_message(dtls_context, &the_session, readbuf, bytes_read); */ - read_from_peer(dtls_context, &the_session, readbuf, bytes_read); - } - dtls_handle_message(ctx, &session, uip_appdata, bytes_read); -#endif - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/net/ip/tinydtls/global.h b/net/ip/tinydtls/global.h deleted file mode 100644 index f0977c848e8738369accdf93199a48c6659d1089..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/global.h +++ /dev/null @@ -1,147 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2014 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _DTLS_GLOBAL_H_ -#define _DTLS_GLOBAL_H_ - -#include -#include - -#include "tinydtls.h" - -#ifndef DTLSv12 -/* The current version of tinyDTLS supports DTLSv1.2 only. */ -#define DTLSv12 1 -#endif - -#ifndef WITH_SHA256 -/* The current version of tinyDTLS supports DTLSv1.2 with SHA256 PRF - only. */ -#define WITH_SHA256 1 -#endif - -/* Define our own types as at least uint32_t does not work on my amd64. */ - -typedef unsigned char uint8; -typedef unsigned char uint16[2]; -typedef unsigned char uint24[3]; -typedef unsigned char uint32[4]; -typedef unsigned char uint48[6]; - -#ifndef DTLS_MAX_BUF -/** Maximum size of DTLS message. - When Peers are sending bigger messages this causes problems. Californium - with ECDSA needs at least 220 */ -#ifdef WITH_CONTIKI -#ifdef DTLS_ECC -#define DTLS_MAX_BUF 200 -#else /* DTLS_ECC */ -#define DTLS_MAX_BUF 100 -#endif /* DTLS_ECC */ -#else /* WITH_CONTIKI */ -#define DTLS_MAX_BUF 1400 -#endif /* WITH_CONTIKI */ -#endif - -#ifndef DTLS_DEFAULT_MAX_RETRANSMIT -/** Number of message retransmissions. */ -#define DTLS_DEFAULT_MAX_RETRANSMIT 7 -#endif - -/** Known cipher suites.*/ -typedef enum { - TLS_NULL_WITH_NULL_NULL = 0x0000, /**< NULL cipher */ - TLS_PSK_WITH_AES_128_CCM_8 = 0xC0A8, /**< see RFC 6655 */ - TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE /**< see RFC 7251 */ -} dtls_cipher_t; - -/** Known compression suites.*/ -typedef enum { - TLS_COMPRESSION_NULL = 0x0000 /* NULL compression */ -} dtls_compression_t; - -#define TLS_EXT_ELLIPTIC_CURVES 10 /* see RFC 4492 */ -#define TLS_EXT_EC_POINT_FORMATS 11 /* see RFC 4492 */ -#define TLS_EXT_SIG_HASH_ALGO 13 /* see RFC 5246 */ -#define TLS_EXT_CLIENT_CERTIFICATE_TYPE 19 /* see RFC 7250 */ -#define TLS_EXT_SERVER_CERTIFICATE_TYPE 20 /* see RFC 7250 */ -#define TLS_EXT_ENCRYPT_THEN_MAC 22 /* see RFC 7366 */ - -#define TLS_CERT_TYPE_RAW_PUBLIC_KEY 2 /* see RFC 7250 */ - -#define TLS_EXT_ELLIPTIC_CURVES_SECP256R1 23 /* see RFC 4492 */ - -#define TLS_EXT_EC_POINT_FORMATS_UNCOMPRESSED 0 /* see RFC 4492 */ - -#define TLS_EC_CURVE_TYPE_NAMED_CURVE 3 /* see RFC 4492 */ - -#define TLS_CLIENT_CERTIFICATE_TYPE_ECDSA_SIGN 64 /* see RFC 4492 */ - -#define TLS_EXT_SIG_HASH_ALGO_SHA256 4 /* see RFC 5246 */ -#define TLS_EXT_SIG_HASH_ALGO_ECDSA 3 /* see RFC 5246 */ - -/** - * XORs \p n bytes byte-by-byte starting at \p y to the memory area - * starting at \p x. */ -static inline void -memxor(unsigned char *x, const unsigned char *y, size_t n) { - while(n--) { - *x ^= *y; - x++; y++; - } -} - -/** - * Compares \p len bytes from @p a with @p b in constant time. This - * functions always traverses the entire length to prevent timing - * attacks. - * - * \param a Byte sequence to compare - * \param b Byte sequence to compare - * \param len Number of bytes to compare. - * \return \c 1 if \p a and \p b are equal, \c 0 otherwise. - */ -static inline int -equals(unsigned char *a, unsigned char *b, size_t len) { - int result = 1; - while (len--) { - result &= (*a++ == *b++); - } - return result; -} - -#ifdef HAVE_FLS -#define dtls_fls(i) fls(i) -#else -static inline int -dtls_fls(unsigned int i) { - int n; - for (n = 0; i; n++) - i >>= 1; - return n; -} -#endif /* HAVE_FLS */ - -#endif /* _DTLS_GLOBAL_H_ */ diff --git a/net/ip/tinydtls/hmac.c b/net/ip/tinydtls/hmac.c deleted file mode 100644 index 186c1e8f0507a270f9e58b72ce414654a7608794..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/hmac.c +++ /dev/null @@ -1,171 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2012 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include - -#include "dtls_config.h" - -#ifdef HAVE_ASSERT_H -#include -#endif - -#include "debug.h" -#include "hmac.h" - -/* use malloc()/free() on platforms other than Contiki */ -#ifndef WITH_CONTIKI -#include - -static inline dtls_hmac_context_t * -dtls_hmac_context_new() { - return (dtls_hmac_context_t *)malloc(sizeof(dtls_hmac_context_t)); -} - -static inline void -dtls_hmac_context_free(dtls_hmac_context_t *ctx) { - free(ctx); -} - -#else /* WITH_CONTIKI */ -#include "memb.h" -MEMB(hmac_context_storage, dtls_hmac_context_t, DTLS_HASH_MAX); - -static inline dtls_hmac_context_t * -dtls_hmac_context_new() { - return (dtls_hmac_context_t *)memb_alloc(&hmac_context_storage); -} - -static inline void -dtls_hmac_context_free(dtls_hmac_context_t *ctx) { - memb_free(&hmac_context_storage, ctx); -} - -void -dtls_hmac_storage_init() { - memb_init(&hmac_context_storage); -} -#endif /* WITH_CONTIKI */ - -void -dtls_hmac_update(dtls_hmac_context_t *ctx, - const unsigned char *input, size_t ilen) { - assert(ctx); - dtls_hash_update(&ctx->data, input, ilen); -} - -dtls_hmac_context_t * -dtls_hmac_new(const unsigned char *key, size_t klen) { - dtls_hmac_context_t *ctx; - - ctx = dtls_hmac_context_new(); - if (ctx) - dtls_hmac_init(ctx, key, klen); - - return ctx; -} - -void -dtls_hmac_init(dtls_hmac_context_t *ctx, const unsigned char *key, size_t klen) { - int i; - - assert(ctx); - - memset(ctx, 0, sizeof(dtls_hmac_context_t)); - - if (klen > DTLS_HMAC_BLOCKSIZE) { - dtls_hash_init(&ctx->data); - dtls_hash_update(&ctx->data, key, klen); - dtls_hash_finalize(ctx->pad, &ctx->data); - } else - memcpy(ctx->pad, key, klen); - - /* create ipad: */ - for (i=0; i < DTLS_HMAC_BLOCKSIZE; ++i) - ctx->pad[i] ^= 0x36; - - dtls_hash_init(&ctx->data); - dtls_hmac_update(ctx, ctx->pad, DTLS_HMAC_BLOCKSIZE); - - /* create opad by xor-ing pad[i] with 0x36 ^ 0x5C: */ - for (i=0; i < DTLS_HMAC_BLOCKSIZE; ++i) - ctx->pad[i] ^= 0x6A; -} - -void -dtls_hmac_free(dtls_hmac_context_t *ctx) { - if (ctx) - dtls_hmac_context_free(ctx); -} - -int -dtls_hmac_finalize(dtls_hmac_context_t *ctx, unsigned char *result) { - unsigned char buf[DTLS_HMAC_DIGEST_SIZE]; - size_t len; - - assert(ctx); - assert(result); - - len = dtls_hash_finalize(buf, &ctx->data); - - dtls_hash_init(&ctx->data); - dtls_hash_update(&ctx->data, ctx->pad, DTLS_HMAC_BLOCKSIZE); - dtls_hash_update(&ctx->data, buf, len); - - len = dtls_hash_finalize(result, &ctx->data); - - return len; -} - -#ifdef HMAC_TEST -#include - -int main(int argc, char **argv) { - static unsigned char buf[DTLS_HMAC_DIGEST_SIZE]; - size_t len, i; - dtls_hmac_context_t *ctx; - - if (argc < 3) { - fprintf(stderr, "usage: %s key text", argv[0]); - return -1; - } - - dtls_hmac_storage_init(); - ctx = dtls_hmac_new(argv[1], strlen(argv[1])); - assert(ctx); - dtls_hmac_update(ctx, argv[2], strlen(argv[2])); - - len = dtls_hmac_finalize(ctx, buf); - - for(i = 0; i < len; i++) - printf("%02x", buf[i]); - printf("\n"); - - dtls_hmac_free(ctx); - - return 0; -} -#endif diff --git a/net/ip/tinydtls/hmac.h b/net/ip/tinydtls/hmac.h deleted file mode 100644 index d9c5e533853191f16d16d6a8e16712632cab3576..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/hmac.h +++ /dev/null @@ -1,154 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2012 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _DTLS_HMAC_H_ -#define _DTLS_HMAC_H_ - -#include - -#include "global.h" - -#ifdef WITH_SHA256 -/** Aaron D. Gifford's implementation of SHA256 - * see http://www.aarongifford.com/ */ -#include "sha2/sha2.h" - -typedef SHA256_CTX dtls_hash_ctx; -typedef dtls_hash_ctx *dtls_hash_t; -#define DTLS_HASH_CTX_SIZE sizeof(SHA256_CTX) - -static inline void -dtls_hash_init(dtls_hash_t ctx) { - SHA256_Init((SHA256_CTX *)ctx); -} - -static inline void -dtls_hash_update(dtls_hash_t ctx, const unsigned char *input, size_t len) { - SHA256_Update((SHA256_CTX *)ctx, input, len); -} - -static inline size_t -dtls_hash_finalize(unsigned char *buf, dtls_hash_t ctx) { - SHA256_Final(buf, (SHA256_CTX *)ctx); - return SHA256_DIGEST_LENGTH; -} -#endif /* WITH_SHA256 */ - -#ifndef WITH_CONTIKI -static inline void dtls_hmac_storage_init() -{ } -#else -void dtls_hmac_storage_init(); -#endif - -/** - * \defgroup HMAC Keyed-Hash Message Authentication Code (HMAC) - * NIST Standard FIPS 198 describes the Keyed-Hash Message Authentication - * Code (HMAC) which is used as hash function for the DTLS PRF. - * @{ - */ - -#define DTLS_HMAC_BLOCKSIZE 64 /**< size of hmac blocks */ -#define DTLS_HMAC_DIGEST_SIZE 32 /**< digest size (for SHA-256) */ -#define DTLS_HMAC_MAX 64 /**< max number of bytes in digest */ - -/** - * List of known hash functions for use in dtls_hmac_init(). The - * identifiers are the same as the HashAlgorithm defined in - * Section 7.4.1.4.1 of RFC 5246. - */ -typedef enum { - HASH_NONE=0, HASH_MD5=1, HASH_SHA1=2, HASH_SHA224=3, - HASH_SHA256=4, HASH_SHA384=5, HASH_SHA512=6 -} dtls_hashfunc_t; - -/** - * Context for HMAC generation. This object is initialized with - * dtls_hmac_init() and must be passed to dtls_hmac_update() and - * dtls_hmac_finalize(). Once, finalized, the component \c H is - * invalid and must be initialized again with dtls_hmac_init() before - * the structure can be used again. - */ -typedef struct { - unsigned char pad[DTLS_HMAC_BLOCKSIZE]; /**< ipad and opad storage */ - dtls_hash_ctx data; /**< context for hash function */ -} dtls_hmac_context_t; - -/** - * Initializes an existing HMAC context. - * - * @param ctx The HMAC context to initialize. - * @param key The secret key. - * @param klen The length of @p key. - */ -void dtls_hmac_init(dtls_hmac_context_t *ctx, const unsigned char *key, size_t klen); - -/** - * Allocates a new HMAC context \p ctx with the given secret key. - * This function returns \c 1 if \c ctx has been set correctly, or \c - * 0 or \c -1 otherwise. Note that this function allocates new storage - * that must be released by dtls_hmac_free(). - * - * \param key The secret key. - * \param klen The length of \p key. - * \return A new dtls_hmac_context_t object or @c NULL on error - */ -dtls_hmac_context_t *dtls_hmac_new(const unsigned char *key, size_t klen); - -/** - * Releases the storage for @p ctx that has been allocated by - * dtls_hmac_new(). - * - * @param ctx The dtls_hmac_context_t to free. - */ -void dtls_hmac_free(dtls_hmac_context_t *ctx); - -/** - * Updates the HMAC context with data from \p input. - * - * \param ctx The HMAC context. - * \param input The input data. - * \param ilen Size of \p input. - */ -void dtls_hmac_update(dtls_hmac_context_t *ctx, - const unsigned char *input, size_t ilen); - -/** - * Completes the HMAC generation and writes the result to the given - * output parameter \c result. The buffer must be large enough to hold - * the message digest created by the actual hash function. If in - * doubt, use \c DTLS_HMAC_MAX. The function returns the number of - * bytes written to \c result. - * - * \param ctx The HMAC context. - * \param result Output parameter where the MAC is written to. - * \return Length of the MAC written to \p result. - */ -int dtls_hmac_finalize(dtls_hmac_context_t *ctx, unsigned char *result); - -/**@}*/ - -#endif /* _DTLS_HMAC_H_ */ diff --git a/net/ip/tinydtls/netq.c b/net/ip/tinydtls/netq.c deleted file mode 100644 index 0a10a50fa179390af34b75f1360b1ff97a5ba7a9..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/netq.c +++ /dev/null @@ -1,140 +0,0 @@ -/* netq.h -- Simple packet queue - * - * Copyright (C) 2010--2012 Olaf Bergmann - * - * This file is part of the library tinyDTLS. Please see the file - * LICENSE for terms of use. - */ - -#include "dtls_config.h" -#include "debug.h" -#include "netq.h" - -#ifdef HAVE_ASSERT_H -#include -#else -#ifndef assert -#warning "assertions are disabled" -# define assert(x) -#endif -#endif - -#include "t_list.h" - -#ifndef WITH_CONTIKI -#include - -static inline netq_t * -netq_malloc_node(size_t size) { - return (netq_t *)malloc(sizeof(netq_t) + size); -} - -static inline void -netq_free_node(netq_t *node) { - free(node); -} - -/* FIXME: implement Contiki's list functions using utlist.h */ - -#else /* WITH_CONTIKI */ -#include "memb.h" - -MEMB(netq_storage, netq_t, NETQ_MAXCNT); - -static inline netq_t * -netq_malloc_node(size_t size) { - return (netq_t *)memb_alloc(&netq_storage); -} - -static inline void -netq_free_node(netq_t *node) { - memb_free(&netq_storage, node); -} - -void -netq_init() { - memb_init(&netq_storage); -} -#endif /* WITH_CONTIKI */ - -int -netq_insert_node(list_t queue, netq_t *node) { - netq_t *p; - - assert(queue); - assert(node); - - p = (netq_t *)list_head(queue); - while(p && p->t <= node->t && list_item_next(p)) - p = list_item_next(p); - - if (p) - list_insert(queue, p, node); - else - list_push(queue, node); - - return 1; -} - -netq_t * -netq_head(list_t queue) { - if (!queue) - return NULL; - - return list_head(queue); -} - -netq_t * -netq_next(netq_t *p) { - if (!p) - return NULL; - - return list_item_next(p); -} - -void -netq_remove(list_t queue, netq_t *p) { - if (!queue || !p) - return; - - list_remove(queue, p); -} - -netq_t *netq_pop_first(list_t queue) { - if (!queue) - return NULL; - - return list_pop(queue); -} - -netq_t * -netq_node_new(size_t size) { - netq_t *node; - node = netq_malloc_node(size); - -#ifndef NDEBUG - if (!node) - dtls_warn("netq_node_new: malloc\n"); -#endif - - if (node) - memset(node, 0, sizeof(netq_t)); - - return node; -} - -void -netq_node_free(netq_t *node) { - if (node) - netq_free_node(node); -} - -void -netq_delete_all(list_t queue) { - netq_t *p; - if (queue) { - while((p = list_pop(queue))) - netq_free_node(p); - } -} - diff --git a/net/ip/tinydtls/netq.h b/net/ip/tinydtls/netq.h deleted file mode 100644 index a771b2342311b16bc8ce991d96e19194e3ce4a73..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/netq.h +++ /dev/null @@ -1,103 +0,0 @@ -/* netq.h -- Simple packet queue - * - * Copyright (C) 2010--2012 Olaf Bergmann - * - * This file is part of the library tinyDTLS. Please see the file - * LICENSE for terms of use. - */ - -#ifndef _DTLS_NETQ_H_ -#define _DTLS_NETQ_H_ - -#include "tinydtls.h" -#include "global.h" -#include "dtls.h" -#include "dtls_time.h" - -/** - * \defgroup netq Network Packet Queue - * The netq utility functions implement an ordered queue of data packets - * to send over the network and can also be used to queue received packets - * from the network. - * @{ - */ - -#ifndef NETQ_MAXCNT -#ifdef DTLS_ECC -#define NETQ_MAXCNT 5 /**< maximum number of elements in netq structure */ -#elif defined(DTLS_PSK) -#define NETQ_MAXCNT 3 /**< maximum number of elements in netq structure */ -#endif -#endif - -/** - * Datagrams in the netq_t structure have a fixed maximum size of - * DTLS_MAX_BUF to simplify memory management on constrained nodes. */ -typedef unsigned char netq_packet_t[DTLS_MAX_BUF]; - -typedef struct netq_t { - struct netq_t *next; - - clock_time_t t; /**< when to send PDU for the next time */ - unsigned int timeout; /**< randomized timeout value */ - - dtls_peer_t *peer; /**< remote address */ - uint16_t epoch; - uint8_t type; - unsigned char retransmit_cnt; /**< retransmission counter, will be removed when zero */ - - size_t length; /**< actual length of data */ -#ifndef WITH_CONTIKI - unsigned char data[]; /**< the datagram to send */ -#else - netq_packet_t data; /**< the datagram to send */ -#endif -} netq_t; - -#ifndef WITH_CONTIKI -static inline void netq_init() -{ } -#else -void netq_init(); -#endif - -/** - * Adds a node to the given queue, ordered by their time-stamp t. - * This function returns @c 0 on error, or non-zero if @p node has - * been added successfully. - * - * @param queue A pointer to the queue head where @p node will be added. - * @param node The new item to add. - * @return @c 0 on error, or non-zero if the new item was added. - */ -int netq_insert_node(list_t queue, netq_t *node); - -/** Destroys specified node and releases any memory that was allocated - * for the associated datagram. */ -void netq_node_free(netq_t *node); - -/** Removes all items from given queue and frees the allocated storage */ -void netq_delete_all(list_t queue); - -/** Creates a new node suitable for adding to a netq_t queue. */ -netq_t *netq_node_new(size_t size); - -/** - * Returns a pointer to the first item in given queue or NULL if - * empty. - */ -netq_t *netq_head(list_t queue); - -netq_t *netq_next(netq_t *p); -void netq_remove(list_t queue, netq_t *p); - -/** - * Removes the first item in given queue and returns a pointer to the - * removed element. If queue is empty when netq_pop_first() is called, - * this function returns NULL. - */ -netq_t *netq_pop_first(list_t queue); - -/**@}*/ - -#endif /* _DTLS_NETQ_H_ */ diff --git a/net/ip/tinydtls/numeric.h b/net/ip/tinydtls/numeric.h deleted file mode 100644 index e319f5b32eaefa1abfe3af10ef7e69e0eecc9e32..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/numeric.h +++ /dev/null @@ -1,142 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _DTLS_NUMERIC_H_ -#define _DTLS_NUMERIC_H_ - -#include - -#ifndef min -#define min(A,B) ((A) <= (B) ? (A) : (B)) -#endif - -#ifndef max -#define max(A,B) ((A) < (B) ? (B) : (A)) -#endif - -/* this one is for consistency... */ -static inline int dtls_int_to_uint8(unsigned char *field, uint8_t value) -{ - field[0] = value & 0xff; - return 1; -} - -static inline int dtls_int_to_uint16(unsigned char *field, uint16_t value) -{ - field[0] = (value >> 8) & 0xff; - field[1] = value & 0xff; - return 2; -} - -static inline int dtls_int_to_uint24(unsigned char *field, uint32_t value) -{ - field[0] = (value >> 16) & 0xff; - field[1] = (value >> 8) & 0xff; - field[2] = value & 0xff; - return 3; -} - -static inline int dtls_int_to_uint32(unsigned char *field, uint32_t value) -{ - field[0] = (value >> 24) & 0xff; - field[1] = (value >> 16) & 0xff; - field[2] = (value >> 8) & 0xff; - field[3] = value & 0xff; - return 4; -} - -static inline int dtls_int_to_uint48(unsigned char *field, uint64_t value) -{ - field[0] = (value >> 40) & 0xff; - field[1] = (value >> 32) & 0xff; - field[2] = (value >> 24) & 0xff; - field[3] = (value >> 16) & 0xff; - field[4] = (value >> 8) & 0xff; - field[5] = value & 0xff; - return 6; -} - -static inline int dtls_int_to_uint64(unsigned char *field, uint64_t value) -{ - field[0] = (value >> 56) & 0xff; - field[1] = (value >> 48) & 0xff; - field[2] = (value >> 40) & 0xff; - field[3] = (value >> 32) & 0xff; - field[4] = (value >> 24) & 0xff; - field[5] = (value >> 16) & 0xff; - field[6] = (value >> 8) & 0xff; - field[7] = value & 0xff; - return 8; -} - -static inline uint8_t dtls_uint8_to_int(const unsigned char *field) -{ - return (uint8_t)field[0]; -} - -static inline uint16_t dtls_uint16_to_int(const unsigned char *field) -{ - return ((uint16_t)field[0] << 8) - | (uint16_t)field[1]; -} - -static inline uint32_t dtls_uint24_to_int(const unsigned char *field) -{ - return ((uint32_t)field[0] << 16) - | ((uint32_t)field[1] << 8) - | (uint32_t)field[2]; -} - -static inline uint32_t dtls_uint32_to_int(const unsigned char *field) -{ - return ((uint32_t)field[0] << 24) - | ((uint32_t)field[1] << 16) - | ((uint32_t)field[2] << 8) - | (uint32_t)field[3]; -} - -static inline uint64_t dtls_uint48_to_int(const unsigned char *field) -{ - return ((uint64_t)field[0] << 40) - | ((uint64_t)field[1] << 32) - | ((uint64_t)field[2] << 24) - | ((uint64_t)field[3] << 16) - | ((uint64_t)field[4] << 8) - | (uint64_t)field[5]; -} - -static inline uint64_t dtls_uint64_to_int(const unsigned char *field) -{ - return ((uint64_t)field[0] << 56) - | ((uint64_t)field[1] << 48) - | ((uint64_t)field[2] << 40) - | ((uint64_t)field[3] << 32) - | ((uint64_t)field[4] << 24) - | ((uint64_t)field[5] << 16) - | ((uint64_t)field[6] << 8) - | (uint64_t)field[7]; -} - -#endif /* _DTLS_NUMERIC_H_ */ diff --git a/net/ip/tinydtls/peer.c b/net/ip/tinydtls/peer.c deleted file mode 100644 index 8f2876cda94e42abf17b0312c2bdf8063bb89b29..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/peer.c +++ /dev/null @@ -1,90 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2013 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "global.h" -#include "peer.h" -#include "debug.h" - -#ifndef WITH_CONTIKI -void peer_init() -{ -} - -static inline dtls_peer_t * -dtls_malloc_peer() { - return (dtls_peer_t *)malloc(sizeof(dtls_peer_t)); -} - -void -dtls_free_peer(dtls_peer_t *peer) { - dtls_handshake_free(peer->handshake_params); - dtls_security_free(peer->security_params[0]); - dtls_security_free(peer->security_params[1]); - free(peer); -} -#else /* WITH_CONTIKI */ - -#include "memb.h" -MEMB(peer_storage, dtls_peer_t, DTLS_PEER_MAX); - -void -peer_init() { - memb_init(&peer_storage); -} - -static inline dtls_peer_t * -dtls_malloc_peer() { - return memb_alloc(&peer_storage); -} - -void -dtls_free_peer(dtls_peer_t *peer) { - dtls_handshake_free(peer->handshake_params); - dtls_security_free(peer->security_params[0]); - dtls_security_free(peer->security_params[1]); - memb_free(&peer_storage, peer); -} -#endif /* WITH_CONTIKI */ - -dtls_peer_t * -dtls_new_peer(const session_t *session) { - dtls_peer_t *peer; - - peer = dtls_malloc_peer(); - if (peer) { - memset(peer, 0, sizeof(dtls_peer_t)); - memcpy(&peer->session, session, sizeof(session_t)); - peer->security_params[0] = dtls_security_new(); - - if (!peer->security_params[0]) { - dtls_free_peer(peer); - return NULL; - } - - dtls_dsrv_log_addr(DTLS_LOG_DEBUG, "dtls_new_peer", session); - } - - return peer; -} diff --git a/net/ip/tinydtls/peer.h b/net/ip/tinydtls/peer.h deleted file mode 100644 index 7f10aca452bea16dfeca922aeb24c4d60690ccc3..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/peer.h +++ /dev/null @@ -1,140 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2013 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * @file peer.h - * @brief information about peers in a DTLS session - */ - -#ifndef _DTLS_PEER_H_ -#define _DTLS_PEER_H_ - -#include - -#include "tinydtls.h" -#include "global.h" -#include "session.h" - -#include "state.h" -#include "crypto.h" - -typedef enum { DTLS_CLIENT=0, DTLS_SERVER } dtls_peer_type; - -/** - * Holds security parameters, local state and the transport address - * for each peer. */ -typedef struct dtls_peer_t { - struct dtls_peer_t *next; - - session_t session; /**< peer address and local interface */ - - dtls_peer_type role; /**< denotes if this host is DTLS_CLIENT or DTLS_SERVER */ - dtls_state_t state; /**< DTLS engine state */ - - dtls_security_parameters_t *security_params[2]; - dtls_handshake_parameters_t *handshake_params; -} dtls_peer_t; - -static inline dtls_security_parameters_t *dtls_security_params_epoch(dtls_peer_t *peer, uint16_t epoch) -{ - if (peer->security_params[0] && peer->security_params[0]->epoch == epoch) { - return peer->security_params[0]; - } else if (peer->security_params[1] && peer->security_params[1]->epoch == epoch) { - return peer->security_params[1]; - } else { - return NULL; - } -} - -static inline dtls_security_parameters_t *dtls_security_params(dtls_peer_t *peer) -{ - return peer->security_params[0]; -} - -static inline dtls_security_parameters_t *dtls_security_params_next(dtls_peer_t *peer) -{ - if (peer->security_params[1]) - dtls_security_free(peer->security_params[1]); - - peer->security_params[1] = dtls_security_new(); - if (!peer->security_params[1]) { - return NULL; - } - peer->security_params[1]->epoch = peer->security_params[0]->epoch + 1; - return peer->security_params[1]; -} - -static inline void dtls_security_params_free_other(dtls_peer_t *peer) -{ - dtls_security_parameters_t * security0 = peer->security_params[0]; - dtls_security_parameters_t * security1 = peer->security_params[1]; - - if (!security0 || !security1 || security0->epoch < security1->epoch) - return; - - dtls_security_free(security1); - peer->security_params[1] = NULL; -} - -static inline void dtls_security_params_switch(dtls_peer_t *peer) -{ - dtls_security_parameters_t * security = peer->security_params[1]; - - peer->security_params[1] = peer->security_params[0]; - peer->security_params[0] = security; -} - -void peer_init(); - -/** - * Creates a new peer for given @p session. The current configuration - * is initialized with the cipher suite TLS_NULL_WITH_NULL_NULL (i.e. - * no security at all). This function returns a pointer to the new - * peer or NULL on error. The caller is responsible for releasing the - * storage allocated for this peer using dtls_free_peer(). - * - * @param session The remote peer's address and local interface index. - * @return A pointer to a newly created and initialized peer object - * or NULL on error. - */ -dtls_peer_t *dtls_new_peer(const session_t *session); - -/** Releases the storage allocated to @p peer. */ -void dtls_free_peer(dtls_peer_t *peer); - -/** Returns the current state of @p peer. */ -static inline dtls_state_t dtls_peer_state(const dtls_peer_t *peer) { - return peer->state; -} - -/** - * Checks if given @p peer is connected. This function returns - * @c 1 if connected, or @c 0 otherwise. - */ -static inline int dtls_peer_is_connected(const dtls_peer_t *peer) { - return peer->state == DTLS_STATE_CONNECTED; -} - -#endif /* _DTLS_PEER_H_ */ diff --git a/net/ip/tinydtls/platform-specific/Makefile.in b/net/ip/tinydtls/platform-specific/Makefile.in deleted file mode 100644 index 6b30d21a96a63174b3368b2b2f3c8728bba16292..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/platform-specific/Makefile.in +++ /dev/null @@ -1,27 +0,0 @@ -# the library's version -VERSION:=@PACKAGE_VERSION@ - -# tools -@SET_MAKE@ -SHELL = /bin/sh -MKDIR = mkdir - -top_builddir = @top_builddir@ - -THIS=platform-specific -DISTDIR?=$(top_builddir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@ -FILES:=Makefile.in $(wildcard *.h) - -clean: - -distclean: clean - @rm -rf $(DISTDIR) - @rm -f *~ - -dist: - test -d $(DISTDIR)/$(THIS) || mkdir $(DISTDIR)/$(THIS) - cp -r $(FILES) $(DISTDIR)/$(THIS) - -# this directory contains no installation candidates -install: - : diff --git a/net/ip/tinydtls/platform-specific/config-cc2538dk.h b/net/ip/tinydtls/platform-specific/config-cc2538dk.h deleted file mode 100644 index 38bc85e79d5357f9b67e1de296486905a5f80750..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/platform-specific/config-cc2538dk.h +++ /dev/null @@ -1,2 +0,0 @@ -#define BYTE_ORDER 1234 -#define HAVE_ASSERT_H 1 diff --git a/net/ip/tinydtls/platform-specific/config-econotag.h b/net/ip/tinydtls/platform-specific/config-econotag.h deleted file mode 100644 index 38bc85e79d5357f9b67e1de296486905a5f80750..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/platform-specific/config-econotag.h +++ /dev/null @@ -1,2 +0,0 @@ -#define BYTE_ORDER 1234 -#define HAVE_ASSERT_H 1 diff --git a/net/ip/tinydtls/platform-specific/config-minimal-net.h b/net/ip/tinydtls/platform-specific/config-minimal-net.h deleted file mode 100644 index 547a1b68ee82a318856338931cedf413f6c5eb89..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/platform-specific/config-minimal-net.h +++ /dev/null @@ -1 +0,0 @@ -#define HAVE_ASSERT_H 1 diff --git a/net/ip/tinydtls/platform-specific/config-native.h b/net/ip/tinydtls/platform-specific/config-native.h deleted file mode 100644 index 547a1b68ee82a318856338931cedf413f6c5eb89..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/platform-specific/config-native.h +++ /dev/null @@ -1 +0,0 @@ -#define HAVE_ASSERT_H 1 diff --git a/net/ip/tinydtls/platform-specific/config-sky.h b/net/ip/tinydtls/platform-specific/config-sky.h deleted file mode 100644 index f49ff3bca1fde1e383501f2007fc51279ae3fa0e..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/platform-specific/config-sky.h +++ /dev/null @@ -1,3 +0,0 @@ -#define BYTE_ORDER 1234 -#define HAVE_ASSERT_H 1 -typedef int ssize_t; diff --git a/net/ip/tinydtls/platform-specific/config-wismote.h b/net/ip/tinydtls/platform-specific/config-wismote.h deleted file mode 100644 index 547a1b68ee82a318856338931cedf413f6c5eb89..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/platform-specific/config-wismote.h +++ /dev/null @@ -1 +0,0 @@ -#define HAVE_ASSERT_H 1 diff --git a/net/ip/tinydtls/platform-specific/config-zephyr.h b/net/ip/tinydtls/platform-specific/config-zephyr.h deleted file mode 100644 index 0a95f5901307e20206ec590abeacca4eec34d9e6..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/platform-specific/config-zephyr.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define HAVE_ASSERT_H 1 - -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -#define BYTE_ORDER LITTLE_ENDIAN -#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -#define BYTE_ORDER BIG_ENDIAN -#else -#error "Unknown byte order" -#endif - -#ifndef MAY_ALIAS -#define MAY_ALIAS __attribute__((__may_alias__)) -#endif diff --git a/net/ip/tinydtls/platform-specific/platform.h b/net/ip/tinydtls/platform-specific/platform.h deleted file mode 100644 index 28d00a2e6a0ad8c55be1d2d02eb56a83602287c2..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/platform-specific/platform.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/************************************************************************/ -/* Contiki-specific parameters */ -/************************************************************************/ - -#ifndef _PLATFORM_H_ -#define _PLATFORM_H_ 1 - -#ifdef CONTIKI -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" - -#include "contiki-conf.h" - -/* global constants for constrained devices running Contiki */ -#ifndef DTLS_PEER_MAX -/** The maximum number DTLS peers (i.e. sessions). */ -# define DTLS_PEER_MAX 1 -#endif - -#ifndef DTLS_HANDSHAKE_MAX -/** The maximum number of concurrent DTLS handshakes. */ -# define DTLS_HANDSHAKE_MAX 1 -#endif - -#ifndef DTLS_SECURITY_MAX -/** The maximum number of concurrently used cipher keys */ -# define DTLS_SECURITY_MAX (DTLS_PEER_MAX + DTLS_HANDSHAKE_MAX) -#endif - -#ifndef DTLS_HASH_MAX -/** The maximum number of hash functions that can be used in parallel. */ -# define DTLS_HASH_MAX (3 * DTLS_PEER_MAX) -#endif - -/************************************************************************/ -/* Specific Contiki platforms */ -/************************************************************************/ - -#if CONTIKI_TARGET_ECONOTAG -# include "platform-specific/config-econotag.h" -#endif /* CONTIKI_TARGET_ECONOTAG */ - -#ifdef CONTIKI_TARGET_CC2538DK -# include "platform-specific/config-cc2538dk.h" -#endif /* CONTIKI_TARGET_CC2538DK */ - -#ifdef CONTIKI_TARGET_FELICIA -#define CONTIKI_TARGET_CC2538DK 1 -# include "platform-specific/config-cc2538dk.h" -#endif /* CONTIKI_TARGET_CC2538DK */ - -#ifdef CONTIKI_TARGET_WISMOTE -# include "platform-specific/config-wismote.h" -#endif /* CONTIKI_TARGET_WISMOTE */ - -#ifdef CONTIKI_TARGET_SKY -# include "platform-specific/config-sky.h" -#endif /* CONTIKI_TARGET_SKY */ - -#ifdef CONTIKI_TARGET_MINIMAL_NET -# include "platform-specific/config-minimal-net.h" -#endif /* CONTIKI_TARGET_MINIMAL_NET */ - -#ifdef CONTIKI_TARGET_NATIVE -# include "platform-specific/config-native.h" -#endif /* CONTIKI_TARGET_NATIVE */ - -#ifdef CONTIKI_TARGET_ZEPHYR -# include "platform-specific/config-zephyr.h" -#endif /* CONTIKI_TARGET_ZEPHYR */ - -#endif /* CONTIKI */ - -#endif /* _PLATFORM_H_ */ diff --git a/net/ip/tinydtls/prng.h b/net/ip/tinydtls/prng.h deleted file mode 100644 index 658cd22f355f7a5fad76e029301a92844286793b..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/prng.h +++ /dev/null @@ -1,87 +0,0 @@ -/* prng.h -- Pseudo Random Numbers - * - * Copyright (C) 2010--2012 Olaf Bergmann - * - * This file is part of the library tinydtls. Please see - * README for terms of use. - */ - -/** - * @file prng.h - * @brief Pseudo Random Numbers - */ - -#ifndef _DTLS_PRNG_H_ -#define _DTLS_PRNG_H_ - -#include "tinydtls.h" - -/** - * @defgroup prng Pseudo Random Numbers - * @{ - */ - -#ifndef WITH_CONTIKI -#include - -/** - * Fills \p buf with \p len random bytes. This is the default - * implementation for prng(). You might want to change prng() to use - * a better PRNG on your specific platform. - */ -static inline int -dtls_prng(unsigned char *buf, size_t len) { - while (len--) - *buf++ = rand() & 0xFF; - return 1; -} - -static inline void -dtls_prng_init(unsigned short seed) { - srand(seed); -} -#else /* WITH_CONTIKI */ -#include -#include "random.h" - -#ifdef HAVE_PRNG -static inline int -dtls_prng(unsigned char *buf, size_t len) -{ - return contiki_prng_impl(buf, len); -} -#else -/** - * Fills \p buf with \p len random bytes. This is the default - * implementation for prng(). You might want to change prng() to use - * a better PRNG on your specific platform. - */ -static inline int -dtls_prng(unsigned char *buf, size_t len) { - unsigned short v = random_rand(); - while (len > sizeof(v)) { - memcpy(buf, &v, sizeof(v)); - len -= sizeof(v); - buf += sizeof(v); - v = random_rand(); - } - - memcpy(buf, &v, len); - return 1; -} -#endif /* HAVE_PRNG */ - -static inline void -dtls_prng_init(unsigned short seed) { - /* random_init() messes with the radio interface of the CC2538 and - * therefore must not be called after the radio has been - * initialized. */ -#ifndef CONTIKI_TARGET_CC2538DK - random_init(seed); -#endif -} -#endif /* WITH_CONTIKI */ - -/** @} */ - -#endif /* _DTLS_PRNG_H_ */ diff --git a/net/ip/tinydtls/session.c b/net/ip/tinydtls/session.c deleted file mode 100644 index eb102978b4c4543dbc2bd3937270fd0c34a3f164..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/session.c +++ /dev/null @@ -1,83 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2014 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "dtls_config.h" -#include "session.h" - -#ifdef HAVE_ASSERT_H -#include -#else -#ifndef assert -#warning "assertions are disabled" -# define assert(x) -#endif -#endif - -#ifdef WITH_CONTIKI -#define _dtls_address_equals_impl(A,B) \ - ((A)->size == (B)->size \ - && (A)->addr.port == (B)->addr.port \ - && uip_ipaddr_cmp(&((A)->addr.ipaddr),&((B)->addr.ipaddr)) \ - && (A)->ifindex == (B)->ifindex) - -#else /* WITH_CONTIKI */ - -static inline int -_dtls_address_equals_impl(const session_t *a, - const session_t *b) { - if (a->ifindex != b->ifindex || - a->size != b->size || a->addr.sa.sa_family != b->addr.sa.sa_family) - return 0; - - /* need to compare only relevant parts of sockaddr_in6 */ - switch (a->addr.sa.sa_family) { - case AF_INET: - return - a->addr.sin.sin_port == b->addr.sin.sin_port && - memcmp(&a->addr.sin.sin_addr, &b->addr.sin.sin_addr, - sizeof(struct in_addr)) == 0; - case AF_INET6: - return a->addr.sin6.sin6_port == b->addr.sin6.sin6_port && - memcmp(&a->addr.sin6.sin6_addr, &b->addr.sin6.sin6_addr, - sizeof(struct in6_addr)) == 0; - default: /* fall through and signal error */ - ; - } - return 0; -} -#endif /* WITH_CONTIKI */ - -void -dtls_session_init(session_t *sess) { - assert(sess); - memset(sess, 0, sizeof(session_t)); - sess->size = sizeof(sess->addr); -} - -int -dtls_session_equals(const session_t *a, const session_t *b) { - assert(a); assert(b); - return _dtls_address_equals_impl(a, b); -} diff --git a/net/ip/tinydtls/session.h b/net/ip/tinydtls/session.h deleted file mode 100644 index de4c2b74a05404ecb11990e7e341302494f9f2f6..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/session.h +++ /dev/null @@ -1,78 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2014 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _DTLS_SESSION_H_ -#define _DTLS_SESSION_H_ - -#include - -#include "tinydtls.h" -#include "global.h" - -#ifdef WITH_CONTIKI -#include "ip/uip.h" -typedef struct { - unsigned char size; - struct { - uip_ipaddr_t ipaddr; - unsigned short port; - } addr; - int ifindex; -} session_t; - -#else /* WITH_CONTIKI */ - -#include -#include -#include - -typedef struct { - socklen_t size; /**< size of addr */ - union { - struct sockaddr sa; - struct sockaddr_storage st; - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - } addr; - uint8_t ifindex; -} session_t; -#endif /* WITH_CONTIKI */ - -/** - * Resets the given session_t object @p sess to its default - * values. In particular, the member rlen must be initialized to the - * available size for storing addresses. - * - * @param sess The session_t object to initialize. - */ -void dtls_session_init(session_t *sess); - -/** - * Compares the given session objects. This function returns @c 0 - * when @p a and @p b differ, @c 1 otherwise. - */ -int dtls_session_equals(const session_t *a, const session_t *b); - -#endif /* _DTLS_SESSION_H_ */ diff --git a/net/ip/tinydtls/sha2/Makefile.in b/net/ip/tinydtls/sha2/Makefile.in deleted file mode 100644 index 85ce9ce079e01d908c2c386f30551b543d8c0d05..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/Makefile.in +++ /dev/null @@ -1,78 +0,0 @@ -# Makefile for tinydtls -# -# Copyright (C) 2011 Olaf Bergmann -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, copy, -# modify, merge, publish, distribute, sublicense, and/or sell copies -# of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# the library's version -VERSION:=@PACKAGE_VERSION@ - -# tools -@SET_MAKE@ -SHELL = /bin/sh -MKDIR = mkdir - -abs_builddir = @abs_builddir@ -top_builddir = @top_builddir@ -top_srcdir:= @top_srcdir@ - -SOURCES:= sha2.c -HEADERS:=sha2.h -OBJECTS:= $(patsubst %.c, %.o, $(SOURCES)) -CPPFLAGS=@CPPFLAGS@ -I$(top_srcdir) -CFLAGS=-Wall -std=c99 -pedantic @CFLAGS@ -LDLIBS=@LIBS@ -FILES:=Makefile.in $(SOURCES) $(HEADERS) README sha2prog.c sha2speed.c sha2test.pl -DISTDIR=$(top_builddir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@ - -.PHONY: all dirs clean install dist distclean .gitignore doc - -.SUFFIXES: -.SUFFIXES: .c .o - -all: - -check: - echo DISTDIR: $(DISTDIR) - echo top_builddir: $(top_builddir) - -clean: - @rm -f $(PROGRAMS) main.o $(LIB) $(OBJECTS) - for dir in $(SUBDIRS); do \ - $(MAKE) -C $$dir clean ; \ - done - -distclean: clean - @rm -rf $(DISTDIR) - @rm -f *~ $(DISTDIR).tar.gz - -dist: $(FILES) - test -d $(DISTDIR)/sha2 || mkdir $(DISTDIR)/sha2 - cp -p $(FILES) $(DISTDIR)/sha2 - test -d $(DISTDIR)/sha2/testvectors || mkdir $(DISTDIR)/sha2/testvectors - cp -pr testvectors $(DISTDIR)/sha2/testvectors - -install: $(HEADERS) - test -d $(includedir)/sha2 || mkdir -p $(includedir)/sha2 - $(install) $(HEADERS) $(includedir)/sha2 - -.gitignore: - echo "core\n*~\n*.[oa]\n*.gz\n*.cap\n$(PROGRAM)\n$(DISTDIR)\n.gitignore" >$@ diff --git a/net/ip/tinydtls/sha2/README b/net/ip/tinydtls/sha2/README deleted file mode 100644 index 95e57f39d816687a0d9f6bf31837a773e292a06b..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/README +++ /dev/null @@ -1,272 +0,0 @@ -VERSION: - -This is version 1.0 RELEASE - -While this is my "release" version, due to lack of additional -official test vectors against which to verify this implementation's -correctness, beware that there may be implementation bugs. Also, -it has not yet been tested on very many other architectures, -big-endian machines in particular. - - -LICENSE: - -This implementation is released freely under an open-source BSD -license which appears at the top of each source code file. - - -WHAT IT IS: - -The files sha2.h and sha2.c implement the SHA-256, SHA-384, and SHA-512 -hash algorithms as described in the PDF document found at the following -web address: - - http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf - -The interface is similar to the interface to SHA-1 found in the OpenSSL -library. - -The file sha2prog.c is a simple program that accepts input from either -STDIN or reads one or more files specified on the command line, and then -generates the specified hash (either SHA-256, SHA-384, SHA-512, or any -combination thereof, including all three at once). - - -LIMITATIONS: - -This implementation has several limitations: - - * Input data is only accepted in octet-length increments. No sub-byte - data is handled. The NIST document describes how to handle sub-byte - input data, but for ease of implementation this version will only - accept message data in multiples of bytes. - * This implementation utilizes 64-bit integer data types. If your - system and compiler does not have a 64-bit integer data type, this - implementation will not work. - * Because of the use of 64-bit operations, many 32-bit architectures - that do have 64-bit data types but do operations most efficiently - on 32-bit words, this implementation may be slower than an - implementation designed to use only 32-bit words (emulating the - 64-bit operations). - * On platforms with 128-bit integer data types, the SHA-384 and SHA-512 - bit counters used by this implementation might be better off using - the 128-bit type instead of simulating it with two 64-bit integers. - * This implementation was written in C in hopes of portability and for - the fun of it during my spare time. It is probably not the most - efficient or fastest C implementation. I welcome suggestions, - however, that suggest ways to speed things up without breaking - portability. I also welcome suggestions to improve portability. - * As mentioned above, this code has NOT been thoroughly tested. - This is perhaps the most severe limitation. - - -BEFORE YOU COMPILE (OPTIONS): - -Each of the options described below may either be defined in the sha2.h -header file (or in the sha2.c file in some cases), or on the command -line at compile time if your compiler supports such things. For -example: - - #define SHA2_USE_INTTYPES_H - #define SHA2_UNROLL_TRANSFORM - -Or: - - cc -c -DSHA2_UNROLL_TRANSFORM sha2.c - cc -c -DBYTE_ORDER=4321 -DBIG_ENDIAN=4321 sha2.c - -Here are the available options. Read on below for a description of -each one: - - SHA2_USE_INTTYPES_H - SHA2_USE_MEMSET_MEMCPY/SHA2_USE_BZERO_BCOPY - SHA2_UNROLL_TRANSFORM - BYTE_ORDER (LITTLE_ENDIAN/BIG_ENDIAN) - -* SHA2_USE_INTTYPES_H option: -By default, this code uses u_intXX_t data types for 8 bit, 32 bit, and -64 bit unsigned integer type definitions. Most BSD systems define these, -as does Linux. However, some (like Compaq's Tru64 Unix) may instead -use uintXX_t data types as defined by recent ANSI C standards and as -included in the inttypes.h header file. Those wanting to use inttypes.h -need to define this either in sha.h or at compile time. - -On those systems where NEITHER definitions are available, you will need -to edit both sha2.h and sha2.c and define things by hand in the appropriate -sections. - -* BYTE_ORDER definitions: -This code assumes that BYTE_ORDER will be defined by the system during -compile to either equal LITTLE_ENDIAN or BIG_ENDIAN. If your system -does not define these, you may need to define them by hand in the sha.c -file according to the byte ordering conventions of your system. - -* SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY -The code in sha2.c can use either memset()/memcpy() for memory block -operations, or bzero()/mcopy(). If you define neither of these, the -code will default to memset()/memcpy(). You can define either at the -command line or in sha2.h or in sha2.c. - -* SHA2_UNROLL_TRANSFORM -By defining this either on the command line or in sha2.h or sha2.c, -the code will use macros to partially "unroll" the SHA transform -function. This usually generates bigger executables. It CAN (but -not necessarily WILL) generate faster code when you tell your compiler -to optimize things. For example, on the FreeBSD and Linux x86 systems -I tested things on (using gcc), when I optimized with just -O2 and -unrolled the transform, the hash transform was faster by 15-30%. On -these same systems, if I did NO optimization, the unrolled transform -was SLOWER, much slower (I'm guessing because the code was breaking -the cache, but I'm not sure). Your mileage may vary. - - -PORTABILITY: - -The code in sha2.c and sha2.h is intended to be portable. It may -require that you do a few #definitions in the .h file. I've successfully -compiled and tested the sha2.c and sha2.h code on Apple's OS X (on -a PPC), FreeBSD 4.1.1 on Intel, Linux on Intel, FreeBSD on the Alpha, -and even under Windows98SE using Metrowerks C. The utility/example -programs (sha2prog.c, sha2test.c, and sha2speed.c) will very likely -have more trouble in portability since they do I/O. - -To get sha2.c/sha2.h working under Windows, I had to define -SHA2_USE_INTTYPES_H, BYTE_ORDER, LITTLE_ENDIAN, and had to comment -out the include of in sha2.h. With a bit more work -I got the test program to run and verified that all the test -cases passed. - - -SUGGESTIONS/BUG FIXES: - -If you make changes to get it working on other architectures, if you fix -any bugs, or if you make changes that improve this implementation's -efficiency that would be relatively portable and you're willing to release -your changes under the same license, please send them to me for possible -inclusion in future versions. - -If you know where I can find some additional test vectors, please let me -know. - - -CHANGE HISTORY: - -0.8 to 0.9 - Fixed spelling errors, changed to u_intXX_t type usage, - removed names from prototypes, added prototypes to sha2.c, - and a few things I can't recall. - -0.9 to 0.9.5 - Add a new define in sha2.c that permits one to compile - it to either use memcpy()/memset() or bcopy()/bzero() - for memory block copying and zeroing. Added support - for unrolled SHA-256/384/512 transform loops. Just - compile with SHA2_UNROLL_TRANSFORM to enable. It takes - longer to compile, but I hope it is a bit faster. I - need to do some test to see whether or not it is. Oh, - in sha2.c, you either need to define SHA2_USE_BZERO_BCOPY - or SHA2_USE_MEMSET_MEMCPY to choose which way you want - to compile. *Whew* It's amazing how quickly something - simple starts to grow more complex even in the span of - just a few hours. I didn't really intend to do this much. -0.9.5 to 0.9.6 - Added a test program (sha2test) which tests against several - known test vectors. WARNING: Some of the test output - hashes are NOT from NIST's documentation and are the - output of this implementation and so may be incorrect. -0.9.6 to 0.9.7 - Fixed a bug that could cause invalid output in certain - cases and added an assumed scenario where zero-length - data is hashed. Also changed the rotation macros to use - a temporary variable as this reduces the number of operations. - When data is fed in blocks of the right length, copying of - data is reduced in this version. Added SHAYXZ_Data() - functions for ease of hashing a set of data. Added another - file sha2speed.c for doing speed testing. Added another test - vector with a larger data size (16KB). Fixed u_intXX_t and - uintXX_t handling by adding a define for SHA2_USE_INTTYPES_H - as well as made a few other minor changes to get rid of - warnings when compiling on Compaq's Tru64 Unix. -0.9.7 to 0.9.8 - The bug fix in 0.9.7 was incomplete and in some cases made - things worse. I believe that 0.9.8 fixes the bug completely - so that output is correct. I cannot verify this, however, - because of the lack of test vectors against which to do such - verification. All versions correctly matched the very few - NIST-provided vectors, but unfortunately the bug only - appeared in longer message data sets. -0.9.8 to 0.9.9 - Fixed some really bad typos and mistakes on my part that - only affected big-endian systems. I didn't have direct - access for testing before this version. Thanks to - Lucas Marshall for giving me access to his OS X system. -0.9.9 to 1.0.0b1 Added a few more test samples and made a few changes to - make things easier compiling on several other platforms. - Also I experimented with alternate macro definitions - in the SHA2_UNROLL_TRANSFORM version (see sha2.slower.c) - and eliminated the T1 temporary variable (the compiler - would of course still use internal temporary storage - during expression evaluation, but I'd hoped the compiler - would be more efficient), but unfortunately under FreeBSD - 4.1.1-STABLE on an x86 platform, the change slowed things - down. -1.0.0b1 to 1.0 RELEASE Fixed an off-by-one implementation bug that affected - SHA-256 when hashed data length L = 55 + 64 * X where X is - either zero or a positive integer, and another (basically - the same bug) bug in SHA-384 and SHA-512 that showed up when - hashed data lengths L = 111 + 128 * X. Thanks to Rogier - van de Pol for sending me test data that revealed the bug. - The fix was very simple (just two tiny changes). Also, - I finally put the files into RCS so future changes will be - easier to manage. The sha2prog.c file was rewritten to - be more useful to me, and I got rid of the old C testing - program and now use a perl script with a subdirectory full - of test data. It's a more flexible test system. - - -LATEST VERSION: - -The latest version and documentation (if any ;) should always be available -on the web at: - - http://www.aarongifford.com/computers/sha.html - - -CONTACT ME: - -I can be reached via email at: - - Aaron Gifford - -Please don't send support questions. I don't have the time to answer and -they'll probably be ignored. Bug fixes, or patches that add something useful -will be gratefully accepted, however. - -If you use this implementation, I would enjoy getting a brief email message -letting me know who you are and what use to which it is being put. There -is no requirement to do so. I just think it would be fun. - - -EXAMPLES: - -Here's an example of compiling and using the sha2 program (in this example -I build it using the unrolled transform version with -O2 optimizations), -and then running the perl testing script: - - cc -O2 -DSHA2_UNROLL_TRANSFORM -Wall -o sha2 sha2prog.c sha2.c - % ./sha2test.pl - - [most of the perl script output deleted for brevity] - - ===== RESULTS (18 VECTOR DATA FILES HASHED) ===== - - HASH TYPE NO. OF TESTS PASSED FAILED - --------- ------------ ------ ------ - SHA-256 18 18 0 - SHA-384 18 18 0 - SHA-512 18 18 0 - ---------------------------------------------- - TOTAL: 54 54 0 - - NO ERRORS! ALL TESTS WERE SUCCESSFUL! - - ALL TEST VECTORS PASSED! - -That's all folks! Have fun! - -Aaron out. - diff --git a/net/ip/tinydtls/sha2/sha2.c b/net/ip/tinydtls/sha2/sha2.c deleted file mode 100644 index d505713d2e12a4c98d64195e8f1ba8e87652f09b..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/sha2.c +++ /dev/null @@ -1,1101 +0,0 @@ -/* - * FILE: sha2.c - * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ - * - * Copyright (c) 2000-2001, Aaron D. Gifford - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $ - */ - -#include "tinydtls.h" -#include "dtls_config.h" -#include /* memcpy()/memset() or bcopy()/bzero() */ -#ifdef HAVE_ASSERT_H -#include /* assert() */ -#else -#ifndef assert -#warning "assertions are disabled" -# define assert(x) -#endif -#endif -#include "sha2.h" - -/* - * ASSERT NOTE: - * Some sanity checking code is included using assert(). On my FreeBSD - * system, this additional code can be removed by compiling with NDEBUG - * defined. Check your own systems manpage on assert() to see how to - * compile WITHOUT the sanity checking code on your system. - * - * UNROLLED TRANSFORM LOOP NOTE: - * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform - * loop version for the hash transform rounds (defined using macros - * later in this file). Either define on the command line, for example: - * - * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c - * - * or define below: - * - * #define SHA2_UNROLL_TRANSFORM - * - */ - - -/*** SHA-256/384/512 Machine Architecture Definitions *****************/ -/* - * BYTE_ORDER NOTE: - * - * Please make sure that your system defines BYTE_ORDER. If your - * architecture is little-endian, make sure it also defines - * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are - * equivilent. - * - * If your system does not define the above, then you can do so by - * hand like this: - * - * #define LITTLE_ENDIAN 1234 - * #define BIG_ENDIAN 4321 - * - * And for little-endian machines, add: - * - * #define BYTE_ORDER LITTLE_ENDIAN - * - * Or for big-endian machines: - * - * #define BYTE_ORDER BIG_ENDIAN - * - * The FreeBSD machine this was written on defines BYTE_ORDER - * appropriately by including (which in turn includes - * where the appropriate definitions are actually - * made). - */ - -/* bergmann: define LITTLE_ENDIAN and BIG_ENDIAN to ease autoconf: */ -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 1234 -#endif -#ifndef BIG_ENDIAN -#define BIG_ENDIAN 4321 -#endif - -#ifndef BYTE_ORDER -# if defined(WORDS_BIGENDIAN) || (defined(AC_APPLE_UNIVERSAL_BUILD) && defined(__BIG_ENDIAN__)) -# define BYTE_ORDER BIG_ENDIAN -# else /* WORDS_BIGENDIAN */ -# define BYTE_ORDER LITTLE_ENDIAN -# endif -#endif - -#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) -#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN -#endif - -/* - * Define the followingsha2_* types to types of the correct length on - * the native archtecture. Most BSD systems and Linux define u_intXX_t - * types. Machines with very recent ANSI C headers, can use the - * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H - * during compile or in the sha.h header file. - * - * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t - * will need to define these three typedefs below (and the appropriate - * ones in sha.h too) by hand according to their system architecture. - * - * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t - * types and pointing out recent ANSI C support for uintXX_t in inttypes.h. - */ -#ifdef SHA2_USE_INTTYPES_H - -typedef uint8_t sha2_byte; /* Exactly 1 byte */ -typedef uint32_t sha2_word32; /* Exactly 4 bytes */ -typedef uint64_t sha2_word64 MAY_ALIAS; /* Exactly 8 bytes */ - -#else /* SHA2_USE_INTTYPES_H */ - -typedef u_int8_t sha2_byte; /* Exactly 1 byte */ -typedef u_int32_t sha2_word32; /* Exactly 4 bytes */ -typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ - -#endif /* SHA2_USE_INTTYPES_H */ - - -/*** SHA-256/384/512 Various Length Definitions ***********************/ -/* NOTE: Most of these are in sha2.h */ -#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) -#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) -#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) - - -/*** ENDIAN REVERSAL MACROS *******************************************/ -#if BYTE_ORDER == LITTLE_ENDIAN -#define REVERSE32(w,x) { \ - sha2_word32 tmp = (w); \ - tmp = (tmp >> 16) | (tmp << 16); \ - (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ -} -#define REVERSE64(w,x) { \ - sha2_word64 tmp = (w); \ - tmp = (tmp >> 32) | (tmp << 32); \ - tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ - ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ - (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ - ((tmp & 0x0000ffff0000ffffULL) << 16); \ -} -#endif /* BYTE_ORDER == LITTLE_ENDIAN */ - -/* - * Macro for incrementally adding the unsigned 64-bit integer n to the - * unsigned 128-bit integer (represented using a two-element array of - * 64-bit words): - */ -#define ADDINC128(w,n) { \ - (w)[0] += (sha2_word64)(n); \ - if ((w)[0] < (n)) { \ - (w)[1]++; \ - } \ -} - -/* - * Macros for copying blocks of memory and for zeroing out ranges - * of memory. Using these macros makes it easy to switch from - * using memset()/memcpy() and using bzero()/bcopy(). - * - * Please define either SHA2_USE_MEMSET_MEMCPY or define - * SHA2_USE_BZERO_BCOPY depending on which function set you - * choose to use: - */ -#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY) -/* Default to memset()/memcpy() if no option is specified */ -#define SHA2_USE_MEMSET_MEMCPY 1 -#endif -#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY) -/* Abort with an error if BOTH options are defined */ -#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both! -#endif - -#ifdef SHA2_USE_MEMSET_MEMCPY -#define MEMSET_BZERO(p,l) memset((p), 0, (l)) -#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l)) -#endif -#ifdef SHA2_USE_BZERO_BCOPY -#define MEMSET_BZERO(p,l) bzero((p), (l)) -#define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l)) -#endif - - -/*** THE SIX LOGICAL FUNCTIONS ****************************************/ -/* - * Bit shifting and rotation (used by the six SHA-XYZ logical functions: - * - * NOTE: The naming of R and S appears backwards here (R is a SHIFT and - * S is a ROTATION) because the SHA-256/384/512 description document - * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this - * same "backwards" definition. - */ -/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ -#define R(b,x) ((x) >> (b)) -/* 32-bit Rotate-right (used in SHA-256): */ -#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) -/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ -#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) - -/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ -#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) -#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) - -/* Four of six logical functions used in SHA-256: */ -#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) -#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) -#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) -#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) - -/* Four of six logical functions used in SHA-384 and SHA-512: */ -#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) -#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) -#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) -#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) - -/*** INTERNAL FUNCTION PROTOTYPES *************************************/ -/* NOTE: These should not be accessed directly from outside this - * library -- they are intended for private internal visibility/use - * only. - */ -void SHA512_Last(SHA512_CTX*); -void SHA256_Transform(SHA256_CTX*, const sha2_word32*); -void SHA512_Transform(SHA512_CTX*, const sha2_word64*); - -#ifdef WITH_SHA256 -/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ -/* Hash constant words K for SHA-256: */ -const static sha2_word32 K256[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, - 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, - 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, - 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, - 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, - 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, - 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, - 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, - 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, - 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, - 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, - 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, - 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL -}; - -/* Initial hash value H for SHA-256: */ -const static sha2_word32 sha256_initial_hash_value[8] = { - 0x6a09e667UL, - 0xbb67ae85UL, - 0x3c6ef372UL, - 0xa54ff53aUL, - 0x510e527fUL, - 0x9b05688cUL, - 0x1f83d9abUL, - 0x5be0cd19UL -}; -#endif - -#if defined(WITH_SHA384) || defined(WITH_SHA512) -/* Hash constant words K for SHA-384 and SHA-512: */ -const static sha2_word64 K512[80] = { - 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, - 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, - 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, - 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, - 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, - 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, - 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, - 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, - 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, - 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, - 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, - 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, - 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, - 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, - 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, - 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, - 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, - 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, - 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, - 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, - 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, - 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, - 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, - 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, - 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, - 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, - 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, - 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, - 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, - 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, - 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, - 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, - 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, - 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, - 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, - 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, - 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, - 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, - 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, - 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL -}; -#endif - -#ifdef WITH_SHA384 -/* Initial hash value H for SHA-384 */ -const static sha2_word64 sha384_initial_hash_value[8] = { - 0xcbbb9d5dc1059ed8ULL, - 0x629a292a367cd507ULL, - 0x9159015a3070dd17ULL, - 0x152fecd8f70e5939ULL, - 0x67332667ffc00b31ULL, - 0x8eb44a8768581511ULL, - 0xdb0c2e0d64f98fa7ULL, - 0x47b5481dbefa4fa4ULL -}; -#endif - -#ifdef WITH_SHA512 -/* Initial hash value H for SHA-512 */ -const static sha2_word64 sha512_initial_hash_value[8] = { - 0x6a09e667f3bcc908ULL, - 0xbb67ae8584caa73bULL, - 0x3c6ef372fe94f82bULL, - 0xa54ff53a5f1d36f1ULL, - 0x510e527fade682d1ULL, - 0x9b05688c2b3e6c1fULL, - 0x1f83d9abfb41bd6bULL, - 0x5be0cd19137e2179ULL -}; -#endif - -/* - * Constant used by SHA256/384/512_End() functions for converting the - * digest to a readable hexadecimal character string: - */ -static const char *sha2_hex_digits = "0123456789abcdef"; - - -/*** SHA-256: *********************************************************/ -#ifdef WITH_SHA256 -void SHA256_Init(SHA256_CTX* context) { - if (context == (SHA256_CTX*)0) { - return; - } - MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH); - context->bitcount = 0; -} - -#ifdef SHA2_UNROLL_TRANSFORM - -/* Unrolled SHA-256 round macros: */ - -#if BYTE_ORDER == LITTLE_ENDIAN - -#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ - REVERSE32(*data++, W256[j]); \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ - K256[j] + W256[j]; \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ - - -#else /* BYTE_ORDER == LITTLE_ENDIAN */ - -#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ - K256[j] + (W256[j] = *data++); \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ - -#endif /* BYTE_ORDER == LITTLE_ENDIAN */ - -#define ROUND256(a,b,c,d,e,f,g,h) \ - s0 = W256[(j+1)&0x0f]; \ - s0 = sigma0_256(s0); \ - s1 = W256[(j+14)&0x0f]; \ - s1 = sigma1_256(s1); \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ - (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ - -void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { - sha2_word32 a, b, c, d, e, f, g, h, s0, s1; - sha2_word32 T1, *W256; - int j; - - W256 = (sha2_word32*)context->buffer; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { - /* Rounds 0 to 15 (unrolled): */ - ROUND256_0_TO_15(a,b,c,d,e,f,g,h); - ROUND256_0_TO_15(h,a,b,c,d,e,f,g); - ROUND256_0_TO_15(g,h,a,b,c,d,e,f); - ROUND256_0_TO_15(f,g,h,a,b,c,d,e); - ROUND256_0_TO_15(e,f,g,h,a,b,c,d); - ROUND256_0_TO_15(d,e,f,g,h,a,b,c); - ROUND256_0_TO_15(c,d,e,f,g,h,a,b); - ROUND256_0_TO_15(b,c,d,e,f,g,h,a); - } while (j < 16); - - /* Now for the remaining rounds to 64: */ - do { - ROUND256(a,b,c,d,e,f,g,h); - ROUND256(h,a,b,c,d,e,f,g); - ROUND256(g,h,a,b,c,d,e,f); - ROUND256(f,g,h,a,b,c,d,e); - ROUND256(e,f,g,h,a,b,c,d); - ROUND256(d,e,f,g,h,a,b,c); - ROUND256(c,d,e,f,g,h,a,b); - ROUND256(b,c,d,e,f,g,h,a); - } while (j < 64); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = 0; -} - -#else /* SHA2_UNROLL_TRANSFORM */ - -void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { - sha2_word32 a, b, c, d, e, f, g, h, s0, s1; - sha2_word32 T1, T2, *W256; - int j; - - W256 = (sha2_word32*)context->buffer; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { -#if BYTE_ORDER == LITTLE_ENDIAN - /* Copy data while converting to host byte order */ - REVERSE32(*data++,W256[j]); - /* Apply the SHA-256 compression function to update a..h */ - T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; -#else /* BYTE_ORDER == LITTLE_ENDIAN */ - /* Apply the SHA-256 compression function to update a..h with copy */ - T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); -#endif /* BYTE_ORDER == LITTLE_ENDIAN */ - T2 = Sigma0_256(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 16); - - do { - /* Part of the message block expansion: */ - s0 = W256[(j+1)&0x0f]; - s0 = sigma0_256(s0); - s1 = W256[(j+14)&0x0f]; - s1 = sigma1_256(s1); - - /* Apply the SHA-256 compression function to update a..h */ - T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + - (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); - T2 = Sigma0_256(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 64); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = T2 = 0; -} - -#endif /* SHA2_UNROLL_TRANSFORM */ - -void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace, usedspace; - - if (len == 0) { - /* Calling with no data is valid - we do nothing */ - return; - } - - /* Sanity check: */ - assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); - - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; - if (usedspace > 0) { - /* Calculate how much free space is available in the buffer */ - freespace = SHA256_BLOCK_LENGTH - usedspace; - - if (len >= freespace) { - /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); - context->bitcount += freespace << 3; - len -= freespace; - data += freespace; - SHA256_Transform(context, (sha2_word32*)context->buffer); - } else { - /* The buffer is not yet full */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, len); - context->bitcount += len << 3; - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA256_BLOCK_LENGTH) { - /* Process as many complete blocks as we can */ - SHA256_Transform(context, (sha2_word32*)data); - context->bitcount += SHA256_BLOCK_LENGTH << 3; - len -= SHA256_BLOCK_LENGTH; - data += SHA256_BLOCK_LENGTH; - } - if (len > 0) { - /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - context->bitcount += len << 3; - } - /* Clean up: */ - usedspace = freespace = 0; -} - -void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { - sha2_word32 *d = (sha2_word32*)digest; - unsigned int usedspace; - - /* Sanity check: */ - assert(context != (SHA256_CTX*)0); - - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert FROM host byte order */ - REVERSE64(context->bitcount,context->bitcount); -#endif - if (usedspace > 0) { - /* Begin padding with a 1 bit: */ - context->buffer[usedspace++] = 0x80; - - if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { - /* Set-up for the last transform: */ - MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); - } else { - if (usedspace < SHA256_BLOCK_LENGTH) { - MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); - } - /* Do second-to-last transform: */ - SHA256_Transform(context, (sha2_word32*)context->buffer); - - /* And set-up for the last transform: */ - MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); - } - } else { - /* Set-up for the last transform: */ - MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); - - /* Begin padding with a 1 bit: */ - *context->buffer = 0x80; - } - /* Set the bit count: */ - *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; - - /* Final transform: */ - SHA256_Transform(context, (sha2_word32*)context->buffer); - -#if BYTE_ORDER == LITTLE_ENDIAN - { - /* Convert TO host byte order */ - int j; - for (j = 0; j < 8; j++) { - REVERSE32(context->state[j],context->state[j]); - *d++ = context->state[j]; - } - } -#else - MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH); -#endif - } - - /* Clean up state data: */ - MEMSET_BZERO(context, sizeof(*context)); - usedspace = 0; -} - -char *SHA256_End(SHA256_CTX* context, char buffer[]) { - sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; - int i; - - /* Sanity check: */ - assert(context != (SHA256_CTX*)0); - - if (buffer != (char*)0) { - SHA256_Final(digest, context); - - for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - MEMSET_BZERO(context, sizeof(*context)); - } - MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH); - return buffer; -} - -char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { - SHA256_CTX context; - - SHA256_Init(&context); - SHA256_Update(&context, data, len); - return SHA256_End(&context, digest); -} -#endif - -/*** SHA-512: *********************************************************/ -#ifdef WITH_SHA512 -void SHA512_Init(SHA512_CTX* context) { - if (context == (SHA512_CTX*)0) { - return; - } - MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; -} - -#ifdef SHA2_UNROLL_TRANSFORM - -/* Unrolled SHA-512 round macros: */ -#if BYTE_ORDER == LITTLE_ENDIAN - -#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ - REVERSE64(*data++, W512[j]); \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ - K512[j] + W512[j]; \ - (d) += T1, \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ - j++ - - -#else /* BYTE_ORDER == LITTLE_ENDIAN */ - -#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ - K512[j] + (W512[j] = *data++); \ - (d) += T1; \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ - j++ - -#endif /* BYTE_ORDER == LITTLE_ENDIAN */ - -#define ROUND512(a,b,c,d,e,f,g,h) \ - s0 = W512[(j+1)&0x0f]; \ - s0 = sigma0_512(s0); \ - s1 = W512[(j+14)&0x0f]; \ - s1 = sigma1_512(s1); \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ - (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ - (d) += T1; \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ - j++ - -void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { - sha2_word64 a, b, c, d, e, f, g, h, s0, s1; - sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; - int j; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { - ROUND512_0_TO_15(a,b,c,d,e,f,g,h); - ROUND512_0_TO_15(h,a,b,c,d,e,f,g); - ROUND512_0_TO_15(g,h,a,b,c,d,e,f); - ROUND512_0_TO_15(f,g,h,a,b,c,d,e); - ROUND512_0_TO_15(e,f,g,h,a,b,c,d); - ROUND512_0_TO_15(d,e,f,g,h,a,b,c); - ROUND512_0_TO_15(c,d,e,f,g,h,a,b); - ROUND512_0_TO_15(b,c,d,e,f,g,h,a); - } while (j < 16); - - /* Now for the remaining rounds up to 79: */ - do { - ROUND512(a,b,c,d,e,f,g,h); - ROUND512(h,a,b,c,d,e,f,g); - ROUND512(g,h,a,b,c,d,e,f); - ROUND512(f,g,h,a,b,c,d,e); - ROUND512(e,f,g,h,a,b,c,d); - ROUND512(d,e,f,g,h,a,b,c); - ROUND512(c,d,e,f,g,h,a,b); - ROUND512(b,c,d,e,f,g,h,a); - } while (j < 80); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = 0; -} - -#else /* SHA2_UNROLL_TRANSFORM */ - -void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { - sha2_word64 a, b, c, d, e, f, g, h, s0, s1; - sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; - int j; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - REVERSE64(*data++, W512[j]); - /* Apply the SHA-512 compression function to update a..h */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; -#else /* BYTE_ORDER == LITTLE_ENDIAN */ - /* Apply the SHA-512 compression function to update a..h with copy */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); -#endif /* BYTE_ORDER == LITTLE_ENDIAN */ - T2 = Sigma0_512(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 16); - - do { - /* Part of the message block expansion: */ - s0 = W512[(j+1)&0x0f]; - s0 = sigma0_512(s0); - s1 = W512[(j+14)&0x0f]; - s1 = sigma1_512(s1); - - /* Apply the SHA-512 compression function to update a..h */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + - (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); - T2 = Sigma0_512(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 80); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = T2 = 0; -} - -#endif /* SHA2_UNROLL_TRANSFORM */ - -void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace, usedspace; - - if (len == 0) { - /* Calling with no data is valid - we do nothing */ - return; - } - - /* Sanity check: */ - assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); - - usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; - if (usedspace > 0) { - /* Calculate how much free space is available in the buffer */ - freespace = SHA512_BLOCK_LENGTH - usedspace; - - if (len >= freespace) { - /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); - ADDINC128(context->bitcount, freespace << 3); - len -= freespace; - data += freespace; - SHA512_Transform(context, (sha2_word64*)context->buffer); - } else { - /* The buffer is not yet full */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, len); - ADDINC128(context->bitcount, len << 3); - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA512_BLOCK_LENGTH) { - /* Process as many complete blocks as we can */ - SHA512_Transform(context, (sha2_word64*)data); - ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); - len -= SHA512_BLOCK_LENGTH; - data += SHA512_BLOCK_LENGTH; - } - if (len > 0) { - /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - ADDINC128(context->bitcount, len << 3); - } - /* Clean up: */ - usedspace = freespace = 0; -} - -void SHA512_Last(SHA512_CTX* context) { - unsigned int usedspace; - - usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert FROM host byte order */ - REVERSE64(context->bitcount[0],context->bitcount[0]); - REVERSE64(context->bitcount[1],context->bitcount[1]); -#endif - if (usedspace > 0) { - /* Begin padding with a 1 bit: */ - context->buffer[usedspace++] = 0x80; - - if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { - /* Set-up for the last transform: */ - MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); - } else { - if (usedspace < SHA512_BLOCK_LENGTH) { - MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); - } - /* Do second-to-last transform: */ - SHA512_Transform(context, (sha2_word64*)context->buffer); - - /* And set-up for the last transform: */ - MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); - } - } else { - /* Prepare for final transform: */ - MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); - - /* Begin padding with a 1 bit: */ - *context->buffer = 0x80; - } - /* Store the length of input data (in bits): */ - *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; - *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; - - /* Final transform: */ - SHA512_Transform(context, (sha2_word64*)context->buffer); -} - -void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { - sha2_word64 *d = (sha2_word64*)digest; - - /* Sanity check: */ - assert(context != (SHA512_CTX*)0); - - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - SHA512_Last(context); - - /* Save the hash data for output: */ -#if BYTE_ORDER == LITTLE_ENDIAN - { - /* Convert TO host byte order */ - int j; - for (j = 0; j < 8; j++) { - REVERSE64(context->state[j],context->state[j]); - *d++ = context->state[j]; - } - } -#else - MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); -#endif - } - - /* Zero out state data */ - MEMSET_BZERO(context, sizeof(context)); -} - -char *SHA512_End(SHA512_CTX* context, char buffer[]) { - sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; - int i; - - /* Sanity check: */ - assert(context != (SHA512_CTX*)0); - - if (buffer != (char*)0) { - SHA512_Final(digest, context); - - for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - MEMSET_BZERO(context, sizeof(context)); - } - MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); - return buffer; -} - -char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { - SHA512_CTX context; - - SHA512_Init(&context); - SHA512_Update(&context, data, len); - return SHA512_End(&context, digest); -} -#endif - -/*** SHA-384: *********************************************************/ -#ifdef WITH_SHA384 -void SHA384_Init(SHA384_CTX* context) { - if (context == (SHA384_CTX*)0) { - return; - } - MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; -} - -void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { - SHA512_Update((SHA512_CTX*)context, data, len); -} - -void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { - sha2_word64 *d = (sha2_word64*)digest; - - /* Sanity check: */ - assert(context != (SHA384_CTX*)0); - - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - SHA512_Last((SHA512_CTX*)context); - - /* Save the hash data for output: */ -#if BYTE_ORDER == LITTLE_ENDIAN - { - /* Convert TO host byte order */ - int j; - for (j = 0; j < 6; j++) { - REVERSE64(context->state[j],context->state[j]); - *d++ = context->state[j]; - } - } -#else - MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH); -#endif - } - - /* Zero out state data */ - MEMSET_BZERO(context, sizeof(context)); -} - -char *SHA384_End(SHA384_CTX* context, char buffer[]) { - sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; - int i; - - /* Sanity check: */ - assert(context != (SHA384_CTX*)0); - - if (buffer != (char*)0) { - SHA384_Final(digest, context); - - for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - MEMSET_BZERO(context, sizeof(context)); - } - MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); - return buffer; -} - -char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { - SHA384_CTX context; - - SHA384_Init(&context); - SHA384_Update(&context, data, len); - return SHA384_End(&context, digest); -} -#endif diff --git a/net/ip/tinydtls/sha2/sha2.h b/net/ip/tinydtls/sha2/sha2.h deleted file mode 100644 index d34ea357750ce4b894e69badb4aebf33042bffdf..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/sha2.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - * FILE: sha2.h - * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ - * - * Copyright (c) 2000-2001, Aaron D. Gifford - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $ - */ - -#ifndef __SHA2_H__ -#define __SHA2_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define SHA2_USE_INTTYPES_H 1 - -/* - * Import u_intXX_t size_t type definitions from system headers. You - * may need to change this, or define these things yourself in this - * file. - */ -#include - -#ifdef SHA2_USE_INTTYPES_H - -#include - -#endif /* SHA2_USE_INTTYPES_H */ - - -/*** SHA-256/384/512 Various Length Definitions ***********************/ -#define SHA256_BLOCK_LENGTH 64 -#define SHA256_DIGEST_LENGTH 32 -#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) -#define SHA384_BLOCK_LENGTH 128 -#define SHA384_DIGEST_LENGTH 48 -#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) -#define SHA512_BLOCK_LENGTH 128 -#define SHA512_DIGEST_LENGTH 64 -#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) - - -/*** SHA-256/384/512 Context Structures *******************************/ -/* NOTE: If your architecture does not define either u_intXX_t types or - * uintXX_t (from inttypes.h), you may need to define things by hand - * for your system: - */ -#if 0 -typedef unsigned char u_int8_t; /* 1-byte (8-bits) */ -typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */ -typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ -#endif -/* - * Most BSD systems already define u_intXX_t types, as does Linux. - * Some systems, however, like Compaq's Tru64 Unix instead can use - * uintXX_t types defined by very recent ANSI C standards and included - * in the file: - * - * #include - * - * If you choose to use then please define: - * - * #define SHA2_USE_INTTYPES_H - * - * Or on the command line during compile: - * - * cc -DSHA2_USE_INTTYPES_H ... - */ -#ifdef SHA2_USE_INTTYPES_H - -typedef struct _SHA256_CTX { - uint32_t state[8]; - uint64_t bitcount; - uint8_t buffer[SHA256_BLOCK_LENGTH]; -} SHA256_CTX; -typedef struct _SHA512_CTX { - uint64_t state[8]; - uint64_t bitcount[2]; - uint8_t buffer[SHA512_BLOCK_LENGTH]; -} SHA512_CTX; - -#else /* SHA2_USE_INTTYPES_H */ - -typedef struct _SHA256_CTX { - u_int32_t state[8]; - u_int64_t bitcount; - u_int8_t buffer[SHA256_BLOCK_LENGTH]; -} SHA256_CTX; -typedef struct _SHA512_CTX { - u_int64_t state[8]; - u_int64_t bitcount[2]; - u_int8_t buffer[SHA512_BLOCK_LENGTH]; -} SHA512_CTX; - -#endif /* SHA2_USE_INTTYPES_H */ - -typedef SHA512_CTX SHA384_CTX; - - -/*** SHA-256/384/512 Function Prototypes ******************************/ -#ifndef NOPROTO -#ifdef SHA2_USE_INTTYPES_H - -#ifdef WITH_SHA256 -void SHA256_Init(SHA256_CTX *); -void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t); -void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); -char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); -char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); -#endif - -#ifdef WITH_SHA384 -void SHA384_Init(SHA384_CTX*); -void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t); -void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); -char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); -char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); -#endif - -#ifdef WITH_SHA512 -void SHA512_Init(SHA512_CTX*); -void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t); -void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); -char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); -char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); -#endif - -#else /* SHA2_USE_INTTYPES_H */ - -#ifdef WITH_SHA256 -void SHA256_Init(SHA256_CTX *); -void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t); -void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); -char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); -char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); -#endif - -#ifdef WITH_SHA384 -void SHA384_Init(SHA384_CTX*); -void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t); -void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); -char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); -char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); -#endif - -#ifdef WITH_SHA512 -void SHA512_Init(SHA512_CTX*); -void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t); -void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); -char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); -char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); -#endif - -#endif /* SHA2_USE_INTTYPES_H */ - -#else /* NOPROTO */ - -#ifdef WITH_SHA256 -void SHA256_Init(); -void SHA256_Update(); -void SHA256_Final(); -char* SHA256_End(); -char* SHA256_Data(); -#endif - -#ifdef WITH_SHA384 -void SHA384_Init(); -void SHA384_Update(); -void SHA384_Final(); -char* SHA384_End(); -char* SHA384_Data(); -#endif - -#ifdef WITH_SHA512 -void SHA512_Init(); -void SHA512_Update(); -void SHA512_Final(); -char* SHA512_End(); -char* SHA512_Data(); -#endif - -#endif /* NOPROTO */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __SHA2_H__ */ - diff --git a/net/ip/tinydtls/sha2/sha2prog.c b/net/ip/tinydtls/sha2/sha2prog.c deleted file mode 100644 index 8d9d6aee4b27367a6968cc4d0a6ea65cdf491695..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/sha2prog.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * FILE: sha2prog.c - * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ - * - * Copyright (c) 2000-2001, Aaron D. Gifford - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: sha2prog.c,v 1.1 2001/11/08 00:02:11 adg Exp adg $ - */ - -#include -#include -#include -#include -#include - -#include "sha2.h" - -void usage(char *prog, char *msg) { - fprintf(stderr, "%s\nUsage:\t%s [options] []\nOptions:\n\t-256\tGenerate SHA-256 hash\n\t-384\tGenerate SHA-284 hash\n\t-512\tGenerate SHA-512 hash\n\t-ALL\tGenerate all three hashes\n\t-q\tQuiet mode - only output hexadecimal hashes, one per line\n\n", msg, prog); - exit(-1); -} - -#define BUFLEN 16384 - -int main(int argc, char **argv) { - int kl, l, fd, ac; - int quiet = 0, hash = 0; - char *av, *file = (char*)0; - FILE *IN = (FILE*)0; - SHA256_CTX ctx256; - SHA384_CTX ctx384; - SHA512_CTX ctx512; - unsigned char buf[BUFLEN]; - - SHA256_Init(&ctx256); - SHA384_Init(&ctx384); - SHA512_Init(&ctx512); - - /* Read data from STDIN by default */ - fd = fileno(stdin); - - ac = 1; - while (ac < argc) { - if (*argv[ac] == '-') { - av = argv[ac] + 1; - if (!strcmp(av, "q")) { - quiet = 1; - } else if (!strcmp(av, "256")) { - hash |= 1; - } else if (!strcmp(av, "384")) { - hash |= 2; - } else if (!strcmp(av, "512")) { - hash |= 4; - } else if (!strcmp(av, "ALL")) { - hash = 7; - } else { - usage(argv[0], "Invalid option."); - } - ac++; - } else { - file = argv[ac++]; - if (ac != argc) { - usage(argv[0], "Too many arguments."); - } - if ((IN = fopen(file, "r")) == NULL) { - perror(argv[0]); - exit(-1); - } - fd = fileno(IN); - } - } - if (hash == 0) - hash = 7; /* Default to ALL */ - - kl = 0; - while ((l = read(fd,buf,BUFLEN)) > 0) { - kl += l; - SHA256_Update(&ctx256, (unsigned char*)buf, l); - SHA384_Update(&ctx384, (unsigned char*)buf, l); - SHA512_Update(&ctx512, (unsigned char*)buf, l); - } - if (file) { - fclose(IN); - } - - if (hash & 1) { - SHA256_End(&ctx256, buf); - if (!quiet) - printf("SHA-256 (%s) = ", file); - printf("%s\n", buf); - } - if (hash & 2) { - SHA384_End(&ctx384, buf); - if (!quiet) - printf("SHA-384 (%s) = ", file); - printf("%s\n", buf); - } - if (hash & 4) { - SHA512_End(&ctx512, buf); - if (!quiet) - printf("SHA-512 (%s) = ", file); - printf("%s\n", buf); - } - - return 1; -} - diff --git a/net/ip/tinydtls/sha2/sha2speed.c b/net/ip/tinydtls/sha2/sha2speed.c deleted file mode 100644 index 2e135750fa25cfa43851de03215ab323935ec417..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/sha2speed.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * FILE: sha2speed.c - * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ - * - * Copyright (c) 2000-2001, Aaron D. Gifford - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: sha2speed.c,v 1.1 2001/11/08 00:02:23 adg Exp adg $ - */ - -#include -#include -#include -#include - -#include "sha2.h" - -#define BUFSIZE 16384 - -void usage(char *prog) { - fprintf(stderr, "Usage:\t%s [] [] []\n", prog); - exit(-1); -} - -void printspeed(char *caption, unsigned long bytes, double time) { - if (bytes / 1073741824UL > 0) { - printf("%s %.4f sec (%.3f GBps)\n", caption, time, (double)bytes/1073741824UL/time); - } else if (bytes / 1048576 > 0) { - printf("%s %.4f (%.3f MBps)\n", caption, time, (double)bytes/1048576/time); - } else if (bytes / 1024 > 0) { - printf("%s %.4f (%.3f KBps)\n", caption, time, (double)bytes/1024/time); - } else { - printf("%s %.4f (%f Bps)\n", caption, time, (double)bytes/time); - } -} - - -int main(int argc, char **argv) { - SHA256_CTX c256; - SHA384_CTX c384; - SHA512_CTX c512; - char buf[BUFSIZE]; - char md[SHA512_DIGEST_STRING_LENGTH]; - int bytes, blocks, rep, i, j; - struct timeval start, end; - double t, ave256, ave384, ave512; - double best256, best384, best512; - - if (argc > 4) { - usage(argv[0]); - } - - /* Default to 1024 16K blocks (16 MB) */ - bytes = 1024 * 1024 * 16; - if (argc > 1) { - blocks = atoi(argv[1]); - } - blocks = bytes / BUFSIZE; - - /* Default to 10 repetitions */ - rep = 10; - if (argc > 2) { - rep = atoi(argv[2]); - } - - /* Set up the input data */ - if (argc > 3) { - memset(buf, atoi(argv[2]), BUFSIZE); - } else { - memset(buf, 0xb7, BUFSIZE); - } - - ave256 = ave384 = ave512 = 0; - best256 = best384 = best512 = 100000; - for (i = 0; i < rep; i++) { - SHA256_Init(&c256); - SHA384_Init(&c384); - SHA512_Init(&c512); - - gettimeofday(&start, (struct timezone*)0); - for (j = 0; j < blocks; j++) { - SHA256_Update(&c256, (unsigned char*)buf, BUFSIZE); - } - if (bytes % BUFSIZE) { - SHA256_Update(&c256, (unsigned char*)buf, bytes % BUFSIZE); - } - SHA256_End(&c256, md); - gettimeofday(&end, (struct timezone*)0); - t = ((end.tv_sec - start.tv_sec) * 1000000.0 + (end.tv_usec - start.tv_usec)) / 1000000.0; - ave256 += t; - if (t < best256) { - best256 = t; - } - printf("SHA-256[%d] (%.4f/%.4f/%.4f seconds) = 0x%s\n", i+1, t, ave256/(i+1), best256, md); - - gettimeofday(&start, (struct timezone*)0); - for (j = 0; j < blocks; j++) { - SHA384_Update(&c384, (unsigned char*)buf, BUFSIZE); - } - if (bytes % BUFSIZE) { - SHA384_Update(&c384, (unsigned char*)buf, bytes % BUFSIZE); - } - SHA384_End(&c384, md); - gettimeofday(&end, (struct timezone*)0); - t = ((end.tv_sec - start.tv_sec) * 1000000.0 + (end.tv_usec - start.tv_usec)) / 1000000.0; - ave384 += t; - if (t < best384) { - best384 = t; - } - printf("SHA-384[%d] (%.4f/%.4f/%.4f seconds) = 0x%s\n", i+1, t, ave384/(i+1), best384, md); - - gettimeofday(&start, (struct timezone*)0); - for (j = 0; j < blocks; j++) { - SHA512_Update(&c512, (unsigned char*)buf, BUFSIZE); - } - if (bytes % BUFSIZE) { - SHA512_Update(&c512, (unsigned char*)buf, bytes % BUFSIZE); - } - SHA512_End(&c512, md); - gettimeofday(&end, (struct timezone*)0); - t = ((end.tv_sec - start.tv_sec) * 1000000.0 + (end.tv_usec - start.tv_usec)) / 1000000.0; - ave512 += t; - if (t < best512) { - best512 = t; - } - printf("SHA-512[%d] (%.4f/%.4f/%.4f seconds) = 0x%s\n", i+1, t, ave512/(i+1), best512, md); - } - ave256 /= rep; - ave384 /= rep; - ave512 /= rep; - printf("\nTEST RESULTS SUMMARY:\nTEST REPETITIONS: %d\n", rep); - if (bytes / 1073741824UL > 0) { - printf("TEST SET SIZE: %.3f GB\n", (double)bytes/1073741824UL); - } else if (bytes / 1048576 > 0) { - printf("TEST SET SIZE: %.3f MB\n", (double)bytes/1048576); - } else if (bytes /1024 > 0) { - printf("TEST SET SIZE: %.3f KB\n", (double)bytes/1024); - } else { - printf("TEST SET SIZE: %d B\n", bytes); - } - printspeed("SHA-256 average:", bytes, ave256); - printspeed("SHA-256 best: ", bytes, best256); - printspeed("SHA-384 average:", bytes, ave384); - printspeed("SHA-384 best: ", bytes, best384); - printspeed("SHA-512 average:", bytes, ave512); - printspeed("SHA-512 best: ", bytes, best512); - - return 1; -} - diff --git a/net/ip/tinydtls/sha2/sha2test.pl b/net/ip/tinydtls/sha2/sha2test.pl deleted file mode 100755 index dc884d8c17df18f250cd643a3437a2d21336578c..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/sha2test.pl +++ /dev/null @@ -1,358 +0,0 @@ -#!/usr/bin/perl -# -# FILE: sha2test.pl -# AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ -# -# Copyright (c) 2001, Aaron D. Gifford -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the names of contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $Id: sha2test.pl,v 1.1 2001/11/08 00:02:37 adg Exp adg $ -# - -sub usage { - my ($err) = shift(@_); - - print <] [ [ ...]] - -Options: - -256 Use SHA-256 hashes during testing - -384 Use SHA-384 hashes during testing - -512 Use SHA-512 hashes during testing - -ALL Use all three hashes during testing - -c256 Specify a command to execute to generate a - SHA-256 hash. Be sure to include a '%' - character which will be replaced by the - test vector data filename containing the - data to be hashed. This command implies - the -256 option. - -c384 Specify a command to execute to generate a - SHA-384 hash. See above. Implies -384. - -c512 Specify a command to execute to generate a - SHA-512 hash. See above. Implies -512. - -cALL Specify a command to execute that will - generate all three hashes at once and output - the data in hexadecimal. See above for - information about the . - This option implies the -ALL option, and - also overrides any other command options if - present. - -By default, this program expects to execute the command ./sha2 within the -current working directory to generate all hashes. If no test vector -information files are specified, this program expects to read a series of -files ending in ".info" within a subdirectory of the current working -directory called "testvectors". - -EOM - exit(-1); -} - -$c256 = $c384 = $c512 = $cALL = ""; -$hashes = 0; -@FILES = (); - -# Read all command-line options and files: -while ($opt = shift(@ARGV)) { - if ($opt =~ s/^\-//) { - if ($opt eq "256") { - $hashes |= 1; - } elsif ($opt eq "384") { - $hashes |= 2; - } elsif ($opt eq "512") { - $hashes |= 4; - } elsif ($opt =~ /^ALL$/i) { - $hashes = 7; - } elsif ($opt =~ /^c256$/i) { - $hashes |= 1; - $opt = $c256 = shift(@ARGV); - $opt =~ s/\s+.*$//; - if (!$c256 || $c256 !~ /\%/ || !-x $opt) { - usage("Missing or invalid command specification for option -c256: $opt\n"); - } - } elsif ($opt =~ /^c384$/i) { - $hashes |= 2; - $opt = $c384 = shift(@ARGV); - $opt =~ s/\s+.*$//; - if (!$c384 || $c384 !~ /\%/ || !-x $opt) { - usage("Missing or invalid command specification for option -c384: $opt\n"); - } - } elsif ($opt =~ /^c512$/i) { - $hashes |= 4; - $opt = $c512 = shift(@ARGV); - $opt =~ s/\s+.*$//; - if (!$c512 || $c512 !~ /\%/ || !-x $opt) { - usage("Missing or invalid command specification for option -c512: $opt\n"); - } - } elsif ($opt =~ /^cALL$/i) { - $hashes = 7; - $opt = $cALL = shift(@ARGV); - $opt =~ s/\s+.*$//; - if (!$cALL || $cALL !~ /\%/ || !-x $opt) { - usage("Missing or invalid command specification for option -cALL: $opt\n"); - } - } else { - usage("Unknown/invalid option '$opt'\n"); - } - } else { - usage("Invalid, nonexistent, or unreadable file '$opt': $!\n") if (!-f $opt); - push(@FILES, $opt); - } -} - -# Set up defaults: -if (!$cALL && !$c256 && !$c384 && !$c512) { - $cALL = "./sha2 -ALL %"; - usage("Required ./sha2 binary executable not found.\n") if (!-x "./sha2"); -} -$hashes = 7 if (!$hashes); - -# Do some sanity checks: -usage("No command was supplied to generate SHA-256 hashes.\n") if ($hashes & 1 == 1 && !$cALL && !$c256); -usage("No command was supplied to generate SHA-384 hashes.\n") if ($hashes & 2 == 2 && !$cALL && !$c384); -usage("No command was supplied to generate SHA-512 hashes.\n") if ($hashes & 4 == 4 && !$cALL && !$c512); - -# Default .info files: -if (scalar(@FILES) < 1) { - opendir(DIR, "testvectors") || usage("Unable to scan directory 'testvectors' for vector information files: $!\n"); - @FILES = grep(/\.info$/, readdir(DIR)); - closedir(DIR); - @FILES = map { s/^/testvectors\//; $_; } @FILES; - @FILES = sort(@FILES); -} - -# Now read in each test vector information file: -foreach $file (@FILES) { - $dir = $file; - if ($file !~ /\//) { - $dir = "./"; - } else { - $dir =~ s/\/[^\/]+$//; - $dir .= "/"; - } - open(FILE, "<" . $file) || - usage("Unable to open test vector information file '$file' for reading: $!\n"); - $vec = { desc => "", file => "", sha256 => "", sha384 => "", sha512 => "" }; - $data = $field = ""; - $line = 0; - while() { - $line++; - s/\s*[\r\n]+$//; - next if ($field && $field ne "DESCRIPTION" && !$_); - if (/^(DESCRIPTION|FILE|SHA256|SHA384|SHA512):$/) { - if ($field eq "DESCRIPTION") { - $vec->{desc} = $data; - } elsif ($field eq "FILE") { - $data = $dir . $data if ($data !~ /^\//); - $vec->{file} = $data; - } elsif ($field eq "SHA256") { - $vec->{sha256} = $data; - } elsif ($field eq "SHA384") { - $vec->{sha384} = $data; - } elsif ($field eq "SHA512") { - $vec->{sha512} = $data; - } - $data = ""; - $field = $1; - } elsif ($field eq "DESCRIPTION") { - s/^ //; - $data .= $_ . "\n"; - } elsif ($field =~ /^SHA\d\d\d$/) { - s/^\s+//; - if (!/^([a-f0-9]{32}|[a-f0-9]{64})$/) { - usage("Invalid SHA-256/384/512 test vector information " . - "file format at line $line of file '$file'\n"); - } - $data .= $_; - } elsif ($field eq "FILE") { - s/^ //; - $data .= $_; - } else { - usage("Invalid SHA-256/384/512 test vector information file " . - "format at line $line of file '$file'\n"); - } - } - if ($field eq "DESCRIPTION") { - $data = $dir . $data if ($data !~ /^\//); - $vec->{desc} = $data; - } elsif ($field eq "FILE") { - $vec->{file} = $data; - } elsif ($field eq "SHA256") { - $vec->{sha256} = $data; - } elsif ($field eq "SHA384") { - $vec->{sha384} = $data; - } elsif ($field eq "SHA512") { - $vec->{sha512} = $data; - } else { - usage("Invalid SHA-256/384/512 test vector information file " . - "format. Missing required fields in file '$file'\n"); - } - - # Sanity check all entries: - if (!$vec->{desc}) { - usage("Invalid SHA-256/384/512 test vector information file " . - "format. Missing required DESCRIPTION field in file '$file'\n"); - } - if (!$vec->{file}) { - usage("Invalid SHA-256/384/512 test vector information file " . - "format. Missing required FILE field in file '$file'\n"); - } - if (! -f $vec->{file}) { - usage("The test vector data file (field FILE) name " . - "'$vec->{file}' is not a readable file. Check the FILE filed in " . - "file '$file'.\n"); - } - if (!($vec->{sha256} || $vec->{sha384} || $vec->{sha512})) { - usage("Invalid SHA-256/384/512 test vector information file " . - "format. There must be at least one SHA256, SHA384, or SHA512 " . - "field specified in file '$file'.\n"); - } - if ($vec->{sha256} !~ /^(|[a-f0-9]{64})$/) { - usage("Invalid SHA-256/384/512 test vector information file " . - "format. The SHA256 field is invalid in file '$file'.\n"); - } - if ($vec->{sha384} !~ /^(|[a-f0-9]{96})$/) { - usage("Invalid SHA-256/384/512 test vector information file " . - "format. The SHA384 field is invalid in file '$file'.\n"); - } - if ($vec->{sha512} !~ /^(|[a-f0-9]{128})$/) { - usage("Invalid SHA-256/384/512 test vector information file " . - "format. The SHA512 field is invalid in file '$file'.\n"); - } - close(FILE); - if ($hashes & (($vec->{sha256} ? 1 : 0) | ($vec->{sha384} ? 2 : 0) | ($vec->{sha512} ? 4 : 0))) { - push(@VECTORS, $vec); - } -} - -usage("There were no test vectors for the specified hash(es) in any of the test vector information files you specified.\n") if (scalar(@VECTORS) < 1); - -$num = $errors = $error256 = $error384 = $error512 = $tests = $test256 = $test384 = $test512 = 0; -foreach $vec (@VECTORS) { - $num++; - print "TEST VECTOR #$num:\n"; - print "\t" . join("\n\t", split(/\n/, $vec->{desc})) . "\n"; - print "VECTOR DATA FILE:\n\t$vec->{file}\n"; - $sha256 = $sha384 = $sha512 = ""; - if ($cALL) { - $prog = $cALL; - $prog =~ s/\%/'$vec->{file}'/g; - @SHA = grep(/[a-fA-f0-9]{64,128}/, split(/\n/, `$prog`)); - ($sha256) = grep(/(^[a-fA-F0-9]{64}$|^[a-fA-F0-9]{64}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{64}$|[^a-fA-F0-9][a-fA-F0-9]{64}[^a-fA-F0-9])/, @SHA); - ($sha384) = grep(/(^[a-fA-F0-9]{96}$|^[a-fA-F0-9]{96}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{96}$|[^a-fA-F0-9][a-fA-F0-9]{96}[^a-fA-F0-9])/, @SHA); - ($sha512) = grep(/(^[a-fA-F0-9]{128}$|^[a-fA-F0-9]{128}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{128}$|[^a-fA-F0-9][a-fA-F0-9]{128}[^a-fA-F0-9])/, @SHA); - } else { - if ($c256) { - $prog = $c256; - $prog =~ s/\%/'$vec->{file}'/g; - @SHA = grep(/[a-fA-f0-9]{64,128}/, split(/\n/, `$prog`)); - ($sha256) = grep(/(^[a-fA-F0-9]{64}$|^[a-fA-F0-9]{64}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{64}$|[^a-fA-F0-9][a-fA-F0-9]{64}[^a-fA-F0-9])/, @SHA); - } - if ($c384) { - $prog = $c384; - $prog =~ s/\%/'$vec->{file}'/g; - @SHA = grep(/[a-fA-f0-9]{64,128}/, split(/\n/, `$prog`)); - ($sha384) = grep(/(^[a-fA-F0-9]{96}$|^[a-fA-F0-9]{96}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{96}$|[^a-fA-F0-9][a-fA-F0-9]{96}[^a-fA-F0-9])/, @SHA); - } - if ($c512) { - $prog = $c512; - $prog =~ s/\%/'$vec->{file}'/g; - @SHA = grep(/[a-fA-f0-9]{64,128}/, split(/\n/, `$prog`)); - ($sha512) = grep(/(^[a-fA-F0-9]{128}$|^[a-fA-F0-9]{128}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{128}$|[^a-fA-F0-9][a-fA-F0-9]{128}[^a-fA-F0-9])/, @SHA); - } - } - usage("Unable to generate any hashes for file '$vec->{file}'!\n") if (!$sha256 && !$sha384 && $sha512); - $sha256 =~ tr/A-F/a-f/; - $sha384 =~ tr/A-F/a-f/; - $sha512 =~ tr/A-F/a-f/; - $sha256 =~ s/^.*([a-f0-9]{64}).*$/$1/; - $sha384 =~ s/^.*([a-f0-9]{96}).*$/$1/; - $sha512 =~ s/^.*([a-f0-9]{128}).*$/$1/; - - if ($sha256 && $hashes & 1 == 1) { - if ($vec->{sha256} eq $sha256) { - print "SHA256 MATCHES:\n\t$sha256\n" - } else { - print "SHA256 DOES NOT MATCH:\n\tEXPECTED:\n\t\t$vec->{sha256}\n" . - "\tGOT:\n\t\t$sha256\n\n"; - $error256++; - } - $test256++; - } - if ($sha384 && $hashes & 2 == 2) { - if ($vec->{sha384} eq $sha384) { - print "SHA384 MATCHES:\n\t" . substr($sha384, 0, 64) . "\n\t" . - substr($sha384, -32) . "\n"; - } else { - print "SHA384 DOES NOT MATCH:\n\tEXPECTED:\n\t\t" . - substr($vec->{sha384}, 0, 64) . "\n\t\t" . - substr($vec->{sha384}, -32) . "\n\tGOT:\n\t\t" . - substr($sha384, 0, 64) . "\n\t\t" . substr($sha384, -32) . "\n\n"; - $error384++; - } - $test384++; - } - if ($sha512 && $hashes & 4 == 4) { - if ($vec->{sha512} eq $sha512) { - print "SHA512 MATCHES:\n\t" . substr($sha512, 0, 64) . "\n\t" . - substr($sha512, -64) . "\n"; - } else { - print "SHA512 DOES NOT MATCH:\n\tEXPECTED:\n\t\t" . - substr($vec->{sha512}, 0, 64) . "\n\t\t" . - substr($vec->{sha512}, -32) . "\n\tGOT:\n\t\t" . - substr($sha512, 0, 64) . "\n\t\t" . substr($sha512, -64) . "\n\n"; - $error512++; - } - $test512++; - } -} - -$errors = $error256 + $error384 + $error512; -$tests = $test256 + $test384 + $test512; -print "\n\n===== RESULTS ($num VECTOR DATA FILES HASHED) =====\n\n"; -print "HASH TYPE\tNO. OF TESTS\tPASSED\tFAILED\n"; -print "---------\t------------\t------\t------\n"; -if ($test256) { - $pass = $test256 - $error256; - print "SHA-256\t\t".substr(" $test256", -12)."\t".substr(" $pass", -6)."\t".substr(" $error256", -6)."\n"; -} -if ($test384) { - $pass = $test384 - $error384; - print "SHA-384\t\t".substr(" $test384", -12)."\t".substr(" $pass", -6)."\t".substr(" $error384", -6)."\n"; -} -if ($test512) { - $pass = $test512 - $error512; - print "SHA-512\t\t".substr(" $test512", -12)."\t".substr(" $pass", -6)."\t".substr(" $error512", -6)."\n"; -} -print "----------------------------------------------\n"; -$pass = $tests - $errors; -print "TOTAL: ".substr(" $tests", -12)."\t".substr(" $pass", -6)."\t".substr(" $errors", -6)."\n\n"; -print "NO ERRORS! ALL TESTS WERE SUCCESSFUL!\n\n" if (!$errors); - diff --git a/net/ip/tinydtls/sha2/testvectors/vector001.dat b/net/ip/tinydtls/sha2/testvectors/vector001.dat deleted file mode 100644 index f2ba8f84ab5c1bce84a7b441cb1959cfc7093b7f..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector001.dat +++ /dev/null @@ -1 +0,0 @@ -abc \ No newline at end of file diff --git a/net/ip/tinydtls/sha2/testvectors/vector001.info b/net/ip/tinydtls/sha2/testvectors/vector001.info deleted file mode 100644 index 57b444edc176793fdbe59e4e41ffe71a7f313187..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector001.info +++ /dev/null @@ -1,21 +0,0 @@ -DESCRIPTION: - This test vector is taken from the PDF document that describes - the SHA-256/384/512 algorithms. That document contains sample - output for all three versions (SHA-256, SHA-384, and SHA-512). - - (Total length of test vector data: 3) - -FILE: - vector001.dat - -SHA256: - ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad - -SHA384: - cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed - 8086072ba1e7cc2358baeca134c825a7 - -SHA512: - ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a - 2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f - diff --git a/net/ip/tinydtls/sha2/testvectors/vector002.dat b/net/ip/tinydtls/sha2/testvectors/vector002.dat deleted file mode 100644 index 199f24ed041a6af4d09fa175444712eb1849af8d..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector002.dat +++ /dev/null @@ -1 +0,0 @@ -abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq \ No newline at end of file diff --git a/net/ip/tinydtls/sha2/testvectors/vector002.info b/net/ip/tinydtls/sha2/testvectors/vector002.info deleted file mode 100644 index 0fc1ed3ce6039df4ebf86779199a3cfd317f86c2..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector002.info +++ /dev/null @@ -1,21 +0,0 @@ -DESCRIPTION: - The PDF document only provided sample output for SHA-256 using - this test data. I have provided SHA-384 and SHA-512 sample - output from my own implementation which may not be correct. - - (Total length of test vector data: 56) - -FILE: - vector002.dat - -SHA256: - 248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1 - -SHA384: - 3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6 - b0455a8520bc4e6f5fe95b1fe3c8452b - -SHA512: - 204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c335 - 96fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445 - diff --git a/net/ip/tinydtls/sha2/testvectors/vector003.dat b/net/ip/tinydtls/sha2/testvectors/vector003.dat deleted file mode 100644 index 4674ea42f610e17c814d83f7b35c41383273ee33..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector003.dat +++ /dev/null @@ -1 +0,0 @@ -abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu \ No newline at end of file diff --git a/net/ip/tinydtls/sha2/testvectors/vector003.info b/net/ip/tinydtls/sha2/testvectors/vector003.info deleted file mode 100644 index 17a2ad85989ff1b3d0197e9ff0b9362d3e8c2d0d..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector003.info +++ /dev/null @@ -1,22 +0,0 @@ -DESCRIPTION: - For this test data (from the PDF document), no example output - was provided for SHA-256 (SHA-384 and SHA-512 samples were - provided), so the sample for SHA-256 comes from the output of - my own implementation and so may not be correct. - - (Total length of test vector data: 112) - -FILE: - vector003.dat - -SHA256: - cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1 - -SHA384: - 09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712 - fcc7c71a557e2db966c3e9fa91746039 - -SHA512: - 8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018 - 501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909 - diff --git a/net/ip/tinydtls/sha2/testvectors/vector004.dat b/net/ip/tinydtls/sha2/testvectors/vector004.dat deleted file mode 100644 index 3d71ebac2df1e4712e5bbfeab775b35adda8faab..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector004.dat +++ /dev/null @@ -1 +0,0 @@ -Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battlefield of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this. But, in a larger sense, we can not dedicate--we can not consecrate--we can not hallow--this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us--that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion--that we here highly resolve that these dead shall not have died in vain--that this nation, under God, shall have a new birth of freedom--and that government of the people, by the people, for the people, shall not perish from the earth. -- President Abraham Lincoln, November 19, 1863 \ No newline at end of file diff --git a/net/ip/tinydtls/sha2/testvectors/vector004.info b/net/ip/tinydtls/sha2/testvectors/vector004.info deleted file mode 100644 index eed148cf9b99c620cfec23f5ee248c37b493cc9b..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector004.info +++ /dev/null @@ -1,22 +0,0 @@ -DESCRIPTION: - The output samples for this test vector come exclusively from my - own implementation and so may be completely incorrect. Use with - a very large grain of salt. The input sample comes from...well - most anyone in the U.S. will know and many outside the U.S. too. - - (Total length of test vector data: 1515) - -FILE: - vector004.dat - -SHA256: - 4d25fccf8752ce470a58cd21d90939b7eb25f3fa418dd2da4c38288ea561e600 - -SHA384: - 69cc75b95280bdd9e154e743903e37b1205aa382e92e051b1f48a6db9d0203f8 - a17c1762d46887037275606932d3381e - -SHA512: - 23450737795d2f6a13aa61adcca0df5eef6df8d8db2b42cd2ca8f783734217a7 - 3e9cabc3c9b8a8602f8aeaeb34562b6b1286846060f9809b90286b3555751f09 - diff --git a/net/ip/tinydtls/sha2/testvectors/vector005.dat b/net/ip/tinydtls/sha2/testvectors/vector005.dat deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/net/ip/tinydtls/sha2/testvectors/vector005.info b/net/ip/tinydtls/sha2/testvectors/vector005.info deleted file mode 100644 index 37602d30a31b777a931cec9e26e3922b72b79146..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector005.info +++ /dev/null @@ -1,23 +0,0 @@ -DESCRIPTION: - The output samples for this test vector come exclusively from my - own implementation and so may be completely incorrect. Use with - a very large grain of salt. The input sample is EMPTY (no bits). - Mr. David A. Ireland's SHA-256 implementation agrees with my own - implementation on the output of this test vector (SHA-256 only). - - (Total length of test vector data: 0) - -FILE: - vector005.dat - -SHA256: - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 - -SHA384: - 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da - 274edebfe76f65fbd51ad2f14898b95b - -SHA512: - cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce - 47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e - diff --git a/net/ip/tinydtls/sha2/testvectors/vector006.dat b/net/ip/tinydtls/sha2/testvectors/vector006.dat deleted file mode 100644 index 7caf161334261a0d9102774b26cadf2dcfd37222..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector006.dat +++ /dev/null @@ -1 +0,0 @@ -This is exactly 64 bytes long, not counting the terminating byte \ No newline at end of file diff --git a/net/ip/tinydtls/sha2/testvectors/vector006.info b/net/ip/tinydtls/sha2/testvectors/vector006.info deleted file mode 100644 index 2a0d78aca7b4d3b25281ac843a7c32d08941f5ac..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector006.info +++ /dev/null @@ -1,22 +0,0 @@ -DESCRIPTION: - The output samples for thi test vector come exclusively from my - own implementation and so may be completely incorrect. Use with - a very large grain of salt. The input sample exactly the same - length as the SHA-256 block length. - - (Total length of test vector data: 64) - -FILE: - vector006.dat - -SHA256: - ab64eff7e88e2e46165e29f2bce41826bd4c7b3552f6b382a9e7d3af47c245f8 - -SHA384: - e28e35e25a1874908bf0958bb088b69f3d742a753c86993e9f4b1c4c21988f95 - 8bd1fe0315b195aca7b061213ac2a9bd - -SHA512: - 70aefeaa0e7ac4f8fe17532d7185a289bee3b428d950c14fa8b713ca09814a38 - 7d245870e007a80ad97c369d193e41701aa07f3221d15f0e65a1ff970cedf030 - diff --git a/net/ip/tinydtls/sha2/testvectors/vector007.dat b/net/ip/tinydtls/sha2/testvectors/vector007.dat deleted file mode 100644 index 1caf01b39425ba4bf674fabfad635bc71f057ca7..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector007.dat +++ /dev/null @@ -1 +0,0 @@ -For this sample, this 63-byte string will be used as input data \ No newline at end of file diff --git a/net/ip/tinydtls/sha2/testvectors/vector007.info b/net/ip/tinydtls/sha2/testvectors/vector007.info deleted file mode 100644 index fad860d61ca7075f1e87f28d15867465d0c96868..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector007.info +++ /dev/null @@ -1,22 +0,0 @@ -DESCRIPTION: - The output samples for thi test vector come exclusively from my - own implementation and so may be completely incorrect. Use with - a very large grain of salt. The input sample one byte shorter - than the SHA-256 block length. - - (Total length of test vector data: 63) - -FILE: - vector007.dat - -SHA256: - f08a78cbbaee082b052ae0708f32fa1e50c5c421aa772ba5dbb406a2ea6be342 - -SHA384: - 37b49ef3d08de53e9bd018b0630067bd43d09c427d06b05812f48531bce7d2a6 - 98ee2d1ed1ffed46fd4c3b9f38a8a557 - -SHA512: - b3de4afbc516d2478fe9b518d063bda6c8dd65fc38402dd81d1eb7364e72fb6e - 6663cf6d2771c8f5a6da09601712fb3d2a36c6ffea3e28b0818b05b0a8660766 - diff --git a/net/ip/tinydtls/sha2/testvectors/vector008.dat b/net/ip/tinydtls/sha2/testvectors/vector008.dat deleted file mode 100644 index baae22678b3856ab718a72df36be1e9f27ddef74..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector008.dat +++ /dev/null @@ -1 +0,0 @@ -And this textual data, astonishing as it may appear, is exactly 128 bytes in length, as are both SHA-384 and SHA-512 block sizes \ No newline at end of file diff --git a/net/ip/tinydtls/sha2/testvectors/vector008.info b/net/ip/tinydtls/sha2/testvectors/vector008.info deleted file mode 100644 index 22cfd811ae5c4f0008c42611e5ec517bab76b6a2..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector008.info +++ /dev/null @@ -1,22 +0,0 @@ -DESCRIPTION: - The output samples for thi test vector come exclusively from my - own implementation and so may be completely incorrect. Use with - a very large grain of salt. The input sample exactly the same - length as the SHA-384 and SHA-512 block lengths. - - (Total length of test vector data: 128) - -FILE: - vector008.dat - -SHA256: - 0ab803344830f92089494fb635ad00d76164ad6e57012b237722df0d7ad26896 - -SHA384: - e3e3602f4d90c935321d788f722071a8809f4f09366f2825cd85da97ccd2955e - b6b8245974402aa64789ed45293e94ba - -SHA512: - 97fb4ec472f3cb698b9c3c12a12768483e5b62bcdad934280750b4fa4701e5e0 - 550a80bb0828342c19631ba55a55e1cee5de2fda91fc5d40e7bee1d4e6d415b3 - diff --git a/net/ip/tinydtls/sha2/testvectors/vector009.dat b/net/ip/tinydtls/sha2/testvectors/vector009.dat deleted file mode 100644 index 9c64af44e5cd828fdd997768555744746ae6ab7f..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector009.dat +++ /dev/null @@ -1 +0,0 @@ -By hashing data that is one byte less than a multiple of a hash block length (like this 127-byte string), bugs may be revealed. \ No newline at end of file diff --git a/net/ip/tinydtls/sha2/testvectors/vector009.info b/net/ip/tinydtls/sha2/testvectors/vector009.info deleted file mode 100644 index d5fe515843de1a0835dde9523ba34140712cf572..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector009.info +++ /dev/null @@ -1,22 +0,0 @@ -DESCRIPTION: - The output samples for thi test vector come exclusively from my - own implementation and so may be completely incorrect. Use with - a very large grain of salt. The input sample is one byte shorter - in length than the SHA-384 and SHA-512 block lengths. - - (Total length of test vector data: 127) - -FILE: - vector009.dat - -SHA256: - e4326d0459653d7d3514674d713e74dc3df11ed4d30b4013fd327fdb9e394c26 - -SHA384: - 1ca650f38480fa9dfb5729636bec4a935ebc1cd4c0055ee50cad2aa627e06687 - 1044fd8e6fdb80edf10b85df15ba7aab - -SHA512: - d399507bbf5f2d0da51db1ff1fc51c1c9ff1de0937e00d01693b240e84fcc340 - 0601429f45c297acc6e8fcf1e4e4abe9ff21a54a0d3d88888f298971bd206cd5 - diff --git a/net/ip/tinydtls/sha2/testvectors/vector010.dat b/net/ip/tinydtls/sha2/testvectors/vector010.dat deleted file mode 100644 index f1681bce65cb44b71f4e7d038c0996d18e87e52d..0000000000000000000000000000000000000000 Binary files a/net/ip/tinydtls/sha2/testvectors/vector010.dat and /dev/null differ diff --git a/net/ip/tinydtls/sha2/testvectors/vector010.info b/net/ip/tinydtls/sha2/testvectors/vector010.info deleted file mode 100644 index df7717d8dfc20067243cf2f4cb1a1c2fe0c56fb7..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector010.info +++ /dev/null @@ -1,22 +0,0 @@ -DESCRIPTION: - The output samples for thi test vector come exclusively from my - own implementation and so may be completely incorrect. Use with - a very large grain of salt. The input sample is exactly 5 times - size of the SHA-256 block length. - - (Total length of test vector data: 320) - -FILE: - vector010.dat - -SHA256: - a7f001d996dd25af402d03b5f61aef950565949c1a6ad5004efa730328d2dbf3 - -SHA384: - b8261ddcd7df7b3969a516b72550de6fbf0e394a4a7bb2bbc60ec603c2ceff64 - 3c5bf62bc6dcbfa5beb54b62d750b969 - -SHA512: - caf970d3638e21053173a638c4b94d6d1ff87bc47b58f8ee928fbe9e245c23ab - f81019e45bf017ecc8610e5e0b95e3b025ccd611a772ca4fb3dfba26f0859725 - diff --git a/net/ip/tinydtls/sha2/testvectors/vector011.dat b/net/ip/tinydtls/sha2/testvectors/vector011.dat deleted file mode 100644 index d1609a9b5e72c7125f55e39cb9e2ef20e2ad36e6..0000000000000000000000000000000000000000 Binary files a/net/ip/tinydtls/sha2/testvectors/vector011.dat and /dev/null differ diff --git a/net/ip/tinydtls/sha2/testvectors/vector011.info b/net/ip/tinydtls/sha2/testvectors/vector011.info deleted file mode 100644 index f36988caf52335e86f65a7b5404c529fe6e87161..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector011.info +++ /dev/null @@ -1,22 +0,0 @@ -DESCRIPTION: - The output samples for thi test vector come exclusively from my - own implementation and so may be completely incorrect. Use with - a very large grain of salt. The input sample is one byte less - than 7 times the size of the SHA-256 block length. - - (Total length of test vector data: 447) - -FILE: - vector011.dat - -SHA256: - 6dcd63a07b0922cc3a9b3315b158478681cc32543b0a4180abe58a73c5e14cc2 - -SHA384: - 548e4e9a1ff57f469ed47b023bf5279dfb4d4ca08c65051e3a5c41fab84479a2 - 05496276906008b4b3c5b0970b2f5446 - -SHA512: - ee5d07460183b130687c977e9f8d43110989b0864b18fe6ee00a53dec5eda111 - f3aaa3bac7ab8dae26ed545a4de33ed45190f18fa0c327c44642ab9424265330 - diff --git a/net/ip/tinydtls/sha2/testvectors/vector012.dat b/net/ip/tinydtls/sha2/testvectors/vector012.dat deleted file mode 100644 index d74f1dbc7de5c45b6127c0dfa017ec2be859c8a1..0000000000000000000000000000000000000000 Binary files a/net/ip/tinydtls/sha2/testvectors/vector012.dat and /dev/null differ diff --git a/net/ip/tinydtls/sha2/testvectors/vector012.info b/net/ip/tinydtls/sha2/testvectors/vector012.info deleted file mode 100644 index a1574e17d776f5004eb2a75d3d577b14a7d422da..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector012.info +++ /dev/null @@ -1,22 +0,0 @@ -DESCRIPTION: - The output samples for thi test vector come exclusively from my - own implementation and so may be completely incorrect. Use with - a very large grain of salt. The input sample is exactly 5 times - size of the SHA-384 and SHA-512 block lengths. - - (Total length of test vector data: 640) - -FILE: - vector012.dat - -SHA256: - af6ebfde7d93d5badb6cde6287ecc2061c1cafc5b1c1217cd984fbcdb9c61aaa - -SHA384: - c6fec3a3278dd6b5afc8c0971d32d38faf5802f1a21527c32563b32a1ac34065 - 6b433b44fe2648aa2232206f4301193a - -SHA512: - 73ffeb67716c3495fbc33f2d62fe08e2616706a5599881c7e67e9ef2b68f4988 - ea8b3b604ba87e50b07962692705c420fa31a00be41d6aaa9f3b11eafe9cf49b - diff --git a/net/ip/tinydtls/sha2/testvectors/vector013.dat b/net/ip/tinydtls/sha2/testvectors/vector013.dat deleted file mode 100644 index cc8a8aed3aef4c61f83dff8f70319cb4a34c109d..0000000000000000000000000000000000000000 Binary files a/net/ip/tinydtls/sha2/testvectors/vector013.dat and /dev/null differ diff --git a/net/ip/tinydtls/sha2/testvectors/vector013.info b/net/ip/tinydtls/sha2/testvectors/vector013.info deleted file mode 100644 index 4fbd4cbcd65aecd1d139e737290efbbb7c6b779c..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector013.info +++ /dev/null @@ -1,22 +0,0 @@ -DESCRIPTION: - The output samples for thi test vector come exclusively from my - own implementation and so may be completely incorrect. Use with - a very large grain of salt. The input sample is one byte short - of 17 times size of the SHA-384 and SHA-512 block lengths. - - (Total length of test vector data: 2175) - -FILE: - vector013.dat - -SHA256: - 8ff59c6d33c5a991088bc44dd38f037eb5ad5630c91071a221ad6943e872ac29 - -SHA384: - 92dca5655229b3c34796a227ff1809e273499adc2830149481224e0f54ff4483 - bd49834d4865e508ef53d4cd22b703ce - -SHA512: - 0e928db6207282bfb498ee871202f2337f4074f3a1f5055a24f08e912ac118f8 - 101832cdb9c2f702976e629183db9bacfdd7b086c800687c3599f15de7f7b9dd - diff --git a/net/ip/tinydtls/sha2/testvectors/vector014.dat b/net/ip/tinydtls/sha2/testvectors/vector014.dat deleted file mode 100644 index 6ee662908433f9cf8cf4b6a39efe9480efc374f1..0000000000000000000000000000000000000000 Binary files a/net/ip/tinydtls/sha2/testvectors/vector014.dat and /dev/null differ diff --git a/net/ip/tinydtls/sha2/testvectors/vector014.info b/net/ip/tinydtls/sha2/testvectors/vector014.info deleted file mode 100644 index 1780afc60dde39573eb42d5c63a74eccc535054b..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector014.info +++ /dev/null @@ -1,22 +0,0 @@ -DESCRIPTION: - The output samples for thi test vector come exclusively from my - own implementation and so may be completely incorrect. Use with - a very large grain of salt. The input sample 4 KB of misc. - data. - - (Total length of test vector data: 16384) - -FILE: - vector014.dat - -SHA256: - 1818e87564e0c50974ecaabbb2eb4ca2f6cc820234b51861e2590be625f1f703 - -SHA384: - 310fbb2027bdb7042f0e09e7b092e9ada506649510a7aa029825c8e8019e9c30 - 749d723f2de1bd8c043d8d89d3748c2f - -SHA512: - a001636f3ff1ce34f432f8e8f7785b78be84318beb8485a406650a8b243c419f - 7db6435cf6bf3000c6524adb5b52bad01afb76b3ceff701331e18b85b0e4cbd3 - diff --git a/net/ip/tinydtls/sha2/testvectors/vector015.dat b/net/ip/tinydtls/sha2/testvectors/vector015.dat deleted file mode 100644 index 7d630214058c237d3e753e8e0d514cc569eb7216..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector015.dat +++ /dev/null @@ -1 +0,0 @@ -qwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwerty \ No newline at end of file diff --git a/net/ip/tinydtls/sha2/testvectors/vector015.info b/net/ip/tinydtls/sha2/testvectors/vector015.info deleted file mode 100644 index d0357826e857c058a1ffb8e60b83d6414d990664..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector015.info +++ /dev/null @@ -1,21 +0,0 @@ -DESCRIPTION: - This is yet another of my own test vectors for a larger - input data set. The input data is the string "qwerty - repeated 65536 times. - - (Total length of test vector data: 393216) - -FILE: - vector015.dat - -SHA256: - 5e3dfe0cc98fd1c2de2a9d2fd893446da43d290f2512200c515416313cdf3192 - -SHA384: - 0d5e45317bc7997cb9c8a23bad9bac9170d5bc81789b51af6bcd74ace379fd64 - 9a2b48cb56c4cb4ec1477e6933329e0e - -SHA512: - 735bd6bebfe6f8070d70069105bc761f35ed1ac3742f2e372fdc14d2a51898e6 - 153ccaff9073324130abdc451c730dc5dab5a0452487b1171c4dd97f92e267b7 - diff --git a/net/ip/tinydtls/sha2/testvectors/vector016.dat b/net/ip/tinydtls/sha2/testvectors/vector016.dat deleted file mode 100644 index fc00891b74041a8c5de95a4cd09d07d0104a30bf..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector016.dat +++ /dev/null @@ -1 +0,0 @@ -Rijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AES \ No newline at end of file diff --git a/net/ip/tinydtls/sha2/testvectors/vector016.info b/net/ip/tinydtls/sha2/testvectors/vector016.info deleted file mode 100644 index effb114a35ba3cbc85addd3ac13498bbcfc29f06..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector016.info +++ /dev/null @@ -1,23 +0,0 @@ -DESCRIPTION: - This test vector came from Brian LaMacchia in his e-mail - message containing several samples of output from his SHA-256 - and SHA-512 implementations. My own implementations match - his output exactly. The input data data set is the string - "Rijndael is AES" repeated 1024 times. - - (Total length of test vector data: 15360) - -FILE: - vector016.dat - -SHA256: - 80fced5a97176a5009207cd119551b42c5b51ceb445230d02ecc2663bbfb483a - -SHA384: - aa1e77c094e5ce6db81a1add4c095201d020b7f8885a4333218da3b799b9fc42 - f00d60cd438a1724ae03bd7b515b739b - -SHA512: - fae25ec70bcb3bbdef9698b9d579da49db68318dbdf18c021d1f76aaceff9628 - 38873235597e7cce0c68aabc610e0deb79b13a01c302abc108e459ddfbe9bee8 - diff --git a/net/ip/tinydtls/sha2/testvectors/vector017.dat b/net/ip/tinydtls/sha2/testvectors/vector017.dat deleted file mode 100644 index 4272d9799125bcd2cf6cb680ebd38e6e0ba1c3aa..0000000000000000000000000000000000000000 Binary files a/net/ip/tinydtls/sha2/testvectors/vector017.dat and /dev/null differ diff --git a/net/ip/tinydtls/sha2/testvectors/vector017.info b/net/ip/tinydtls/sha2/testvectors/vector017.info deleted file mode 100644 index 5d6c632b718e24bd5252545bdb1fa09a3cc2c36f..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector017.info +++ /dev/null @@ -1,32 +0,0 @@ -DESCRIPTION: - Rogier van de Pol notified me that my implementation differed - with several others on several test data sets he had tested - against. This test vector data set is one Rogier provided - to me that highlighted an off-by-one bug in my implementation - that affected SHA-256/384/512 hashes where the data set length - was of a certain length. In the case of SHA512 or SHA384, if - the data length after subtracting 111 was an even multiple of - 128 bytes, the bug surfaced. In the case of SHA256, after - subtracting 55, the remaining length was an even multiple of 64, - the bug surfaced. The fix was simple. In SHA512_Last() and in - SHA256_Final() functions, I simply replaced a single "<" test - with a "<=" test. - - Thanks, Rogier! - - (Total length of test vector data: 12271) - -FILE: - vector017.dat - -SHA256: - 88ee6ada861083094f4c64b373657e178d88ef0a4674fce6e4e1d84e3b176afb - -SHA384: - 78cc6402a29eb984b8f8f888ab0102cabe7c06f0b9570e3d8d744c969db14397 - f58ecd14e70f324bf12d8dd4cd1ad3b2 - -SHA512: - 211bec83fbca249c53668802b857a9889428dc5120f34b3eac1603f13d1b4796 - 5c387b39ef6af15b3a44c5e7b6bbb6c1096a677dc98fc8f472737540a332f378 - diff --git a/net/ip/tinydtls/sha2/testvectors/vector018.dat b/net/ip/tinydtls/sha2/testvectors/vector018.dat deleted file mode 100644 index cc8a8d14f7408d918861bebf04e02042fa199850..0000000000000000000000000000000000000000 Binary files a/net/ip/tinydtls/sha2/testvectors/vector018.dat and /dev/null differ diff --git a/net/ip/tinydtls/sha2/testvectors/vector018.info b/net/ip/tinydtls/sha2/testvectors/vector018.info deleted file mode 100644 index 7ee34445b59d4ff12955999287f80b3b41dd2db2..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/sha2/testvectors/vector018.info +++ /dev/null @@ -1,26 +0,0 @@ -DESCRIPTION: - I added this vector after fixing a bug first discovered by - Rogier van de Pol. The length of this data set is designed to - test for that bug or similar bugs in SHA-256 hashes. The bug - was an off-by-one bug where I used a "<" test instead of a "<=" - test in SHA256_Final(). Whenever data set lengths were an even - multiple of 64 after subtracting 55, the bug showed up. The - fix was easy, once the problem was fully diagnosed. - - Thanks, Rogier! - - (Total length of test vector data: 1079) - -FILE: - vector018.dat - -SHA256: - 5a2e925a7f8399fa63a20a1524ae83a7e3c48452f9af4df493c8c51311b04520 - -SHA384: - 72ec26cc742bc5fb1ef82541c9cadcf01a15c8104650d305f24ec8b006d7428e - 8ebe2bb320a465dbdd5c6326bbd8c9ad - -SHA512: - ebad464e6d9f1df7e8aadff69f52db40a001b253fbf65a018f29974dcc7fbf8e - 58b69e247975fbadb4153d7289357c9b6212752d0ab67dd3d9bbc0bb908aa98c diff --git a/net/ip/tinydtls/state.h b/net/ip/tinydtls/state.h deleted file mode 100644 index 72df125790ee7a82284ec9b434ac4d86c4b2747a..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/state.h +++ /dev/null @@ -1,64 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2013 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * @file state.h - * @brief state information for DTLS FSM - */ - -#ifndef _DTLS_STATE_H_ -#define _DTLS_STATE_H_ - -#include -#include - -#include "global.h" -#include "hmac.h" - -typedef enum { - DTLS_STATE_INIT = 0, DTLS_STATE_WAIT_CLIENTHELLO, DTLS_STATE_WAIT_CLIENTCERTIFICATE, - DTLS_STATE_WAIT_CLIENTKEYEXCHANGE, DTLS_STATE_WAIT_CERTIFICATEVERIFY, - DTLS_STATE_WAIT_CHANGECIPHERSPEC, - DTLS_STATE_WAIT_FINISHED, DTLS_STATE_FINISHED, - /* client states */ - DTLS_STATE_CLIENTHELLO, DTLS_STATE_WAIT_SERVERCERTIFICATE, DTLS_STATE_WAIT_SERVERKEYEXCHANGE, - DTLS_STATE_WAIT_SERVERHELLODONE, - - DTLS_STATE_CONNECTED, - DTLS_STATE_CLOSING, - DTLS_STATE_CLOSED -} dtls_state_t; - -typedef struct { - uint16_t mseq_s; /**< send handshake message sequence number counter */ - uint16_t mseq_r; /**< received handshake message sequence number counter */ - - /** pending config that is updated during handshake */ - /* FIXME: dtls_security_parameters_t pending_config; */ - - /* temporary storage for the final handshake hash */ - dtls_hash_ctx hs_hash; -} dtls_hs_state_t; -#endif /* _DTLS_STATE_H_ */ diff --git a/net/ip/tinydtls/t_list.h b/net/ip/tinydtls/t_list.h deleted file mode 100644 index 0f5a1bb99220dce575bf694ac5c9f6e1794131a8..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/t_list.h +++ /dev/null @@ -1,194 +0,0 @@ -/* t_list -- tinydtls lists - * - * Copyright (C) 2012 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * @file t_list.h - * @brief Wrappers for list structures and functions - */ - -#ifndef _DTLS_LIST_H_ -#define _DTLS_LIST_H_ - -#include "tinydtls.h" - -#ifndef WITH_CONTIKI - -/* We define list structures and utility functions to be compatible - * with Contiki list structures. The Contiki list API is part of the - * Contiki operating system, and therefore the following licensing - * terms apply (taken from contiki/core/lib/list.h): - * - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - * $ Id: list.h,v 1.5 2010/09/13 13:31:00 adamdunkels Exp $ - */ - -typedef void **list_t; -struct list { - struct list *next; -}; - -#define LIST_CONCAT(s1, s2) s1##s2 - -#define LIST_STRUCT(name) \ - void *LIST_CONCAT(name, _list); \ - list_t name - -#define LIST_STRUCT_INIT(struct_ptr, name) { \ - (struct_ptr)->name = &((struct_ptr)->LIST_CONCAT(name,_list)); \ - (struct_ptr)->LIST_CONCAT(name,_list) = NULL; \ - } - -static inline void * -list_head(list_t list) { - return *list; -} - -static inline void -list_remove(list_t list, void *item) { - struct list *l, *r; - - if(*list == NULL) { - return; - } - - r = NULL; - for(l = *list; l != NULL; l = l->next) { - if(l == item) { - if(r == NULL) { - /* First on list */ - *list = l->next; - } else { - /* Not first on list */ - r->next = l->next; - } - l->next = NULL; - return; - } - r = l; - } -} - -static inline void * -list_tail(list_t list) -{ - struct list *l; - - if(*list == NULL) { - return NULL; - } - - for(l = *list; l->next != NULL; l = l->next); - - return l; -} - -static inline void -list_add(list_t list, void *item) { - struct list *l; - - /* Make sure not to add the same element twice */ - list_remove(list, item); - - ((struct list *)item)->next = NULL; - - l = list_tail(list); - - if(l == NULL) { - *list = item; - } else { - l->next = item; - } -} - -static inline void -list_push(list_t list, void *item) { - /* Make sure not to add the same element twice */ - list_remove(list, item); - - ((struct list *)item)->next = *list; - *list = item; -} - -static inline void * -list_pop(list_t list) { - struct list *l; - l = *list; - if(l) - list_remove(list, l); - - return l; -} - -static inline void -list_insert(list_t list, void *previtem, void *newitem) { - if(previtem == NULL) { - list_push(list, newitem); - } else { - ((struct list *)newitem)->next = ((struct list *)previtem)->next; - ((struct list *)previtem)->next = newitem; - } -} - -static inline void * -list_item_next(void *item) -{ - return item == NULL? NULL: ((struct list *)item)->next; -} - -#else /* WITH_CONTIKI */ -#include "list.h" -#endif /* WITH_CONTIKI */ - -#endif /* _DTLS_LIST_H_ */ diff --git a/net/ip/tinydtls/tests/Makefile.in b/net/ip/tinydtls/tests/Makefile.in deleted file mode 100644 index 3a50695d8e4d845b6598a9e0fa5fc71793085578..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/tests/Makefile.in +++ /dev/null @@ -1,84 +0,0 @@ -# Makefile for tinydtls -# -# Copyright (C) 2011 Olaf Bergmann -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, copy, -# modify, merge, publish, distribute, sublicense, and/or sell copies -# of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# the library's version -VERSION:=@PACKAGE_VERSION@ - -# tools -@SET_MAKE@ -SHELL = /bin/sh -MKDIR = mkdir - -abs_builddir = @abs_builddir@ -top_builddir = @top_builddir@ -top_srcdir:= @top_srcdir@ - -# files and flags -SOURCES:= dtls-server.c ccm-test.c prf-test.c \ - dtls-client.c - #cbc_aes128-test.c #dsrv-test.c -OBJECTS:= $(patsubst %.c, %.o, $(SOURCES)) -PROGRAMS:= $(patsubst %.c, %, $(SOURCES)) -HEADERS:= -CFLAGS:=-Wall @CFLAGS@ -CPPFLAGS:=-I$(top_srcdir) @CPPFLAGS@ -LDFLAGS:=-L$(top_builddir) -LDLIBS:=-ltinydtls @LIBS@ -DISTDIR=$(top_builddir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@ -FILES:=Makefile.in $(SOURCES) ccm-testdata.c #cbc_aes128-testdata.c - -.PHONY: all dirs clean distclean .gitignore doc - -.SUFFIXES: -.SUFFIXES: .c .o - -all: $(PROGRAMS) - -check: - echo DISTDIR: $(DISTDIR) - echo top_builddir: $(top_builddir) - -clean: - @rm -f $(PROGRAMS) main.o $(LIB) $(OBJECTS) - for dir in $(SUBDIRS); do \ - $(MAKE) -C $$dir clean ; \ - done - -doc: - $(MAKE) -C doc - -distclean: clean - @rm -rf $(DISTDIR) - @rm -f *~ $(DISTDIR).tar.gz - -dist: $(FILES) - test -d $(DISTDIR)/tests || mkdir $(DISTDIR)/tests - cp $(FILES) $(DISTDIR)/tests - -# this directory contains no installation candidates -install: - : - -.gitignore: - echo "core\n*~\n*.[oa]\n*.gz\n*.cap\n$(PROGRAM)\n$(DISTDIR)\n.gitignore" >$@ diff --git a/net/ip/tinydtls/tests/cbc_aes128-test.c b/net/ip/tinydtls/tests/cbc_aes128-test.c deleted file mode 100644 index 1f91920350ef7387cf98ad011c465f4c0ebe3e34..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/tests/cbc_aes128-test.c +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include - -#include "debug.h" -#include "numeric.h" -#include "crypto.h" - -#include "cbc_aes128-testdata.c" - -void -dump(unsigned char *buf, size_t len) { - size_t i = 0; - while (i < len) { - printf("%02x ", buf[i++]); - if (i % 4 == 0) - printf(" "); - if (i % 16 == 0) - printf("\n\t"); - } - printf("\n"); -} - -int main(int argc, char **argv) { - int len, n; - - for (n = 0; n < sizeof(data)/sizeof(struct test_vector); ++n) { - dtls_cipher_context_t *cipher; - - cipher = dtls_new_cipher(&ciphers[AES128], - data[n].key, - sizeof(data[n].key)); - - if (!cipher) { - fprintf(stderr, "cannot set key\n"); - exit(-1); - } - - dtls_init_cipher(cipher, data[n].nonce, sizeof(data[n].nonce)); - - if (data[n].M == 0) - len = dtls_encrypt(cipher, data[n].msg, data[n].lm); - else - len = dtls_decrypt(cipher, data[n].msg, data[n].lm); - - printf("Packet Vector #%d ", n+1); - if (len != data[n].r_lm - || memcmp(data[n].msg, data[n].result, len)) - printf("FAILED, "); - else - printf("OK, "); - - printf("result is (total length = %d):\n\t", (int)len); - dump(data[n].msg, len); - - free(cipher); - } - - return 0; -} diff --git a/net/ip/tinydtls/tests/cbc_aes128-testdata.c b/net/ip/tinydtls/tests/cbc_aes128-testdata.c deleted file mode 100644 index 07916799950d87c0ab873baae9d39f83b7ef4b71..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/tests/cbc_aes128-testdata.c +++ /dev/null @@ -1,72 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* test vectors from Appendix F.2.{1,2} of NIST SP 800-38A, ed. 2001 */ - -struct test_vector { - size_t M; /* mode: 0 == encrypt, 1 == decrypt */ - size_t lm; /* overall message length */ - size_t la; /* not used */ - unsigned char key[AES_BLKLEN]; - unsigned char nonce[AES_BLKLEN]; - unsigned char msg[2000]; - size_t r_lm; /* overall result length */ - unsigned char result[2000]; /* result */ -}; - -struct test_vector data[] = { - /* F.2.1 (encrypt) */ - { 0, 4 * AES_BLKLEN, 0, - { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, /* AES key */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* Nonce */ - { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, - 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, - 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, - 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }, /* msg */ - 4 * AES_BLKLEN, /* length of result */ - { 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, - 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2, - 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16, - 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7 - } /* result */ - }, - - /* F.2.2 (decrypt) */ - { 1, 4 * AES_BLKLEN, 0, - { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, /* AES key */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* Nonce */ - { 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, - 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2, - 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16, - 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7 - }, /* msg */ - 4 * AES_BLKLEN, /* length of result */ - { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, - 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, - 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, - 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 - } /* result */ - } -}; diff --git a/net/ip/tinydtls/tests/ccm-test.c b/net/ip/tinydtls/tests/ccm-test.c deleted file mode 100644 index cbb7d2a0b216f6de0f5b0d47a1739dcc384a6c42..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/tests/ccm-test.c +++ /dev/null @@ -1,96 +0,0 @@ -#include -#include -#include -#ifdef HAVE_STRINGS_H -#include -#endif - -#ifdef WITH_CONTIKI -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" -#endif /* WITH_CONTIKI */ - -//#include "debug.h" -#include "numeric.h" -#include "ccm.h" - -#include "ccm-testdata.c" - -#ifndef HAVE_FLS -int fls(unsigned int i) { - int n; - for (n = 0; i; n++) - i >>= 1; - return n; -} -#endif - -void -dump(unsigned char *buf, size_t len) { - size_t i = 0; - while (i < len) { - printf("%02x ", buf[i++]); - if (i % 4 == 0) - printf(" "); - if (i % 16 == 0) - printf("\n\t"); - } - printf("\n"); -} - -#ifdef WITH_CONTIKI -PROCESS(ccm_test_process, "CCM test process"); -AUTOSTART_PROCESSES(&ccm_test_process); -PROCESS_THREAD(ccm_test_process, ev, d) -{ -#else /* WITH_CONTIKI */ -int main(int argc, char **argv) { -#endif /* WITH_CONTIKI */ - long int len; - int n; - - rijndael_ctx ctx; - -#ifdef WITH_CONTIKI - PROCESS_BEGIN(); -#endif /* WITH_CONTIKI */ - - for (n = 0; n < sizeof(data)/sizeof(struct test_vector); ++n) { - - if (rijndael_set_key_enc_only(&ctx, data[n].key, 8*sizeof(data[n].key)) < 0) { - fprintf(stderr, "cannot set key\n"); - return -1; - } - - len = dtls_ccm_encrypt_message(&ctx, data[n].M, data[n].L, data[n].nonce, - data[n].msg + data[n].la, - data[n].lm - data[n].la, - data[n].msg, data[n].la); - - len += + data[n].la; - printf("Packet Vector #%d ", n+1); - if (len != data[n].r_lm || memcmp(data[n].msg, data[n].result, len)) - printf("FAILED, "); - else - printf("OK, "); - - printf("result is (total length = %lu):\n\t", len); - dump(data[n].msg, len); - - len = dtls_ccm_decrypt_message(&ctx, data[n].M, data[n].L, data[n].nonce, - data[n].msg + data[n].la, len - data[n].la, - data[n].msg, data[n].la); - - if (len < 0) - printf("Packet Vector #%d: cannot decrypt message\n", n+1); - else - printf("\t*** MAC verified (total length = %lu) ***\n", len + data[n].la); - } - -#ifdef WITH_CONTIKI - PROCESS_END(); -#else /* WITH_CONTIKI */ - return 0; -#endif /* WITH_CONTIKI */ -} diff --git a/net/ip/tinydtls/tests/ccm-testdata.c b/net/ip/tinydtls/tests/ccm-testdata.c deleted file mode 100644 index f0da4ae9467e50449a479f85cbee76746f3ce24a..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/tests/ccm-testdata.c +++ /dev/null @@ -1,395 +0,0 @@ -/* dtls -- a very basic DTLS implementation - * - * Copyright (C) 2011 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* test vectors from RFC 3610 */ - -struct test_vector { - size_t M, L; - size_t lm; /* overall message length */ - size_t la; /* number of bytes additional data */ - unsigned char key[DTLS_CCM_BLOCKSIZE]; - unsigned char nonce[DTLS_CCM_BLOCKSIZE]; - unsigned char msg[200]; - size_t r_lm; /* overall result length */ - unsigned char result[200]; /* result */ -}; - -struct test_vector data[] = { - /* #1 */ - { 8, 2, 31, 8, - { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ - { 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E}, /* msg */ - 39, /* length of result */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2, 0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80, 0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84, 0x17, 0xE8, 0xD1, 0x2C, 0xFD, 0xF9, 0x26, 0xE0} /* result */ - }, - - /* #2 */ - { 8, 2, 32, 8, - { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ - { 0x00, 0x00, 0x00, 0x04, 0x03, 0x02, 0x01, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}, /* msg */ - 40, /* length of result */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x72, 0xC9, 0x1A, 0x36, 0xE1, 0x35, 0xF8, 0xCF, 0x29, 0x1C, 0xA8, 0x94, 0x08, 0x5C, 0x87, 0xE3, 0xCC, 0x15, 0xC4, 0x39, 0xC9, 0xE4, 0x3A, 0x3B, 0xA0, 0x91, 0xD5, 0x6E, 0x10, 0x40, 0x09, 0x16} /* result */ - }, - - /* #3 */ - { 8, 2, 33, 8, - { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ - { 0x00, 0x00, 0x00, 0x05, 0x04, 0x03, 0x02, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20}, /* msg */ - 41, /* length of result */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x51, 0xB1, 0xE5, 0xF4, 0x4A, 0x19, 0x7D, 0x1D, 0xA4, 0x6B, 0x0F, 0x8E, 0x2D, 0x28, 0x2A, 0xE8, 0x71, 0xE8, 0x38, 0xBB, 0x64, 0xDA, 0x85, 0x96, 0x57, 0x4A, 0xDA, 0xA7, 0x6F, 0xBD, 0x9F, 0xB0, 0xC5} /* result */ - }, - - /* #4 */ - { 8, 2, 31, 12, - { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ - { 0x00, 0x00, 0x00, 0x06, 0x05, 0x04, 0x03, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E}, /* msg */ - 39, /* length of result */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xA2, 0x8C, 0x68, 0x65, 0x93, 0x9A, 0x9A, 0x79, 0xFA, 0xAA, 0x5C, 0x4C, 0x2A, 0x9D, 0x4A, 0x91, 0xCD, 0xAC, 0x8C, 0x96, 0xC8, 0x61, 0xB9, 0xC9, 0xE6, 0x1E, 0xF1} /* result */ - }, - - /* #5 */ - { 8, 2, 32, 12, - { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ - { 0x00, 0x00, 0x00, 0x07, 0x06, 0x05, 0x04, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}, /* msg */ - 40, /* length of result */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xDC, 0xF1, 0xFB, 0x7B, 0x5D, 0x9E, 0x23, 0xFB, 0x9D, 0x4E, 0x13, 0x12, 0x53, 0x65, 0x8A, 0xD8, 0x6E, 0xBD, 0xCA, 0x3E, 0x51, 0xE8, 0x3F, 0x07, 0x7D, 0x9C, 0x2D, 0x93} /* result */ - }, - - /* #6 */ - { 8, 2, 33, 12, - { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ - { 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20}, /* msg */ - 41, /* length of result */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x6F, 0xC1, 0xB0, 0x11, 0xF0, 0x06, 0x56, 0x8B, 0x51, 0x71, 0xA4, 0x2D, 0x95, 0x3D, 0x46, 0x9B, 0x25, 0x70, 0xA4, 0xBD, 0x87, 0x40, 0x5A, 0x04, 0x43, 0xAC, 0x91, 0xCB, 0x94} /* result */ - }, - - /* #7 */ - { 10, 2, 31, 8, - { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ - { 0x00, 0x00, 0x00, 0x09, 0x08, 0x07, 0x06, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E}, /* msg */ - 41, /* length of result */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x01, 0x35, 0xD1, 0xB2, 0xC9, 0x5F, 0x41, 0xD5, 0xD1, 0xD4, 0xFE, 0xC1, 0x85, 0xD1, 0x66, 0xB8, 0x09, 0x4E, 0x99, 0x9D, 0xFE, 0xD9, 0x6C, 0x04, 0x8C, 0x56, 0x60, 0x2C, 0x97, 0xAC, 0xBB, 0x74, 0x90} /* result */ - }, - - /* #8 */ - { 10, 2, 32, 8, - { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ - { 0x00, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x07, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}, /* msg */ - 42, /* length of result */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x7B, 0x75, 0x39, 0x9A, 0xC0, 0x83, 0x1D, 0xD2, 0xF0, 0xBB, 0xD7, 0x58, 0x79, 0xA2, 0xFD, 0x8F, 0x6C, 0xAE, 0x6B, 0x6C, 0xD9, 0xB7, 0xDB, 0x24, 0xC1, 0x7B, 0x44, 0x33, 0xF4, 0x34, 0x96, 0x3F, 0x34, 0xB4} /* result */ - }, - - /* #9 */ - { 10, 2, 33, 8, - { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ - { 0x00, 0x00, 0x00, 0x0B, 0x0A, 0x09, 0x08, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20}, /* msg */ - 43, /* length of result */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x82, 0x53, 0x1A, 0x60, 0xCC, 0x24, 0x94, 0x5A, 0x4B, 0x82, 0x79, 0x18, 0x1A, 0xB5, 0xC8, 0x4D, 0xF2, 0x1C, 0xE7, 0xF9, 0xB7, 0x3F, 0x42, 0xE1, 0x97, 0xEA, 0x9C, 0x07, 0xE5, 0x6B, 0x5E, 0xB1, 0x7E, 0x5F, 0x4E} /* result */ - }, - - /* #10 */ - { 10, 2, 31, 12, - { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ - { 0x00, 0x00, 0x00, 0x0C, 0x0B, 0x0A, 0x09, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E}, /* msg */ - 41, /* length of result */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x07, 0x34, 0x25, 0x94, 0x15, 0x77, 0x85, 0x15, 0x2B, 0x07, 0x40, 0x98, 0x33, 0x0A, 0xBB, 0x14, 0x1B, 0x94, 0x7B, 0x56, 0x6A, 0xA9, 0x40, 0x6B, 0x4D, 0x99, 0x99, 0x88, 0xDD} /* result */ - }, - - /* #11 */ - { 10, 2, 32, 12, - { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ - { 0x00, 0x00, 0x00, 0x0D, 0x0C, 0x0B, 0x0A, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}, /* msg */ - 42, /* length of result */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x67, 0x6B, 0xB2, 0x03, 0x80, 0xB0, 0xE3, 0x01, 0xE8, 0xAB, 0x79, 0x59, 0x0A, 0x39, 0x6D, 0xA7, 0x8B, 0x83, 0x49, 0x34, 0xF5, 0x3A, 0xA2, 0xE9, 0x10, 0x7A, 0x8B, 0x6C, 0x02, 0x2C} /* result */ - }, - - /* #12 */ - { 10, 2, 33, 12, - { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ - { 0x00, 0x00, 0x00, 0x0E, 0x0D, 0x0C, 0x0B, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20}, /* msg */ - 43, /* length of result */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xC0, 0xFF, 0xA0, 0xD6, 0xF0, 0x5B, 0xDB, 0x67, 0xF2, 0x4D, 0x43, 0xA4, 0x33, 0x8D, 0x2A, 0xA4, 0xBE, 0xD7, 0xB2, 0x0E, 0x43, 0xCD, 0x1A, 0xA3, 0x16, 0x62, 0xE7, 0xAD, 0x65, 0xD6, 0xDB} /* result */ - }, - - /* #13 */ - { 8, 2, 31, 8, - { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ - { 0x00, 0x41, 0x2B, 0x4E, 0xA9, 0xCD, 0xBE, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ - { 0x0B, 0xE1, 0xA8, 0x8B, 0xAC, 0xE0, 0x18, 0xB1, 0x08, 0xE8, 0xCF, 0x97, 0xD8, 0x20, 0xEA, 0x25, 0x84, 0x60, 0xE9, 0x6A, 0xD9, 0xCF, 0x52, 0x89, 0x05, 0x4D, 0x89, 0x5C, 0xEA, 0xC4, 0x7C}, /* msg */ - 39, /* length of result */ - { 0x0B, 0xE1, 0xA8, 0x8B, 0xAC, 0xE0, 0x18, 0xB1, 0x4C, 0xB9, 0x7F, 0x86, 0xA2, 0xA4, 0x68, 0x9A, 0x87, 0x79, 0x47, 0xAB, 0x80, 0x91, 0xEF, 0x53, 0x86, 0xA6, 0xFF, 0xBD, 0xD0, 0x80, 0xF8, 0xE7, 0x8C, 0xF7, 0xCB, 0x0C, 0xDD, 0xD7, 0xB3} /* result */ - }, - - /* #14 */ - { 8, 2, 32, 8, - { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ - { 0x00, 0x33, 0x56, 0x8E, 0xF7, 0xB2, 0x63, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ - { 0x63, 0x01, 0x8F, 0x76, 0xDC, 0x8A, 0x1B, 0xCB, 0x90, 0x20, 0xEA, 0x6F, 0x91, 0xBD, 0xD8, 0x5A, 0xFA, 0x00, 0x39, 0xBA, 0x4B, 0xAF, 0xF9, 0xBF, 0xB7, 0x9C, 0x70, 0x28, 0x94, 0x9C, 0xD0, 0xEC}, /* msg */ - 40, /* length of result */ - { 0x63, 0x01, 0x8F, 0x76, 0xDC, 0x8A, 0x1B, 0xCB, 0x4C, 0xCB, 0x1E, 0x7C, 0xA9, 0x81, 0xBE, 0xFA, 0xA0, 0x72, 0x6C, 0x55, 0xD3, 0x78, 0x06, 0x12, 0x98, 0xC8, 0x5C, 0x92, 0x81, 0x4A, 0xBC, 0x33, 0xC5, 0x2E, 0xE8, 0x1D, 0x7D, 0x77, 0xC0, 0x8A} /* result */ - }, - - /* #15 */ - { 8, 2, 33, 8, - { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ - { 0x00, 0x10, 0x3F, 0xE4, 0x13, 0x36, 0x71, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ - { 0xAA, 0x6C, 0xFA, 0x36, 0xCA, 0xE8, 0x6B, 0x40, 0xB9, 0x16, 0xE0, 0xEA, 0xCC, 0x1C, 0x00, 0xD7, 0xDC, 0xEC, 0x68, 0xEC, 0x0B, 0x3B, 0xBB, 0x1A, 0x02, 0xDE, 0x8A, 0x2D, 0x1A, 0xA3, 0x46, 0x13, 0x2E}, /* msg */ - 41, /* length of result */ - { 0xAA, 0x6C, 0xFA, 0x36, 0xCA, 0xE8, 0x6B, 0x40, 0xB1, 0xD2, 0x3A, 0x22, 0x20, 0xDD, 0xC0, 0xAC, 0x90, 0x0D, 0x9A, 0xA0, 0x3C, 0x61, 0xFC, 0xF4, 0xA5, 0x59, 0xA4, 0x41, 0x77, 0x67, 0x08, 0x97, 0x08, 0xA7, 0x76, 0x79, 0x6E, 0xDB, 0x72, 0x35, 0x06} /* result */ - }, - - /* #16 */ - { 8, 2, 31, 12, - { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ - { 0x00, 0x76, 0x4C, 0x63, 0xB8, 0x05, 0x8E, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ - { 0xD0, 0xD0, 0x73, 0x5C, 0x53, 0x1E, 0x1B, 0xEC, 0xF0, 0x49, 0xC2, 0x44, 0x12, 0xDA, 0xAC, 0x56, 0x30, 0xEF, 0xA5, 0x39, 0x6F, 0x77, 0x0C, 0xE1, 0xA6, 0x6B, 0x21, 0xF7, 0xB2, 0x10, 0x1C}, /* msg */ - 39, /* length of result */ - { 0xD0, 0xD0, 0x73, 0x5C, 0x53, 0x1E, 0x1B, 0xEC, 0xF0, 0x49, 0xC2, 0x44, 0x14, 0xD2, 0x53, 0xC3, 0x96, 0x7B, 0x70, 0x60, 0x9B, 0x7C, 0xBB, 0x7C, 0x49, 0x91, 0x60, 0x28, 0x32, 0x45, 0x26, 0x9A, 0x6F, 0x49, 0x97, 0x5B, 0xCA, 0xDE, 0xAF} /* result */ - }, - - /* #17 */ - { 8, 2, 32, 12, - { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ - { 0x00, 0xF8, 0xB6, 0x78, 0x09, 0x4E, 0x3B, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ - { 0x77, 0xB6, 0x0F, 0x01, 0x1C, 0x03, 0xE1, 0x52, 0x58, 0x99, 0xBC, 0xAE, 0xE8, 0x8B, 0x6A, 0x46, 0xC7, 0x8D, 0x63, 0xE5, 0x2E, 0xB8, 0xC5, 0x46, 0xEF, 0xB5, 0xDE, 0x6F, 0x75, 0xE9, 0xCC, 0x0D}, /* msg */ - 40, /* length of result */ - { 0x77, 0xB6, 0x0F, 0x01, 0x1C, 0x03, 0xE1, 0x52, 0x58, 0x99, 0xBC, 0xAE, 0x55, 0x45, 0xFF, 0x1A, 0x08, 0x5E, 0xE2, 0xEF, 0xBF, 0x52, 0xB2, 0xE0, 0x4B, 0xEE, 0x1E, 0x23, 0x36, 0xC7, 0x3E, 0x3F, 0x76, 0x2C, 0x0C, 0x77, 0x44, 0xFE, 0x7E, 0x3C} /* result */ - }, - - /* #18 */ - { 8, 2, 33, 12, - { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ - { 0x00, 0xD5, 0x60, 0x91, 0x2D, 0x3F, 0x70, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ - { 0xCD, 0x90, 0x44, 0xD2, 0xB7, 0x1F, 0xDB, 0x81, 0x20, 0xEA, 0x60, 0xC0, 0x64, 0x35, 0xAC, 0xBA, 0xFB, 0x11, 0xA8, 0x2E, 0x2F, 0x07, 0x1D, 0x7C, 0xA4, 0xA5, 0xEB, 0xD9, 0x3A, 0x80, 0x3B, 0xA8, 0x7F}, /* msg */ - 41, /* length of result */ - { 0xCD, 0x90, 0x44, 0xD2, 0xB7, 0x1F, 0xDB, 0x81, 0x20, 0xEA, 0x60, 0xC0, 0x00, 0x97, 0x69, 0xEC, 0xAB, 0xDF, 0x48, 0x62, 0x55, 0x94, 0xC5, 0x92, 0x51, 0xE6, 0x03, 0x57, 0x22, 0x67, 0x5E, 0x04, 0xC8, 0x47, 0x09, 0x9E, 0x5A, 0xE0, 0x70, 0x45, 0x51} /* result */ - }, - - /* #19 */ - { 10, 2, 31, 8, - { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ - { 0x00, 0x42, 0xFF, 0xF8, 0xF1, 0x95, 0x1C, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ - { 0xD8, 0x5B, 0xC7, 0xE6, 0x9F, 0x94, 0x4F, 0xB8, 0x8A, 0x19, 0xB9, 0x50, 0xBC, 0xF7, 0x1A, 0x01, 0x8E, 0x5E, 0x67, 0x01, 0xC9, 0x17, 0x87, 0x65, 0x98, 0x09, 0xD6, 0x7D, 0xBE, 0xDD, 0x18}, /* msg */ - 41, /* length of result */ - { 0xD8, 0x5B, 0xC7, 0xE6, 0x9F, 0x94, 0x4F, 0xB8, 0xBC, 0x21, 0x8D, 0xAA, 0x94, 0x74, 0x27, 0xB6, 0xDB, 0x38, 0x6A, 0x99, 0xAC, 0x1A, 0xEF, 0x23, 0xAD, 0xE0, 0xB5, 0x29, 0x39, 0xCB, 0x6A, 0x63, 0x7C, 0xF9, 0xBE, 0xC2, 0x40, 0x88, 0x97, 0xC6, 0xBA} /* result */ - }, - - /* #20 */ - { 10, 2, 32, 8, - { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ - { 0x00, 0x92, 0x0F, 0x40, 0xE5, 0x6C, 0xDC, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ - { 0x74, 0xA0, 0xEB, 0xC9, 0x06, 0x9F, 0x5B, 0x37, 0x17, 0x61, 0x43, 0x3C, 0x37, 0xC5, 0xA3, 0x5F, 0xC1, 0xF3, 0x9F, 0x40, 0x63, 0x02, 0xEB, 0x90, 0x7C, 0x61, 0x63, 0xBE, 0x38, 0xC9, 0x84, 0x37}, /* msg */ - 42, /* length of result */ - { 0x74, 0xA0, 0xEB, 0xC9, 0x06, 0x9F, 0x5B, 0x37, 0x58, 0x10, 0xE6, 0xFD, 0x25, 0x87, 0x40, 0x22, 0xE8, 0x03, 0x61, 0xA4, 0x78, 0xE3, 0xE9, 0xCF, 0x48, 0x4A, 0xB0, 0x4F, 0x44, 0x7E, 0xFF, 0xF6, 0xF0, 0xA4, 0x77, 0xCC, 0x2F, 0xC9, 0xBF, 0x54, 0x89, 0x44} /* result */ - }, - - /* #21 */ - { 10, 2, 33, 8, - { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ - { 0x00, 0x27, 0xCA, 0x0C, 0x71, 0x20, 0xBC, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ - { 0x44, 0xA3, 0xAA, 0x3A, 0xAE, 0x64, 0x75, 0xCA, 0xA4, 0x34, 0xA8, 0xE5, 0x85, 0x00, 0xC6, 0xE4, 0x15, 0x30, 0x53, 0x88, 0x62, 0xD6, 0x86, 0xEA, 0x9E, 0x81, 0x30, 0x1B, 0x5A, 0xE4, 0x22, 0x6B, 0xFA}, /* msg */ - 43, /* length of result */ - { 0x44, 0xA3, 0xAA, 0x3A, 0xAE, 0x64, 0x75, 0xCA, 0xF2, 0xBE, 0xED, 0x7B, 0xC5, 0x09, 0x8E, 0x83, 0xFE, 0xB5, 0xB3, 0x16, 0x08, 0xF8, 0xE2, 0x9C, 0x38, 0x81, 0x9A, 0x89, 0xC8, 0xE7, 0x76, 0xF1, 0x54, 0x4D, 0x41, 0x51, 0xA4, 0xED, 0x3A, 0x8B, 0x87, 0xB9, 0xCE} /* result */ - }, - - /* #22 */ - { 10, 2, 31, 12, - { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ - { 0x00, 0x5B, 0x8C, 0xCB, 0xCD, 0x9A, 0xF8, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ - { 0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25, 0x20, 0xC3, 0x3C, 0x49, 0xFD, 0x70, 0xB9, 0x6B, 0x49, 0xE2, 0x1D, 0x62, 0x17, 0x41, 0x63, 0x28, 0x75, 0xDB, 0x7F, 0x6C, 0x92, 0x43, 0xD2, 0xD7, 0xC2}, /* msg */ - 41, /* length of result */ - { 0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25, 0x20, 0xC3, 0x3C, 0x49, 0xFD, 0x70, 0x31, 0xD7, 0x50, 0xA0, 0x9D, 0xA3, 0xED, 0x7F, 0xDD, 0xD4, 0x9A, 0x20, 0x32, 0xAA, 0xBF, 0x17, 0xEC, 0x8E, 0xBF, 0x7D, 0x22, 0xC8, 0x08, 0x8C, 0x66, 0x6B, 0xE5, 0xC1, 0x97} /* result */ - }, - - /* #23 */ - { 10, 2, 32, 12, - { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ - { 0x00, 0x3E, 0xBE, 0x94, 0x04, 0x4B, 0x9A, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ - { 0x47, 0xA6, 0x5A, 0xC7, 0x8B, 0x3D, 0x59, 0x42, 0x27, 0xE8, 0x5E, 0x71, 0xE2, 0xFC, 0xFB, 0xB8, 0x80, 0x44, 0x2C, 0x73, 0x1B, 0xF9, 0x51, 0x67, 0xC8, 0xFF, 0xD7, 0x89, 0x5E, 0x33, 0x70, 0x76}, /* msg */ - 42, /* length of result */ - { 0x47, 0xA6, 0x5A, 0xC7, 0x8B, 0x3D, 0x59, 0x42, 0x27, 0xE8, 0x5E, 0x71, 0xE8, 0x82, 0xF1, 0xDB, 0xD3, 0x8C, 0xE3, 0xED, 0xA7, 0xC2, 0x3F, 0x04, 0xDD, 0x65, 0x07, 0x1E, 0xB4, 0x13, 0x42, 0xAC, 0xDF, 0x7E, 0x00, 0xDC, 0xCE, 0xC7, 0xAE, 0x52, 0x98, 0x7D} /* result */ - }, - - /* #24 */ - { 10, 2, 33, 12, - { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ - { 0x00, 0x8D, 0x49, 0x3B, 0x30, 0xAE, 0x8B, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ - { 0x6E, 0x37, 0xA6, 0xEF, 0x54, 0x6D, 0x95, 0x5D, 0x34, 0xAB, 0x60, 0x59, 0xAB, 0xF2, 0x1C, 0x0B, 0x02, 0xFE, 0xB8, 0x8F, 0x85, 0x6D, 0xF4, 0xA3, 0x73, 0x81, 0xBC, 0xE3, 0xCC, 0x12, 0x85, 0x17, 0xD4}, /* msg */ - 43, /* length of result */ - { 0x6E, 0x37, 0xA6, 0xEF, 0x54, 0x6D, 0x95, 0x5D, 0x34, 0xAB, 0x60, 0x59, 0xF3, 0x29, 0x05, 0xB8, 0x8A, 0x64, 0x1B, 0x04, 0xB9, 0xC9, 0xFF, 0xB5, 0x8C, 0xC3, 0x90, 0x90, 0x0F, 0x3D, 0xA1, 0x2A, 0xB1, 0x6D, 0xCE, 0x9E, 0x82, 0xEF, 0xA1, 0x6D, 0xA6, 0x20, 0x59} /* result */ - }, - - /* #25 */ - /* Cipher: AES-128 M=16 L=2 K_LEN=1 N_LEN=13 K=0x00 N=0x00000000000000000000000000 */ - { 16, 2, 0, 0, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* AES key */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Nonce */ - { }, /* msg */ - 16, /* length of result */ - { 0x8b, 0x60, 0xab, 0xcd, 0x60, 0x43, 0x81, 0x0b, - 0xa3, 0x78, 0xa0, 0x1d, 0x4a, 0x29, 0x83, 0x0b - } /* result */ - }, - - /* #26 */ - /* Cipher: AES-128 M=16 L=2 K_LEN=1 N_LEN=13 K=0x00 N=0x00000000000000000000000000 */ - { 16, 2, 37, 0, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* AES key */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }, /* Nonce */ - { 0x45, 0x69, 0x6e, 0x20, 0x6b, 0x6c, 0x65, 0x69, - 0x6e, 0x65, 0x72, 0x20, 0x54, 0x65, 0x78, 0x74, - 0x0a, 0x7a, 0x75, 0x6d, 0x20, 0x54, 0x65, 0x73, - 0x74, 0x65, 0x6e, 0x20, 0x76, 0x6f, 0x6e, 0x20, - 0x43, 0x43, 0x4d, 0x2e, 0x0a - }, /* msg */ - 53, /* length of result */ - { 0x90, 0x11, 0x9c, 0x2d, 0x6b, 0xf9, 0xe9, 0x05, - 0x3e, 0x0b, 0x44, 0x56, 0xca, 0xc8, 0xb6, 0x1a, - 0x00, 0x57, 0xa9, 0x8b, 0x6b, 0x69, 0x09, 0x7e, - 0x8e, 0x50, 0x50, 0x63, 0x50, 0x58, 0x0f, 0x78, - 0x75, 0x69, 0x6e, 0x9f, 0x3d, 0x63, 0x93, 0xe7, - 0x7a, 0x84, 0xe9, 0x9f, 0x11, 0x93, 0x95, 0xa0, - 0x9a, 0xef, 0x0d, 0xa0, 0xed - } /* result */ - }, - - /* #27 */ - /* Cipher: AES-128 M=8 L=5 K_LEN=16 N_LEN=10 K=0x001234567890abcdefdcaffeed3921ee N=0x00112233445566778899 */ - { 8, 5, 0, 0, - { 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, - 0xef, 0xdc, 0xaf, 0xfe, 0xed, 0x39, 0x21, 0xee }, /* AES key */ - { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99 }, /* Nonce */ - { }, /* msg */ - 8, /* length of result */ - { 0xb1, 0x33, 0x51, 0xc8, 0xb3, 0xd5, 0x10, 0xa7 } /* result */ - }, - - /* #28 */ - /* Cipher: AES-128 M=8 L=5 K_LEN=16 N_LEN=10 K=0x001234567890abcdefdcaffeed3921ee N=0x00112233445566778899 */ - { 8, 5, 37, 0, - { 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, - 0xef, 0xdc, 0xaf, 0xfe, 0xed, 0x39, 0x21, 0xee }, /* AES key */ - { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99 }, /* Nonce */ - { 0x45, 0x69, 0x6e, 0x20, 0x6b, 0x6c, 0x65, 0x69, - 0x6e, 0x65, 0x72, 0x20, 0x54, 0x65, 0x78, 0x74, - 0x0a, 0x7a, 0x75, 0x6d, 0x20, 0x54, 0x65, 0x73, - 0x74, 0x65, 0x6e, 0x20, 0x76, 0x6f, 0x6e, 0x20, - 0x43, 0x43, 0x4d, 0x2e, 0x0a - }, /* msg */ - 45, /* length of result */ - { 0x44, 0x7a, 0x82, 0x70, 0x1d, 0xd0, 0x35, 0x7b, - 0x68, 0xf7, 0x35, 0x4d, 0xbf, 0xd9, 0x16, 0x15, - 0x97, 0x41, 0x3d, 0x1e, 0x89, 0xc1, 0x25, 0xe7, - 0xd6, 0xa7, 0xde, 0x90, 0x1e, 0xf1, 0x69, 0x69, - 0x9f, 0xce, 0x40, 0xdc, 0xf0, 0xd1, 0x74, 0x53, - 0x2c, 0xa3, 0xb0, 0xcf, 0xb9 - } /* result */ - }, - - /* #29 */ - /* Cipher: AES-128 M=14 L=3 K_LEN=16 N_LEN=12 K=0x001234567890abcdefdcaffeed3921ee N=0x001122334455667788990000 */ - { 14, 3, 0, 0, - { 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, - 0xef, 0xdc, 0xaf, 0xfe, 0xed, 0x39, 0x21, 0xee }, /* AES key */ - { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0x00, 0x00 }, /* Nonce */ - { }, /* msg */ - 14, /* length of result */ - { 0xa4, 0x06, 0xa4, 0x23, 0x93, 0x3d, 0xa0, 0xca, - 0xb5, 0x90, 0xdb, 0x69, 0x69, 0x33 } /* result */ - }, - - /* #30 */ - /* Cipher: AES-128 M=14 L=3 K_LEN=16 N_LEN=12 K=0x001234567890abcdefdcaffeed3921ee N=0x001122334455667788990000 */ - { 14, 3, 37, 0, - { 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, - 0xef, 0xdc, 0xaf, 0xfe, 0xed, 0x39, 0x21, 0xee }, /* AES key */ - { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0x00, 0x00 }, /* Nonce */ - { 0x45, 0x69, 0x6e, 0x20, 0x6b, 0x6c, 0x65, 0x69, - 0x6e, 0x65, 0x72, 0x20, 0x54, 0x65, 0x78, 0x74, - 0x0a, 0x7a, 0x75, 0x6d, 0x20, 0x54, 0x65, 0x73, - 0x74, 0x65, 0x6e, 0x20, 0x76, 0x6f, 0x6e, 0x20, - 0x43, 0x43, 0x4d, 0x2e, 0x0a - }, /* msg */ - 51, - { 0x60, 0xaf, 0x87, 0x67, 0x4d, 0x9d, 0x54, 0x17, - 0x16, 0xc0, 0x29, 0x10, 0x7e, 0x3e, 0x34, 0x93, - 0x78, 0xe8, 0xd3, 0xc8, 0xc1, 0x03, 0x4f, 0xd6, - 0xf5, 0x3b, 0xaf, 0xd3, 0xf0, 0xd7, 0x0b, 0xdd, - 0x63, 0x93, 0xed, 0xf2, 0xb2, 0x72, 0xdc, 0xae, - 0x7c, 0xa0, 0x01, 0xdb, 0x56, 0x2a, 0x06, 0xb6, - 0xe9, 0xcf, 0x3c } /* result */ - }, - - /* #31 */ - /* Cipher: AES-128 M=8 L=5 K_LEN=6 N_LEN=10 K=0x11223344aabb N=0x00112233445566778899 */ - { 8, 5, 0, 0, - { 0x11, 0x22, 0x33, 0x44, 0xaa, 0xbb }, /* AES key */ - { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99 }, /* Nonce */ - { }, /* msg */ - 8, - { 0x28, 0x15, 0xfe, 0x81, 0xdd, 0xc3, 0x79, 0x04 } /* result */ - }, - - /* #32 */ - /* Cipher: AES-128 M=8 L=5 K_LEN=6 N_LEN=10 K=0x11223344aabb N=0x00112233445566778899 */ - - { 8, 5, 37, 0, - { 0x11, 0x22, 0x33, 0x44, 0xaa, 0xbb }, /* AES key */ - { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99 }, /* Nonce */ - { 0x45, 0x69, 0x6e, 0x20, 0x6b, 0x6c, 0x65, 0x69, - 0x6e, 0x65, 0x72, 0x20, 0x54, 0x65, 0x78, 0x74, - 0x0a, 0x7a, 0x75, 0x6d, 0x20, 0x54, 0x65, 0x73, - 0x74, 0x65, 0x6e, 0x20, 0x76, 0x6f, 0x6e, 0x20, - 0x43, 0x43, 0x4d, 0x2e, 0x0a - }, /* msg */ - 45, - { 0xdb, 0x31, 0x55, 0x9d, 0xab, 0x70, 0xdc, 0x62, - 0xd7, 0x76, 0x41, 0xb2, 0x14, 0x9e, 0x9c, 0x26, - 0x70, 0x61, 0xea, 0x36, 0xf8, 0x0e, 0xdf, 0x19, - 0xa6, 0xc7, 0x46, 0x3d, 0x5a, 0xc3, 0x0a, 0x73, - 0x14, 0x96, 0xa4, 0x84, 0x7f, 0x37, 0x55, 0x42, - 0xce, 0x7e, 0xf9, 0x3b, 0xe5 } /* result */ - } -}; diff --git a/net/ip/tinydtls/tests/dsrv-test.c b/net/ip/tinydtls/tests/dsrv-test.c deleted file mode 100644 index e7b44a9eecb5298c35642728e923b3bec92d471d..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/tests/dsrv-test.c +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "dsrv.h" - -void -handle_read(struct dsrv_context_t *ctx) { - int len; - static char buf[200]; - struct sockaddr_storage src; - socklen_t srclen = sizeof(src); - int fd = dsrv_get_fd(ctx, DSRV_READ); - - len = recvfrom(fd, buf, sizeof(buf), 0, - (struct sockaddr *)&src, &srclen); - - if (len < 0) { - perror("recvfrom"); - } else { - printf("read %d bytes: '%*s'\n", len, len, buf); - if (dsrv_sendto(ctx, (struct sockaddr *)&src, srclen, 0, buf, len) - == NULL) { - fprintf(stderr, "cannot add packet to sendqueue\n"); - } - } -} - -int -handle_write(struct dsrv_context_t *ctx) { - struct packet_t *p; - int fd = dsrv_get_fd(ctx, DSRV_WRITE); - int len; - - p = ctx->rq ? nq_peek(ctx->wq) : NULL; - - if (!p) - return -1; - - len = sendto(fd, p->buf, p->len, 0, p->raddr, p->rlen); - - if (len < 0) - perror("sendto"); - else - nq_pop(ctx->wq); - - return len; -} - -int main(int argc, char **argv) { - -#if 1 - struct sockaddr_in6 listen_addr = { AF_INET6, htons(20220), 0, IN6ADDR_ANY_INIT, 0 }; -#else - struct sockaddr_in listen_addr = { AF_INET, htons(20220), { htonl(0x7f000001) } }; -#endif - fd_set rfds, wfds; - struct timeval timeout; - struct dsrv_context_t *ctx; - int result; - - ctx = dsrv_new_context((struct sockaddr *)&listen_addr, sizeof(listen_addr), - 200,200); - - if (!ctx) { - fprintf(stderr, "E: cannot create server context\n"); - return -1; - } - - while (1) { - FD_ZERO(&rfds); - FD_ZERO(&wfds); - - dsrv_prepare(ctx, &rfds, DSRV_READ); - dsrv_prepare(ctx, &wfds, DSRV_WRITE); - -#if 0 - timeout.tv_sec = 0; - timeout.tv_usec = dsrv_get_timeout(ctx); -#else - timeout.tv_sec = 5; - timeout.tv_usec = 0; -#endif - - result = select( FD_SETSIZE, &rfds, &wfds, 0, &timeout); - - if (result < 0) { /* error */ - if (errno != EINTR) - perror("select"); - } else if (result == 0) { /* timeout */ - printf("."); - } else { /* ok */ - if (dsrv_check(ctx, &wfds, DSRV_WRITE)) - handle_write(ctx); - else if (dsrv_check(ctx, &rfds, DSRV_READ)) - handle_read(ctx); - } - } - - dsrv_close(ctx); - dsrv_free_context(ctx); - - return 0; -} diff --git a/net/ip/tinydtls/tests/dtls-client.c b/net/ip/tinydtls/tests/dtls-client.c deleted file mode 100644 index 96ed0faa9582c0188a54ce89e9e0a9b95ded6123..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/tests/dtls-client.c +++ /dev/null @@ -1,502 +0,0 @@ -#include "tinydtls.h" - -/* This is needed for apple */ -#define __APPLE_USE_RFC_3542 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "global.h" -#include "debug.h" -#include "dtls.h" - -#define DEFAULT_PORT 20220 - -#define PSK_DEFAULT_IDENTITY "Client_identity" -#define PSK_DEFAULT_KEY "secretPSK" -#define PSK_OPTIONS "i:k:" - -#ifdef __GNUC__ -#define UNUSED_PARAM __attribute__((unused)) -#else -#define UNUSED_PARAM -#endif /* __GNUC__ */ - -static char buf[200]; -static size_t len = 0; - -typedef struct { - size_t length; /* length of string */ - unsigned char *s; /* string data */ -} dtls_str; - -static dtls_str output_file = { 0, NULL }; /* output file name */ - -static dtls_context_t *dtls_context = NULL; - - -static const unsigned char ecdsa_priv_key[] = { - 0x41, 0xC1, 0xCB, 0x6B, 0x51, 0x24, 0x7A, 0x14, - 0x43, 0x21, 0x43, 0x5B, 0x7A, 0x80, 0xE7, 0x14, - 0x89, 0x6A, 0x33, 0xBB, 0xAD, 0x72, 0x94, 0xCA, - 0x40, 0x14, 0x55, 0xA1, 0x94, 0xA9, 0x49, 0xFA}; - -static const unsigned char ecdsa_pub_key_x[] = { - 0x36, 0xDF, 0xE2, 0xC6, 0xF9, 0xF2, 0xED, 0x29, - 0xDA, 0x0A, 0x9A, 0x8F, 0x62, 0x68, 0x4E, 0x91, - 0x63, 0x75, 0xBA, 0x10, 0x30, 0x0C, 0x28, 0xC5, - 0xE4, 0x7C, 0xFB, 0xF2, 0x5F, 0xA5, 0x8F, 0x52}; - -static const unsigned char ecdsa_pub_key_y[] = { - 0x71, 0xA0, 0xD4, 0xFC, 0xDE, 0x1A, 0xB8, 0x78, - 0x5A, 0x3C, 0x78, 0x69, 0x35, 0xA7, 0xCF, 0xAB, - 0xE9, 0x3F, 0x98, 0x72, 0x09, 0xDA, 0xED, 0x0B, - 0x4F, 0xAB, 0xC3, 0x6F, 0xC7, 0x72, 0xF8, 0x29}; - -#ifdef DTLS_PSK -ssize_t -read_from_file(char *arg, unsigned char *buf, size_t max_buf_len) { - FILE *f; - ssize_t result = 0; - - f = fopen(arg, "r"); - if (f == NULL) - return -1; - - while (!feof(f)) { - size_t bytes_read; - bytes_read = fread(buf, 1, max_buf_len, f); - if (ferror(f)) { - result = -1; - break; - } - - buf += bytes_read; - result += bytes_read; - max_buf_len -= bytes_read; - } - - fclose(f); - return result; -} - -/* The PSK information for DTLS */ -#define PSK_ID_MAXLEN 256 -#define PSK_MAXLEN 256 -static unsigned char psk_id[PSK_ID_MAXLEN]; -static size_t psk_id_length = 0; -static unsigned char psk_key[PSK_MAXLEN]; -static size_t psk_key_length = 0; - -/* This function is the "key store" for tinyDTLS. It is called to - * retrieve a key for the given identity within this particular - * session. */ -static int -get_psk_info(struct dtls_context_t *ctx UNUSED_PARAM, - const session_t *session UNUSED_PARAM, - dtls_credentials_type_t type, - const unsigned char *id, size_t id_len, - unsigned char *result, size_t result_length) { - - switch (type) { - case DTLS_PSK_IDENTITY: - if (id_len) { - dtls_debug("got psk_identity_hint: '%.*s'\n", id_len, id); - } - - if (result_length < psk_id_length) { - dtls_warn("cannot set psk_identity -- buffer too small\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - memcpy(result, psk_id, psk_id_length); - return psk_id_length; - case DTLS_PSK_KEY: - if (id_len != psk_id_length || memcmp(psk_id, id, id_len) != 0) { - dtls_warn("PSK for unknown id requested, exiting\n"); - return dtls_alert_fatal_create(DTLS_ALERT_ILLEGAL_PARAMETER); - } else if (result_length < psk_key_length) { - dtls_warn("cannot set psk -- buffer too small\n"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - memcpy(result, psk_key, psk_key_length); - return psk_key_length; - default: - dtls_warn("unsupported request type: %d\n", type); - } - - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); -} -#endif /* DTLS_PSK */ - -#ifdef DTLS_ECC -static int -get_ecdsa_key(struct dtls_context_t *ctx, - const session_t *session, - const dtls_ecdsa_key_t **result) { - static const dtls_ecdsa_key_t ecdsa_key = { - .curve = DTLS_ECDH_CURVE_SECP256R1, - .priv_key = ecdsa_priv_key, - .pub_key_x = ecdsa_pub_key_x, - .pub_key_y = ecdsa_pub_key_y - }; - - *result = &ecdsa_key; - return 0; -} - -static int -verify_ecdsa_key(struct dtls_context_t *ctx, - const session_t *session, - const unsigned char *other_pub_x, - const unsigned char *other_pub_y, - size_t key_size) { - return 0; -} -#endif /* DTLS_ECC */ - -static void -try_send(struct dtls_context_t *ctx, session_t *dst) { - int res; - res = dtls_write(ctx, dst, (uint8 *)buf, len); - if (res >= 0) { - memmove(buf, buf + res, len - res); - len -= res; - } -} - -static void -handle_stdin() { - if (fgets(buf + len, sizeof(buf) - len, stdin)) - len += strlen(buf + len); -} - -static int -read_from_peer(struct dtls_context_t *ctx, - session_t *session, uint8 *data, size_t len) { - size_t i; - for (i = 0; i < len; i++) - printf("%c", data[i]); - return 0; -} - -static int -send_to_peer(struct dtls_context_t *ctx, - session_t *session, uint8 *data, size_t len) { - - int fd = *(int *)dtls_get_app_data(ctx); - return sendto(fd, data, len, MSG_DONTWAIT, - &session->addr.sa, session->size); -} - -static int -dtls_handle_read(struct dtls_context_t *ctx) { - int fd; - session_t session; -#define MAX_READ_BUF 2000 - static uint8 buf[MAX_READ_BUF]; - int len; - - fd = *(int *)dtls_get_app_data(ctx); - - if (!fd) - return -1; - - memset(&session, 0, sizeof(session_t)); - session.size = sizeof(session.addr); - len = recvfrom(fd, buf, MAX_READ_BUF, 0, - &session.addr.sa, &session.size); - - if (len < 0) { - perror("recvfrom"); - return -1; - } else { - dtls_dsrv_log_addr(DTLS_LOG_DEBUG, "peer", &session); - dtls_debug_dump("bytes from peer", buf, len); - } - - return dtls_handle_message(ctx, &session, buf, len); -} - -static void dtls_handle_signal(int sig) -{ - dtls_free_context(dtls_context); - signal(sig, SIG_DFL); - kill(getpid(), sig); -} - -/* stolen from libcoap: */ -static int -resolve_address(const char *server, struct sockaddr *dst) { - - struct addrinfo *res, *ainfo; - struct addrinfo hints; - static char addrstr[256]; - int error; - - memset(addrstr, 0, sizeof(addrstr)); - if (server && strlen(server) > 0) - memcpy(addrstr, server, strlen(server)); - else - memcpy(addrstr, "localhost", 9); - - memset ((char *)&hints, 0, sizeof(hints)); - hints.ai_socktype = SOCK_DGRAM; - hints.ai_family = AF_UNSPEC; - - error = getaddrinfo(addrstr, "", &hints, &res); - - if (error != 0) { - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(error)); - return error; - } - - for (ainfo = res; ainfo != NULL; ainfo = ainfo->ai_next) { - - switch (ainfo->ai_family) { - case AF_INET6: - case AF_INET: - - memcpy(dst, ainfo->ai_addr, ainfo->ai_addrlen); - return ainfo->ai_addrlen; - default: - ; - } - } - - freeaddrinfo(res); - return -1; -} - -/*---------------------------------------------------------------------------*/ -static void -usage( const char *program, const char *version) { - const char *p; - - p = strrchr( program, '/' ); - if ( p ) - program = ++p; - - fprintf(stderr, "%s v%s -- DTLS client implementation\n" - "(c) 2011-2014 Olaf Bergmann \n\n" -#ifdef DTLS_PSK - "usage: %s [-i file] [-k file] [-o file] [-p port] [-v num] addr [port]\n" -#else /* DTLS_PSK */ - "usage: %s [-o file] [-p port] [-v num] addr [port]\n" -#endif /* DTLS_PSK */ -#ifdef DTLS_PSK - "\t-i file\t\tread PSK identity from file\n" - "\t-k file\t\tread pre-shared key from file\n" -#endif /* DTLS_PSK */ - "\t-o file\t\toutput received data to this file (use '-' for STDOUT)\n" - "\t-p port\t\tlisten on specified port (default is %d)\n" - "\t-v num\t\tverbosity level (default: 3)\n", - program, version, program, DEFAULT_PORT); -} - -static dtls_handler_t cb = { - .write = send_to_peer, - .read = read_from_peer, - .event = NULL, -#ifdef DTLS_PSK - .get_psk_info = get_psk_info, -#endif /* DTLS_PSK */ -#ifdef DTLS_ECC - .get_ecdsa_key = get_ecdsa_key, - .verify_ecdsa_key = verify_ecdsa_key -#endif /* DTLS_ECC */ -}; - -#define DTLS_CLIENT_CMD_CLOSE "client:close" -#define DTLS_CLIENT_CMD_RENEGOTIATE "client:renegotiate" - -int -main(int argc, char **argv) { - fd_set rfds, wfds; - struct timeval timeout; - unsigned short port = DEFAULT_PORT; - char port_str[NI_MAXSERV] = "0"; - log_t log_level = DTLS_LOG_WARN; - int fd, result; - int on = 1; - int opt, res; - session_t dst; - - dtls_init(); - snprintf(port_str, sizeof(port_str), "%d", port); - -#ifdef DTLS_PSK - psk_id_length = strlen(PSK_DEFAULT_IDENTITY); - psk_key_length = strlen(PSK_DEFAULT_KEY); - memcpy(psk_id, PSK_DEFAULT_IDENTITY, psk_id_length); - memcpy(psk_key, PSK_DEFAULT_KEY, psk_key_length); -#endif /* DTLS_PSK */ - - while ((opt = getopt(argc, argv, "p:o:v:" PSK_OPTIONS)) != -1) { - switch (opt) { -#ifdef DTLS_PSK - case 'i' : { - ssize_t result = read_from_file(optarg, psk_id, PSK_ID_MAXLEN); - if (result < 0) { - dtls_warn("cannot read PSK identity\n"); - } else { - psk_id_length = result; - } - break; - } - case 'k' : { - ssize_t result = read_from_file(optarg, psk_key, PSK_MAXLEN); - if (result < 0) { - dtls_warn("cannot read PSK\n"); - } else { - psk_key_length = result; - } - break; - } -#endif /* DTLS_PSK */ - case 'p' : - strncpy(port_str, optarg, NI_MAXSERV-1); - port_str[NI_MAXSERV - 1] = '\0'; - break; - case 'o' : - output_file.length = strlen(optarg); - output_file.s = (unsigned char *)malloc(output_file.length + 1); - - if (!output_file.s) { - dtls_crit("cannot set output file: insufficient memory\n"); - exit(-1); - } else { - /* copy filename including trailing zero */ - memcpy(output_file.s, optarg, output_file.length + 1); - } - break; - case 'v' : - log_level = strtol(optarg, NULL, 10); - break; - default: - usage(argv[0], dtls_package_version()); - exit(1); - } - } - - dtls_set_log_level(log_level); - - if (argc <= optind) { - usage(argv[0], dtls_package_version()); - exit(1); - } - - memset(&dst, 0, sizeof(session_t)); - /* resolve destination address where server should be sent */ - res = resolve_address(argv[optind++], &dst.addr.sa); - if (res < 0) { - dtls_emerg("failed to resolve address\n"); - exit(-1); - } - dst.size = res; - - /* use port number from command line when specified or the listen - port, otherwise */ - dst.addr.sin.sin_port = htons(atoi(optind < argc ? argv[optind++] : port_str)); - - - /* init socket and set it to non-blocking */ - fd = socket(dst.addr.sa.sa_family, SOCK_DGRAM, 0); - - if (fd < 0) { - dtls_alert("socket: %s\n", strerror(errno)); - return 0; - } - - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) < 0) { - dtls_alert("setsockopt SO_REUSEADDR: %s\n", strerror(errno)); - } -#if 0 - flags = fcntl(fd, F_GETFL, 0); - if (flags < 0 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { - dtls_alert("fcntl: %s\n", strerror(errno)); - goto error; - } -#endif - on = 1; -#ifdef IPV6_RECVPKTINFO - if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on) ) < 0) { -#else /* IPV6_RECVPKTINFO */ - if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on) ) < 0) { -#endif /* IPV6_RECVPKTINFO */ - dtls_alert("setsockopt IPV6_PKTINFO: %s\n", strerror(errno)); - } - - if (signal(SIGINT, dtls_handle_signal) == SIG_ERR) { - dtls_alert("An error occurred while setting a signal handler.\n"); - return EXIT_FAILURE; - } - - dtls_context = dtls_new_context(&fd); - if (!dtls_context) { - dtls_emerg("cannot create context\n"); - exit(-1); - } - - dtls_set_handler(dtls_context, &cb); - - dtls_connect(dtls_context, &dst); - - while (1) { - FD_ZERO(&rfds); - FD_ZERO(&wfds); - - FD_SET(fileno(stdin), &rfds); - FD_SET(fd, &rfds); - /* FD_SET(fd, &wfds); */ - - timeout.tv_sec = 5; - timeout.tv_usec = 0; - - result = select(fd+1, &rfds, &wfds, 0, &timeout); - - if (result < 0) { /* error */ - if (errno != EINTR) - perror("select"); - } else if (result == 0) { /* timeout */ - } else { /* ok */ - if (FD_ISSET(fd, &wfds)) - /* FIXME */; - else if (FD_ISSET(fd, &rfds)) - dtls_handle_read(dtls_context); - else if (FD_ISSET(fileno(stdin), &rfds)) - handle_stdin(); - } - - if (len) { - if (len >= strlen(DTLS_CLIENT_CMD_CLOSE) && - !memcmp(buf, DTLS_CLIENT_CMD_CLOSE, strlen(DTLS_CLIENT_CMD_CLOSE))) { - printf("client: closing connection\n"); - dtls_close(dtls_context, &dst); - len = 0; - } else if (len >= strlen(DTLS_CLIENT_CMD_RENEGOTIATE) && - !memcmp(buf, DTLS_CLIENT_CMD_RENEGOTIATE, strlen(DTLS_CLIENT_CMD_RENEGOTIATE))) { - printf("client: renegotiate connection\n"); - dtls_renegotiate(dtls_context, &dst); - len = 0; - } else { - try_send(dtls_context, &dst); - } - } - } - - dtls_free_context(dtls_context); - exit(0); -} - diff --git a/net/ip/tinydtls/tests/dtls-server.c b/net/ip/tinydtls/tests/dtls-server.c deleted file mode 100644 index 3f030b12525635b42d92b978623a8cbb03e7b4ac..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/tests/dtls-server.c +++ /dev/null @@ -1,366 +0,0 @@ - -/* This is needed for apple */ -#define __APPLE_USE_RFC_3542 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tinydtls.h" -#include "dtls.h" -#include "debug.h" - -#define DEFAULT_PORT 20220 - -static const unsigned char ecdsa_priv_key[] = { - 0xD9, 0xE2, 0x70, 0x7A, 0x72, 0xDA, 0x6A, 0x05, - 0x04, 0x99, 0x5C, 0x86, 0xED, 0xDB, 0xE3, 0xEF, - 0xC7, 0xF1, 0xCD, 0x74, 0x83, 0x8F, 0x75, 0x70, - 0xC8, 0x07, 0x2D, 0x0A, 0x76, 0x26, 0x1B, 0xD4}; - -static const unsigned char ecdsa_pub_key_x[] = { - 0xD0, 0x55, 0xEE, 0x14, 0x08, 0x4D, 0x6E, 0x06, - 0x15, 0x59, 0x9D, 0xB5, 0x83, 0x91, 0x3E, 0x4A, - 0x3E, 0x45, 0x26, 0xA2, 0x70, 0x4D, 0x61, 0xF2, - 0x7A, 0x4C, 0xCF, 0xBA, 0x97, 0x58, 0xEF, 0x9A}; - -static const unsigned char ecdsa_pub_key_y[] = { - 0xB4, 0x18, 0xB6, 0x4A, 0xFE, 0x80, 0x30, 0xDA, - 0x1D, 0xDC, 0xF4, 0xF4, 0x2E, 0x2F, 0x26, 0x31, - 0xD0, 0x43, 0xB1, 0xFB, 0x03, 0xE2, 0x2F, 0x4D, - 0x17, 0xDE, 0x43, 0xF9, 0xF9, 0xAD, 0xEE, 0x70}; - -#if 0 -/* SIGINT handler: set quit to 1 for graceful termination */ -void -handle_sigint(int signum) { - dsrv_stop(dsrv_get_context()); -} -#endif - -#ifdef DTLS_PSK -/* This function is the "key store" for tinyDTLS. It is called to - * retrieve a key for the given identity within this particular - * session. */ -static int -get_psk_info(struct dtls_context_t *ctx, const session_t *session, - dtls_credentials_type_t type, - const unsigned char *id, size_t id_len, - unsigned char *result, size_t result_length) { - - struct keymap_t { - unsigned char *id; - size_t id_length; - unsigned char *key; - size_t key_length; - } psk[3] = { - { (unsigned char *)"Client_identity", 15, - (unsigned char *)"secretPSK", 9 }, - { (unsigned char *)"default identity", 16, - (unsigned char *)"\x11\x22\x33", 3 }, - { (unsigned char *)"\0", 2, - (unsigned char *)"", 1 } - }; - - if (type != DTLS_PSK_KEY) { - return 0; - } - - if (id) { - int i; - for (i = 0; i < sizeof(psk)/sizeof(struct keymap_t); i++) { - if (id_len == psk[i].id_length && memcmp(id, psk[i].id, id_len) == 0) { - if (result_length < psk[i].key_length) { - dtls_warn("buffer too small for PSK"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - memcpy(result, psk[i].key, psk[i].key_length); - return psk[i].key_length; - } - } - } - - return dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR); -} - -#endif /* DTLS_PSK */ - -#ifdef DTLS_ECC -static int -get_ecdsa_key(struct dtls_context_t *ctx, - const session_t *session, - const dtls_ecdsa_key_t **result) { - static const dtls_ecdsa_key_t ecdsa_key = { - .curve = DTLS_ECDH_CURVE_SECP256R1, - .priv_key = ecdsa_priv_key, - .pub_key_x = ecdsa_pub_key_x, - .pub_key_y = ecdsa_pub_key_y - }; - - *result = &ecdsa_key; - return 0; -} - -static int -verify_ecdsa_key(struct dtls_context_t *ctx, - const session_t *session, - const unsigned char *other_pub_x, - const unsigned char *other_pub_y, - size_t key_size) { - return 0; -} -#endif /* DTLS_ECC */ - -#define DTLS_SERVER_CMD_CLOSE "server:close" -#define DTLS_SERVER_CMD_RENEGOTIATE "server:renegotiate" - -static int -read_from_peer(struct dtls_context_t *ctx, - session_t *session, uint8 *data, size_t len) { - size_t i; - for (i = 0; i < len; i++) - printf("%c", data[i]); - if (len >= strlen(DTLS_SERVER_CMD_CLOSE) && - !memcmp(data, DTLS_SERVER_CMD_CLOSE, strlen(DTLS_SERVER_CMD_CLOSE))) { - printf("server: closing connection\n"); - dtls_close(ctx, session); - return len; - } else if (len >= strlen(DTLS_SERVER_CMD_RENEGOTIATE) && - !memcmp(data, DTLS_SERVER_CMD_RENEGOTIATE, strlen(DTLS_SERVER_CMD_RENEGOTIATE))) { - printf("server: renegotiate connection\n"); - dtls_renegotiate(ctx, session); - return len; - } - - return dtls_write(ctx, session, data, len); -} - -static int -send_to_peer(struct dtls_context_t *ctx, - session_t *session, uint8 *data, size_t len) { - - int fd = *(int *)dtls_get_app_data(ctx); - return sendto(fd, data, len, MSG_DONTWAIT, - &session->addr.sa, session->size); -} - -static int -dtls_handle_read(struct dtls_context_t *ctx) { - int *fd; - session_t session; - static uint8 buf[DTLS_MAX_BUF]; - int len; - - fd = dtls_get_app_data(ctx); - - assert(fd); - - memset(&session, 0, sizeof(session_t)); - session.size = sizeof(session.addr); - len = recvfrom(*fd, buf, sizeof(buf), MSG_TRUNC, - &session.addr.sa, &session.size); - - if (len < 0) { - perror("recvfrom"); - return -1; - } else { - dtls_debug("got %d bytes from port %d\n", len, - ntohs(session.addr.sin6.sin6_port)); - if (sizeof(buf) < len) { - dtls_warn("packet was truncated (%d bytes lost)\n", len - sizeof(buf)); - } - } - - return dtls_handle_message(ctx, &session, buf, len); -} - -static int -resolve_address(const char *server, struct sockaddr *dst) { - - struct addrinfo *res, *ainfo; - struct addrinfo hints; - static char addrstr[256]; - int error; - - memset(addrstr, 0, sizeof(addrstr)); - if (server && strlen(server) > 0) - memcpy(addrstr, server, strlen(server)); - else - memcpy(addrstr, "localhost", 9); - - memset ((char *)&hints, 0, sizeof(hints)); - hints.ai_socktype = SOCK_DGRAM; - hints.ai_family = AF_UNSPEC; - - error = getaddrinfo(addrstr, "", &hints, &res); - - if (error != 0) { - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(error)); - return error; - } - - for (ainfo = res; ainfo != NULL; ainfo = ainfo->ai_next) { - - switch (ainfo->ai_family) { - case AF_INET6: - - memcpy(dst, ainfo->ai_addr, ainfo->ai_addrlen); - return ainfo->ai_addrlen; - default: - ; - } - } - - freeaddrinfo(res); - return -1; -} - -static void -usage(const char *program, const char *version) { - const char *p; - - p = strrchr( program, '/' ); - if ( p ) - program = ++p; - - fprintf(stderr, "%s v%s -- DTLS server implementation\n" - "(c) 2011-2014 Olaf Bergmann \n\n" - "usage: %s [-A address] [-p port] [-v num]\n" - "\t-A address\t\tlisten on specified address (default is ::)\n" - "\t-p port\t\tlisten on specified port (default is %d)\n" - "\t-v num\t\tverbosity level (default: 3)\n", - program, version, program, DEFAULT_PORT); -} - -static dtls_handler_t cb = { - .write = send_to_peer, - .read = read_from_peer, - .event = NULL, -#ifdef DTLS_PSK - .get_psk_info = get_psk_info, -#endif /* DTLS_PSK */ -#ifdef DTLS_ECC - .get_ecdsa_key = get_ecdsa_key, - .verify_ecdsa_key = verify_ecdsa_key -#endif /* DTLS_ECC */ -}; - -int -main(int argc, char **argv) { - dtls_context_t *the_context = NULL; - log_t log_level = DTLS_LOG_WARN; - fd_set rfds, wfds; - struct timeval timeout; - int fd, opt, result; - int on = 1; - struct sockaddr_in6 listen_addr; - - memset(&listen_addr, 0, sizeof(struct sockaddr_in6)); - - /* fill extra field for 4.4BSD-based systems (see RFC 3493, section 3.4) */ -#if defined(SIN6_LEN) || defined(HAVE_SOCKADDR_IN6_SIN6_LEN) - listen_addr.sin6_len = sizeof(struct sockaddr_in6); -#endif - - listen_addr.sin6_family = AF_INET6; - listen_addr.sin6_port = htons(DEFAULT_PORT); - listen_addr.sin6_addr = in6addr_any; - - while ((opt = getopt(argc, argv, "A:p:v:")) != -1) { - switch (opt) { - case 'A' : - if (resolve_address(optarg, (struct sockaddr *)&listen_addr) < 0) { - fprintf(stderr, "cannot resolve address\n"); - exit(-1); - } - break; - case 'p' : - listen_addr.sin6_port = htons(atoi(optarg)); - break; - case 'v' : - log_level = strtol(optarg, NULL, 10); - break; - default: - usage(argv[0], dtls_package_version()); - exit(1); - } - } - - dtls_set_log_level(log_level); - - /* init socket and set it to non-blocking */ - fd = socket(listen_addr.sin6_family, SOCK_DGRAM, 0); - - if (fd < 0) { - dtls_alert("socket: %s\n", strerror(errno)); - return 0; - } - - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) < 0) { - dtls_alert("setsockopt SO_REUSEADDR: %s\n", strerror(errno)); - } -#if 0 - flags = fcntl(fd, F_GETFL, 0); - if (flags < 0 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { - dtls_alert("fcntl: %s\n", strerror(errno)); - goto error; - } -#endif - on = 1; -#ifdef IPV6_RECVPKTINFO - if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on) ) < 0) { -#else /* IPV6_RECVPKTINFO */ - if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on) ) < 0) { -#endif /* IPV6_RECVPKTINFO */ - dtls_alert("setsockopt IPV6_PKTINFO: %s\n", strerror(errno)); - } - - if (bind(fd, (struct sockaddr *)&listen_addr, sizeof(listen_addr)) < 0) { - dtls_alert("bind: %s\n", strerror(errno)); - goto error; - } - - dtls_init(); - - the_context = dtls_new_context(&fd); - - dtls_set_handler(the_context, &cb); - - while (1) { - FD_ZERO(&rfds); - FD_ZERO(&wfds); - - FD_SET(fd, &rfds); - /* FD_SET(fd, &wfds); */ - - timeout.tv_sec = 5; - timeout.tv_usec = 0; - - result = select( fd+1, &rfds, &wfds, 0, &timeout); - - if (result < 0) { /* error */ - if (errno != EINTR) - perror("select"); - } else if (result == 0) { /* timeout */ - } else { /* ok */ - if (FD_ISSET(fd, &wfds)) - ; - else if (FD_ISSET(fd, &rfds)) { - dtls_handle_read(the_context); - } - } - } - - error: - dtls_free_context(the_context); - exit(0); -} diff --git a/net/ip/tinydtls/tests/netq-test.c b/net/ip/tinydtls/tests/netq-test.c deleted file mode 100644 index d0dc66fba33521c22de703a4c3373e2045b7d78d..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/tests/netq-test.c +++ /dev/null @@ -1,103 +0,0 @@ -#include -#include - -#include "netq.h" - -#ifndef NDEBUG -extern void nq_dump(struct netq_t *); -#endif - -int main(int argc, char **argv) { -#ifndef NDEBUG - struct netq_t *nq; - - struct sockaddr_in6 dst = { AF_INET6, htons(20220), 0, IN6ADDR_ANY_INIT, 0 }; - struct packet_t *p; - - char *pkt[20] = { - "Packet #1", - "This is packet #2", - "The third packet #3 is the largest", - "Packet #4", - "Packet #5", - "Packet #6", - "Packet #7" - }; - - nq = nq_new(200); - - if (!nq) { - fprintf(stderr, "E: cannot create network packet queue\n"); - return -1; - } - - if (!nq_new_packet(nq, (struct sockaddr *)&dst, sizeof(dst), - 0, pkt[0], strlen(pkt[0]))) { - fprintf(stderr, "E: cannot add packet #1\n"); - } - - nq_dump(nq); - - if (!nq_new_packet(nq, (struct sockaddr *)&dst, sizeof(dst), - 0, pkt[1], strlen(pkt[1]))) { - fprintf(stderr, "E: cannot add packet #2\n"); - } - - nq_dump(nq); - - if (!nq_new_packet(nq, (struct sockaddr *)&dst, sizeof(dst), - 0, pkt[2], strlen(pkt[2]))) { - fprintf(stderr, "E: cannot add packet #3\n"); - } - - nq_dump(nq); - - p = nq_pop(nq); - if (!p) { - fprintf(stderr, "E: no packet\n"); - } - - if (!nq_new_packet(nq, (struct sockaddr *)&dst, sizeof(dst), - 0, pkt[3], strlen(pkt[3]))) { - fprintf(stderr, "E: cannot add packet #4\n"); - } - - nq_dump(nq); - - if (!nq_new_packet(nq, (struct sockaddr *)&dst, sizeof(dst), - 0, pkt[4], strlen(pkt[4]))) { - fprintf(stderr, "E: cannot add packet #5\n"); - } - - nq_dump(nq); - - p = nq_pop(nq); - if (!p) { - fprintf(stderr, "E: no packet\n"); - } - - if (!nq_new_packet(nq, (struct sockaddr *)&dst, sizeof(dst), - 0, pkt[5], strlen(pkt[5]))) { - fprintf(stderr, "E: cannot add packet #6\n"); - } - - nq_dump(nq); - - p = nq_pop(nq); - p = nq_pop(nq); - p = nq_pop(nq); - p = nq_pop(nq); - p = nq_pop(nq); - p = nq_pop(nq); - p = nq_pop(nq); - - if (!nq_new_packet(nq, (struct sockaddr *)&dst, sizeof(dst), - 0, pkt[6], strlen(pkt[6]))) { - fprintf(stderr, "E: cannot add packet #7\n"); - } - - nq_dump(nq); -#endif - - return 0; -} diff --git a/net/ip/tinydtls/tests/pcap.c b/net/ip/tinydtls/tests/pcap.c deleted file mode 100644 index 7534c5fdbab369db6dfcb14ec00db2516b6a4fd3..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/tests/pcap.c +++ /dev/null @@ -1,478 +0,0 @@ -#include -#include -#include -#include - -#include "tinydtls.h" -#include "debug.h" -#include "dtls.h" - -#define TRANSPORT_HEADER_SIZE (14+20+8) /* Ethernet + IP + UDP */ - -/* the pre_master_secret is generated from the PSK at startup */ -unsigned char pre_master_secret[60]; -size_t pre_master_len = 0; - -unsigned char master_secret[DTLS_MASTER_SECRET_LENGTH]; -size_t master_secret_len = 0; - -dtls_security_parameters_t security_params[2]; -int config = 0; -unsigned int epoch[2] = { 0, 0 }; - -#if DTLS_VERSION == 0xfeff -dtls_hash_t hs_hash[2]; -#elif DTLS_VERSION == 0xfefd -dtls_hash_t hs_hash[1]; -#endif - -static inline void -update_hash(uint8 *record, size_t rlength, - uint8 *data, size_t data_length) { - int i; - - if (!hs_hash[0]) - return; - - for (i = 0; i < sizeof(hs_hash) / sizeof(dtls_hash_t *); ++i) { - dtls_hash_update(hs_hash[i], data, data_length); - } -} - -static inline void -finalize_hash(uint8 *buf) { -#if DTLS_VERSION == 0xfeff - unsigned char statebuf[sizeof(md5_state_t) + sizeof(SHA_CTX)]; -#elif DTLS_VERSION == 0xfefd - unsigned char statebuf[sizeof(SHA256_CTX)]; -#endif - - if (!hs_hash[0]) - return; - - /* temporarily store hash status for roll-back after finalize */ -#if DTLS_VERSION == 0xfeff - memcpy(statebuf, hs_hash[0], sizeof(md5_state_t)); - memcpy(statebuf + sizeof(md5_state_t), - hs_hash[1], - sizeof(SHA_CTX)); -#elif DTLS_VERSION == 0xfefd - memcpy(statebuf, hs_hash[0], sizeof(statebuf)); -#endif - - dtls_hash_finalize(buf, hs_hash[0]); -#if DTLS_VERSION == 0xfeff - dtls_hash_finalize(buf + 16, hs_hash[1]); -#endif - - /* restore hash status */ -#if DTLS_VERSION == 0xfeff - memcpy(hs_hash[0], statebuf, sizeof(md5_state_t)); - memcpy(hs_hash[1], - statebuf + sizeof(md5_state_t), - sizeof(SHA_CTX)); -#elif DTLS_VERSION == 0xfefd - memcpy(hs_hash[0], statebuf, sizeof(statebuf)); -#endif -} - -static inline void -clear_hash() { - int i; - - for (i = 0; i < sizeof(hs_hash) / sizeof(dtls_hash_t *); ++i) - free(hs_hash[i]); - memset(hs_hash, 0, sizeof(hs_hash)); -} - -#undef CURRENT_CONFIG -#undef OTHER_CONFIG -#undef SWITCH_CONFIG -#define CURRENT_CONFIG (&security_params[config]) -#define OTHER_CONFIG (&security_params[!(config & 0x01)]) -#define SWITCH_CONFIG (config = !(config & 0x01)) - -int -pcap_verify(dtls_security_parameters_t *sec, - int is_client, - const unsigned char *record, size_t record_length, - const unsigned char *cleartext, size_t cleartext_length) { - - unsigned char mac[DTLS_HMAC_MAX]; - dtls_hmac_context_t hmac_ctx; - int ok; - - if (cleartext_length < dtls_kb_digest_size(sec)) - return 0; - - dtls_hmac_init(&hmac_ctx, - is_client - ? dtls_kb_client_mac_secret(sec) - : dtls_kb_server_mac_secret(sec), - dtls_kb_mac_secret_size(sec)); - - cleartext_length -= dtls_kb_digest_size(sec); - - /* calculate MAC even if padding is wrong */ - dtls_mac(&hmac_ctx, - record, /* the pre-filled record header */ - cleartext, cleartext_length, - mac); - - ok = memcmp(mac, cleartext + cleartext_length, - dtls_kb_digest_size(sec)) == 0; -#ifndef NDEBUG - printf("MAC (%s): ", ok ? "valid" : "invalid"); - dump(mac, dtls_kb_digest_size(sec)); - printf("\n"); -#endif - return ok; -} - -int -decrypt_verify(int is_client, const uint8 *packet, size_t length, - uint8 **cleartext, size_t *clen) { - int res, ok = 0; - dtls_cipher_context_t *cipher; - - static unsigned char buf[1000]; - - switch (CURRENT_CONFIG->cipher) { - case AES128: /* TLS_PSK_WITH_AES128_CBC_SHA */ - *cleartext = buf; - *clen = length - sizeof(dtls_record_header_t); - - if (is_client) - cipher = CURRENT_CONFIG->read_cipher; - else - cipher = CURRENT_CONFIG->write_cipher; - - res = dtls_decrypt(cipher, - (uint8 *)packet + sizeof(dtls_record_header_t), *clen, - buf, NULL, 0); - - if (res < 0) { - warn("decryption failed!\n"); - } else { - ok = pcap_verify(CURRENT_CONFIG, is_client, (uint8 *)packet, length, - *cleartext, res); - - if (ok) - *clen = res - dtls_kb_digest_size(CURRENT_CONFIG); - } - break; - default: /* no cipher suite selected */ - *cleartext = (uint8 *)packet + sizeof(dtls_record_header_t); - *clen = length - sizeof(dtls_record_header_t); - - ok = 1; - } - - if (ok) - printf("verify OK\n"); - else - printf("verification failed!\n"); - return ok; -} - -#define SKIP_ETH_HEADER(M,L) \ - if ((L) < 14) \ - return; \ - else { \ - (M) += 14; \ - (L) -= 14; \ - } - -#define SKIP_IP_HEADER(M,L) \ - if (((M)[0] & 0xF0) == 0x40) { /* IPv4 */ \ - (M) += (M[0] & 0x0F) * 4; \ - (L) -= (M[0] & 0x0F) * 4; \ - } else \ - if (((M)[0] & 0xF0) == 0x60) { /* IPv6 */ \ - (M) += 40; \ - (L) -= 40; \ - } - -#define SKIP_UDP_HEADER(M,L) { \ - (M) += 8; \ - (L) -= 8; \ - } - -void -handle_packet(const u_char *packet, int length) { - static int n = 0; - static unsigned char initial_hello[] = { - 0x16, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - uint8 *data; - size_t data_length, rlen; - int i, res; -#if DTLS_VERSION == 0xfeff -#ifndef SHA1_DIGEST_LENGTH -#define SHA1_DIGEST_LENGTH 20 -#endif - uint8 hash_buf[16 + SHA1_DIGEST_LENGTH]; -#elif DTLS_VERSION == 0xfefd - uint8 hash_buf[SHA256_DIGEST_LENGTH]; -#endif -#define verify_data_length 12 - int is_client; - n++; - - SKIP_ETH_HEADER(packet, length); - SKIP_IP_HEADER(packet, length); - - /* determine from port if this is a client */ - is_client = dtls_uint16_to_int(packet) != 20220; - - SKIP_UDP_HEADER(packet, length); - - while (length) { - rlen = dtls_uint16_to_int(packet + 11) + sizeof(dtls_record_header_t); - - if (!rlen) { - fprintf(stderr, "invalid length!\n"); - return; - } - - /* skip packet if it is from a different epoch */ - if (dtls_uint16_to_int(packet + 3) != epoch[is_client]) - goto next; - - res = decrypt_verify(is_client, packet, rlen, - &data, &data_length); - - if (res <= 0) - goto next; - - printf("packet %d (from %s):\n", n, is_client ? "client" : "server"); - hexdump(packet, sizeof(dtls_record_header_t)); - printf("\n"); - hexdump(data, data_length); - printf("\n"); - - if (packet[0] == 22 && data[0] == 1) { /* ClientHello */ - if (memcmp(packet, initial_hello, sizeof(initial_hello)) == 0) - goto next; - - memcpy(dtls_kb_client_iv(OTHER_CONFIG), data + 14, 32); - - clear_hash(); -#if DTLS_VERSION == 0xfeff - hs_hash[0] = dtls_new_hash(HASH_MD5); - hs_hash[1] = dtls_new_hash(HASH_SHA1); - - hs_hash[0]->init(hs_hash[0]->data); - hs_hash[1]->init(hs_hash[1]->data); -#elif DTLS_VERSION == 0xfefd - dtls_hash_init(hs_hash[0]); -#endif - } - - if (packet[0] == 22 && data[0] == 2) { /* ServerHello */ - memcpy(dtls_kb_server_iv(OTHER_CONFIG), data + 14, 32); - /* FIXME: search in ciphers */ - OTHER_CONFIG->cipher = TLS_PSK_WITH_AES_128_CCM_8; - } - - if (packet[0] == 20 && data[0] == 1) { /* ChangeCipherSpec */ - printf("client random: "); - dump(dtls_kb_client_iv(OTHER_CONFIG), 32); - printf("\nserver random: "); - dump(dtls_kb_server_iv(OTHER_CONFIG), 32); - printf("\n"); - master_secret_len = - dtls_prf(pre_master_secret, pre_master_len, - (unsigned char *)"master secret", 13, - dtls_kb_client_iv(OTHER_CONFIG), 32, - dtls_kb_server_iv(OTHER_CONFIG), 32, - master_secret, DTLS_MASTER_SECRET_LENGTH); - - printf("master_secret:\n "); - for(i = 0; i < master_secret_len; i++) - printf("%02x", master_secret[i]); - printf("\n"); - - /* create key_block from master_secret - * key_block = PRF(master_secret, - "key expansion" + server_random + client_random) */ - dtls_prf(master_secret, master_secret_len, - (unsigned char *)"key expansion", 13, - dtls_kb_server_iv(OTHER_CONFIG), 32, - dtls_kb_client_iv(OTHER_CONFIG), 32, - OTHER_CONFIG->key_block, - dtls_kb_size(OTHER_CONFIG)); - - OTHER_CONFIG->read_cipher = - dtls_cipher_new(OTHER_CONFIG->cipher, - dtls_kb_client_write_key(OTHER_CONFIG), - dtls_kb_key_size(OTHER_CONFIG)); - - if (!OTHER_CONFIG->read_cipher) { - warn("cannot create read cipher\n"); - } else { - dtls_cipher_set_iv(OTHER_CONFIG->read_cipher, - dtls_kb_client_iv(OTHER_CONFIG), - dtls_kb_iv_size(OTHER_CONFIG)); - } - - OTHER_CONFIG->write_cipher = - dtls_cipher_new(OTHER_CONFIG->cipher, - dtls_kb_server_write_key(OTHER_CONFIG), - dtls_kb_key_size(OTHER_CONFIG)); - - if (!OTHER_CONFIG->write_cipher) { - warn("cannot create write cipher\n"); - } else { - dtls_cipher_set_iv(OTHER_CONFIG->write_cipher, - dtls_kb_server_iv(OTHER_CONFIG), - dtls_kb_iv_size(OTHER_CONFIG)); - } - - /* if (is_client) */ - SWITCH_CONFIG; - epoch[is_client]++; - - printf("key_block:\n"); - printf(" client_MAC_secret:\t"); - dump(dtls_kb_client_mac_secret(CURRENT_CONFIG), - dtls_kb_mac_secret_size(CURRENT_CONFIG)); - printf("\n"); - - printf(" server_MAC_secret:\t"); - dump(dtls_kb_server_mac_secret(CURRENT_CONFIG), - dtls_kb_mac_secret_size(CURRENT_CONFIG)); - printf("\n"); - - printf(" client_write_key:\t"); - dump(dtls_kb_client_write_key(CURRENT_CONFIG), - dtls_kb_key_size(CURRENT_CONFIG)); - printf("\n"); - - printf(" server_write_key:\t"); - dump(dtls_kb_server_write_key(CURRENT_CONFIG), - dtls_kb_key_size(CURRENT_CONFIG)); - printf("\n"); - - printf(" client_IV:\t\t"); - dump(dtls_kb_client_iv(CURRENT_CONFIG), - dtls_kb_iv_size(CURRENT_CONFIG)); - printf("\n"); - - printf(" server_IV:\t\t"); - dump(dtls_kb_server_iv(CURRENT_CONFIG), - dtls_kb_iv_size(CURRENT_CONFIG)); - printf("\n"); - - } - - if (packet[0] == 22) { - if (data[0] == 20) { /* Finished */ - finalize_hash(hash_buf); - /* clear_hash(); */ - - update_hash((unsigned char *)packet, sizeof(dtls_record_header_t), - data, data_length); - - dtls_prf(master_secret, master_secret_len, - is_client - ? (unsigned char *)"client finished" - : (unsigned char *)"server finished" - , 15, - hash_buf, sizeof(hash_buf), - NULL, 0, - data + sizeof(dtls_handshake_header_t), - verify_data_length); - printf("verify_data:\n"); - dump(data, data_length); - printf("\n"); - } else { - update_hash((unsigned char *)packet, sizeof(dtls_record_header_t), - data, data_length); - } - } - - if (packet[0] == 23) { /* Application Data */ - printf("Application Data:\n"); - dump(data, data_length); - printf("\n"); - } - - next: - length -= rlen; - packet += rlen; - } -} - -void init() { - memset(security_params, 0, sizeof(security_params)); - CURRENT_CONFIG->cipher = -1; - - memset(hs_hash, 0, sizeof(hs_hash)); - - /* set pre_master_secret to default if no PSK was given */ - if (!pre_master_len) { - /* unsigned char psk[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; */ - pre_master_len = - dtls_pre_master_secret((unsigned char *)"secretPSK", 9, - pre_master_secret); - } -} - -int main(int argc, char **argv) { - pcap_t *pcap; - char errbuf[PCAP_ERRBUF_SIZE]; - struct pcap_pkthdr *pkthdr; - const u_char *packet; - int res = 0; - int c, option_index = 0; - - static struct option opts[] = { - { "psk", 1, 0, 'p' }, - { 0, 0, 0, 0 } - }; - - /* handle command line options */ - while (1) { - c = getopt_long(argc, argv, "p:", opts, &option_index); - if (c == -1) - break; - - switch (c) { - case 'p': - pre_master_len = dtls_pre_master_secret((unsigned char *)optarg, - strlen(optarg), pre_master_secret); - break; - } - } - - if (argc <= optind) { - fprintf(stderr, "usage: %s [-p|--psk PSK] pcapfile\n", argv[0]); - return -1; - } - - init(); - - pcap = pcap_open_offline(argv[optind], errbuf); - if (!pcap) { - fprintf(stderr, "pcap_open_offline: %s\n", errbuf); - return -2; - } - - for (;;) { - res = pcap_next_ex(pcap, &pkthdr, &packet); - - switch(res) { - case -2: goto done; - case -1: pcap_perror(pcap, "read packet"); break; - case 1: handle_packet(packet, pkthdr->caplen); break; - default: - ; - } - } - done: - - pcap_close(pcap); - - return 0; -} diff --git a/net/ip/tinydtls/tests/prf-test.c b/net/ip/tinydtls/tests/prf-test.c deleted file mode 100644 index d8d83d9f0d55a981ff9dfc6b69daecb7ef2b82db..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/tests/prf-test.c +++ /dev/null @@ -1,31 +0,0 @@ -#include - -#include "tinydtls.h" -#include "debug.h" -#include "global.h" -#include "crypto.h" - -int -main() { - /* see http://www.ietf.org/mail-archive/web/tls/current/msg03416.html */ - unsigned char key[] = { 0x9b, 0xbe, 0x43, 0x6b, 0xa9, 0x40, 0xf0, 0x17, - 0xb1, 0x76, 0x52, 0x84, 0x9a, 0x71, 0xdb, 0x35 }; - unsigned char label[] = { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6c, 0x61, 0x62, - 0x65, 0x6c}; - unsigned char random1[] = { 0xa0, 0xba, 0x9f, 0x93, 0x6c, 0xda, 0x31, 0x18}; - unsigned char random2[] = {0x27, 0xa6, 0xf7, 0x96, 0xff, 0xd5, 0x19, 0x8c - }; - unsigned char buf[200]; - size_t result; - - result = dtls_prf(key, sizeof(key), - label, sizeof(label), - random1, sizeof(random1), - random2, sizeof(random2), - buf, 100); - - printf("PRF yields %zu bytes of random data:\n", result); - hexdump(buf, result); - printf("\n"); - return 0; -} diff --git a/net/ip/tinydtls/tests/secure-server.c b/net/ip/tinydtls/tests/secure-server.c deleted file mode 100644 index 6ba525875b9c41333d693dee13d1906e95754bd6..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/tests/secure-server.c +++ /dev/null @@ -1,862 +0,0 @@ -/* secure-server -- A (broken) DTLS server example - * - * Copyright (C) 2011 Olaf Bergmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef WITH_DTLS -#define SERVER_CERT_PEM "./server-cert.pem" -#define SERVER_KEY_PEM "./server-key.pem" -#define CA_CERT_PEM "./ca-cert.pem" -#endif - -#ifdef HAVE_ASSERT_H -# include -#else -# define assert(x) -#endif /* HAVE_ASSERT_H */ - -static int quit=0; - -/* SIGINT handler: set quit to 1 for graceful termination */ -void -handle_sigint(int signum) { - quit = 1; -} - -int -check_connect(int sockfd, char *buf, int buflen, - struct sockaddr *src, int *ifindex) { - - /* for some reason, the definition in netinet/in.h is not exported */ -#ifndef IN6_PKTINFO - struct in6_pktinfo - { - struct in6_addr ipi6_addr; /* src/dst IPv6 address */ - unsigned int ipi6_ifindex; /* send/recv interface index */ - }; -#endif - - size_t bytes; - - struct iovec iov[1] = { {buf, buflen} }; - char cmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; - struct in6_pktinfo *p = NULL; - - struct msghdr msg = { 0 }; - struct cmsghdr *cmsg; - - msg.msg_name = src; - msg.msg_namelen = sizeof(struct sockaddr_in6); - msg.msg_iov = iov; - msg.msg_iovlen = 1; - msg.msg_control = cmsgbuf; - msg.msg_controllen = sizeof(cmsgbuf); - - bytes = recvmsg(sockfd, &msg, MSG_DONTWAIT | MSG_PEEK); - if (bytes < 0) { - perror("recvmsg"); - return bytes; - } - - /* TODO: handle msg.msg_flags & MSG_TRUNC */ - if (msg.msg_flags & MSG_CTRUNC) { - fprintf(stderr, "control was truncated!\n"); - return -1; - } - - if (ifindex) { - /* Here we try to retrieve the interface index where the packet was received */ - *ifindex = 0; - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) { - p = (struct in6_pktinfo *)(CMSG_DATA(cmsg)); - *ifindex = p->ipi6_ifindex; - break; - } - } - } - - return bytes; -} - -typedef enum { UNKNOWN=0, DTLS=1 } protocol_t; - -protocol_t -demux_protocol(const char *buf, int len) { - return DTLS; -} - -#ifdef WITH_DTLS -typedef enum { - PEER_ST_ESTABLISHED, PEER_ST_PENDING, PEER_ST_CLOSED - } peer_state_t; -typedef struct { - peer_state_t state; - unsigned long h; - SSL *ssl; -} ssl_peer_t; - -#define MAX_SSL_PENDING 2 /* must be less than MAX_SSL_PEERS */ -#define MAX_SSL_PEERS 10 /* MAX_SSL_PENDING of these might be pending */ -ssl_peer_t *ssl_peer_storage[MAX_SSL_PEERS]; -static int pending = 0; - -void -check_peers() { -typedef struct bio_dgram_data_st - { - union { - struct sockaddr sa; - struct sockaddr_in sa_in; - struct sockaddr_in6 sa_in6; - } peer; - unsigned int connected; - unsigned int _errno; - unsigned int mtu; - struct timeval next_timeout; - struct timeval socket_timeout; - } bio_dgram_data; - - struct sockaddr_in6 peer; - int i; - BIO *bio; - for (i = 0; i < MAX_SSL_PEERS; i++) { - if (ssl_peer_storage[i]) { - if (!ssl_peer_storage[i]->ssl) - fprintf(stderr, "invalid SSL object for peer %d!\n",i); - else { - bio = SSL_get_rbio(ssl_peer_storage[i]->ssl); - if (bio) { - (void) BIO_dgram_get_peer(bio, (struct sockaddr *)&peer); - if (peer.sin6_port && ssl_peer_storage[i]->h != ntohs(peer.sin6_port)) { - fprintf(stderr, " bio %p: port differs from hash: %d != %d! (%sconnected)\n", bio, - ssl_peer_storage[i]->h, - ntohs(((struct sockaddr_in6 *)&peer)->sin6_port), - ((bio_dgram_data *)bio->ptr)->connected ? "" : "not "); - } - - } - } - } - } -} - -/** Creates a hash value from the first num bytes of s, taking init as - * initialization value. */ -static inline unsigned long -_hash(unsigned long init, const char *s, int num) { - int c; - - while (num--) - while ( (c = *s++) ) { - init = ((init << 7) + init) + c; - } - - return init; -} - -static inline unsigned long -hash_peer(const struct sockaddr *peer, int ifindex) { - unsigned long h; - - /* initialize hash value to interface index */ - h = _hash(0, (char *)&ifindex, sizeof(int)); - -#define CAST(TYPE,VAR) ((TYPE)VAR) - - assert(peer); - switch (peer->sa_family) { - case AF_INET: - return ntohs(CAST(const struct sockaddr_in *, peer)->sin_port); - h = _hash(h, (char *) &CAST(const struct sockaddr_in *, peer)->sin_addr, - sizeof(struct in_addr)); - h = _hash(h, (char *) &CAST(const struct sockaddr_in *, peer)->sin_port, - sizeof(in_port_t)); - break; - case AF_INET6: - return ntohs(CAST(const struct sockaddr_in6 *, peer)->sin6_port); - h = _hash(h, - (char *) &CAST(const struct sockaddr_in6 *, peer)->sin6_addr, - sizeof(struct in6_addr)); - h = _hash(h, - (char *) &CAST(const struct sockaddr_in6 *, peer)->sin6_port, - sizeof(in_port_t)); - break; - default: - /* last resort */ - h = _hash(h, (char *)peer, sizeof(struct sockaddr)); - } - - return 42; - return h; -} - -/* Returns index of peer object for specified address/ifindex pair. */ -int -get_index_of_peer(const struct sockaddr *peer, int ifindex) { - unsigned long h; - int idx; -#ifndef NDEBUG - char addr[INET6_ADDRSTRLEN]; - char port[6]; -#endif - - if (!peer) - return -1; - - h = hash_peer(peer,ifindex); - - for (idx = 0; idx < MAX_SSL_PEERS; idx++) { - if (ssl_peer_storage[idx] && ssl_peer_storage[idx]->h == h) { -#ifndef NDEBUG - getnameinfo((struct sockaddr *)peer, sizeof(struct sockaddr_in6), - addr, sizeof(addr), port, sizeof(port), - NI_NUMERICHOST | NI_NUMERICSERV); - - fprintf(stderr, "get_index_of_peer: [%s]:%s => %lu\n", - addr, port, h); -#endif - return idx; - } - } - return -1; -} - -SSL * -get_ssl(SSL_CTX *ctx, int sockfd, struct sockaddr *src, int ifindex) { - int idx; - BIO *bio; - SSL *ssl; -#ifndef NDEBUG - struct sockaddr_storage peer; - char addr[INET6_ADDRSTRLEN]; - char port[6]; - int i; -#endif - - idx = get_index_of_peer(src,ifindex); - if (idx >= 0) { - fprintf(stderr,"found peer %d ",idx); - switch (ssl_peer_storage[idx]->state) { - case PEER_ST_ESTABLISHED: fprintf(stderr,"established\n"); break; - case PEER_ST_PENDING: fprintf(stderr,"pending\n"); break; - case PEER_ST_CLOSED: fprintf(stderr,"closed\n"); break; - default: - OPENSSL_assert(0); - } - -#ifndef NDEBUG - memset(&peer, 0, sizeof(peer)); - (void) BIO_dgram_get_peer(SSL_get_rbio(ssl_peer_storage[idx]->ssl), &peer); - - getnameinfo((struct sockaddr *)&peer, sizeof(peer), - addr, sizeof(addr), port, sizeof(port), - NI_NUMERICHOST | NI_NUMERICSERV); - - fprintf(stderr," [%s]:%s \n", addr, port); -#endif - return ssl_peer_storage[idx]->ssl; - } - - /* none found, create new if sufficient space available */ - if (pending < MAX_SSL_PENDING) { - for (idx = 0; idx < MAX_SSL_PEERS; idx++) { - if (ssl_peer_storage[idx] == NULL) { /* found space */ - ssl = SSL_new(ctx); - - if (ssl) { - bio = BIO_new_dgram(sockfd, BIO_NOCLOSE); - if (!bio) { - SSL_free(ssl); - return NULL; - } - - SSL_set_bio(ssl, bio, bio); - SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE); - - SSL_set_accept_state(ssl); - ssl_peer_storage[idx] = (ssl_peer_t *) malloc(sizeof(ssl_peer_t)); - if (!ssl_peer_storage[idx]) { - SSL_free(ssl); - return NULL; - } - ssl_peer_storage[idx]->state = PEER_ST_PENDING; - ssl_peer_storage[idx]->h = hash_peer(src,ifindex); - ssl_peer_storage[idx]->ssl = ssl; - - pending++; - - fprintf(stderr, - "created new SSL peer %d for ssl object %p (storage: %p)\n", - idx, ssl, ssl_peer_storage[idx]); -#ifndef NDEBUG - if (getnameinfo((struct sockaddr *)&src, sizeof(src), - addr, sizeof(addr), port, sizeof(port), - NI_NUMERICHOST | NI_NUMERICSERV) != 0) { - perror("getnameinfo"); - fprintf(stderr, "port was %u\n", ntohs(((struct sockaddr_in6 *)src)->sin6_port)); - } else { - fprintf(stderr," [%s]:%s \n", addr, port); - } -#endif - OPENSSL_assert(ssl_peer_storage[idx]->ssl == ssl); - fprintf(stderr,"%d objects pending\n", pending); - check_peers(); - return ssl; - } - } - } - } else { - fprintf(stderr, "too many pending SSL objects\n"); - return NULL; - } - - fprintf(stderr, "too many peers\n"); - return NULL; -} - -/** Deletes peer stored at index idx and frees allocated memory. */ -static inline void -delete_peer(int idx) { - if (idx < 0 || !ssl_peer_storage[idx]) - return; - - if (ssl_peer_storage[idx]->state == PEER_ST_PENDING) - pending--; - - OPENSSL_assert(ssl_peer_storage[idx]->ssl); - SSL_free(ssl_peer_storage[idx]->ssl); - - free(ssl_peer_storage[idx]); - ssl_peer_storage[idx] = NULL; - - printf("deleted peer %d\n",idx); -} - -/** Deletes all closed objects from ssl_peer_storage. */ -void -remove_closed() { - int idx; - - for (idx = 0; idx < MAX_SSL_PEERS; idx++) - if (ssl_peer_storage[idx] - && ssl_peer_storage[idx]->state == PEER_ST_CLOSED) - delete_peer(idx); -} - -#define min(a,b) ((a) < (b) ? (a) : (b)) - -unsigned int -psk_server_callback(SSL *ssl, const char *identity, - unsigned char *psk, unsigned int max_psk_len) { - static char keybuf[] = "secretPSK"; - - printf("psk_server_callback: check identity of client %s\n", identity); - memcpy(psk, keybuf, min(strlen(keybuf), max_psk_len)); - - return min(strlen(keybuf), max_psk_len); -} - -#endif - -#ifdef WITH_DTLS -/** - * This function tracks the status changes from libssl to manage local - * object state. - */ -void -info_callback(const SSL *ssl, int where, int ret) { - int idx, i; - struct sockaddr_storage peer; - struct sockaddr_storage peer2; - char addr[INET6_ADDRSTRLEN]; - char port[6]; - - if (where & SSL_CB_LOOP) /* do not care for intermediary states */ - return; - - memset(&peer, 0, sizeof(peer)); - (void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); - - /* lookup SSL object */ /* FIXME: need to get the ifindex */ - idx = get_index_of_peer((struct sockaddr *)&peer, 0); - - if (idx >= 0) - fprintf(stderr, "info_callback: assert: %d < 0 || %p == %p (storage: %p)\n", - idx, ssl, ssl_peer_storage[idx]->ssl, ssl_peer_storage[idx]); - if (idx >= 0 && ssl != ssl_peer_storage[idx]->ssl) { - getnameinfo((struct sockaddr *)&peer, sizeof(peer), - addr, sizeof(addr), port, sizeof(port), - NI_NUMERICHOST | NI_NUMERICSERV); - - fprintf(stderr," ssl: [%s]:%s ", addr, port); - - (void) BIO_dgram_get_peer(SSL_get_rbio(ssl_peer_storage[idx]->ssl), &peer2); - getnameinfo((struct sockaddr *)&peer2, sizeof(peer2), - addr, sizeof(addr), port, sizeof(port), - NI_NUMERICHOST | NI_NUMERICSERV); - - fprintf(stderr," ssl_peer_storage[idx]->ssl: [%s]:%s\n", addr, port); - - fprintf(stderr, " hash:%lu h: %lu\n", - hash_peer((const struct sockaddr *)&peer, 0), - ssl_peer_storage[idx]->h); - - for (i = 0; i < MAX_SSL_PEERS; i++) { - if (ssl_peer_storage[i]) { - fprintf(stderr, "%02d: %p ssl: %p ", - i, ssl_peer_storage[i] ,ssl_peer_storage[i]->ssl); - - (void) BIO_dgram_get_peer(SSL_get_rbio(ssl_peer_storage[i]->ssl), &peer2); - getnameinfo((struct sockaddr *)&peer2, sizeof(peer2), - addr, sizeof(addr), port, sizeof(port), - NI_NUMERICHOST | NI_NUMERICSERV); - - fprintf(stderr," peer: [%s]:%s h: %lu\n", addr, port, ssl_peer_storage[i]->h); - } - } - fprintf(stderr, "***** ASSERT FAILED ******\n"); - - memset(&peer, 0, sizeof(peer)); - (void) BIO_dgram_get_peer(SSL_get_wbio(ssl), &peer); - - idx = get_index_of_peer((struct sockaddr *)&peer, 0); - fprintf(stderr, " get_index_of_peer for wbio returns %d, type is %04x\n", - idx, where); - } -#if 1 - check_peers(); - OPENSSL_assert((idx < 0) || (ssl == ssl_peer_storage[idx]->ssl)); -#endif - - if (where & SSL_CB_ALERT) { -#ifndef NDEBUG - if (ret != 0) - fprintf(stderr,"%s:%s:%s\n", SSL_alert_type_string(ret), - SSL_alert_desc_string(ret), SSL_alert_desc_string_long(ret)); -#endif - - /* examine alert type */ - switch (*SSL_alert_type_string(ret)) { - case 'F': - /* move SSL object from pending to close */ - if (idx >= 0) { - ssl_peer_storage[idx]->state = PEER_ST_CLOSED; - pending--; - } - break; - case 'W': - if ((ret & 0xff) == SSL_AD_CLOSE_NOTIFY) { - if (where == SSL_CB_WRITE_ALERT) - fprintf(stderr,"sent CLOSE_NOTIFY\n"); - else /* received CN */ - fprintf(stderr,"received CLOSE_NOTIFY\n"); - } - break; - default: /* handle unknown alert types */ -#ifndef NDEBUG - printf("not handled!\n"); -#endif - } - } - - if (where & SSL_CB_HANDSHAKE_DONE) { - /* move SSL object from pending to established */ - printf("HANDSHAKE_DONE "); - if (idx >= 0) { - - if (ssl_peer_storage[idx]->state == PEER_ST_PENDING) { - ssl_peer_storage[idx]->state = PEER_ST_ESTABLISHED; - pending--; - printf("moved SSL object %d to ESTABLISHED\n", idx); - printf("%d objects pending\n", pending); - } else { -#ifndef NDEBUG - printf("huh, object %d was not pending? (%d)\n", idx, - ssl_peer_storage[idx]->state); -#endif - } - return; - } - return; - } - - return; -} -#endif - -#ifdef WITH_DTLS -/* checks if ssl object was closed and can be removed */ -int -check_close(SSL *ssl) { - int res, err, idx; - struct sockaddr_storage peer; - - memset(&peer, 0, sizeof(peer)); - (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); - - res = 0; - if (SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN) { - printf("SSL_RECEIVED_SHUTDOWN\n"); - res = SSL_shutdown(ssl); - if (res == 0) { - printf("must call SSL_shutdown again\n"); - res = SSL_shutdown(ssl); - } - if (res < 0) { - err = SSL_get_error(ssl,res); - fprintf(stderr, "shutdown: SSL error %d: %s\n", err, - ERR_error_string(err, NULL)); - } - - /* we can close the SSL object anyway */ - /* FIXME: need to get ifindex from somewhere */ - idx = get_index_of_peer((struct sockaddr *)&peer, 0); - OPENSSL_assert(idx < 0 || ssl == ssl_peer_storage[idx]->ssl); - if (idx >= 0) { - ssl_peer_storage[idx]->state = PEER_ST_CLOSED; - printf("moved SSL object %d to CLOSED\n",idx); - } - } - - return res; -} - -int -check_timeout() { - int i, result, err; - - for (i = 0; i < MAX_SSL_PEERS; i++) { - if (ssl_peer_storage[i]) { - OPENSSL_assert(ssl_peer_storage[i]->ssl); - result = DTLSv1_handle_timeout(ssl_peer_storage[i]->ssl); - if (result < 0) { - err = SSL_get_error(ssl_peer_storage[i]->ssl,result); - fprintf(stderr, "dtls1_handle_timeout (%d): %s\n", - err, ERR_error_string(err, NULL)); - } - } - } - - /* remove outdated obbjects? */ - - return 0; -} -#endif /* WITH_DTLS */ - -int -_read(SSL_CTX *ctx, int sockfd) { - char buf[2000]; - struct sockaddr_in6 src; - int len, ifindex, i; - char addr[INET6_ADDRSTRLEN]; - char port[6]; - socklen_t sz = sizeof(struct sockaddr_in6); -#ifdef WITH_DTLS - SSL *ssl; - int err; -#endif - - /* Retrieve remote address and interface index as well as the first - few bytes of the message to demultiplex protocols. */ - memset(&src, 0, sizeof(struct sockaddr_in6)); - len = check_connect(sockfd, buf, 4, (struct sockaddr *)&src, &ifindex); - - if (len < 0) /* error */ - return len; - -#ifndef NDEBUG - fprintf(stderr,"received packet"); - - if (getnameinfo((struct sockaddr *)&src, sizeof(src), - addr, sizeof(addr), port, sizeof(port), - NI_NUMERICHOST | NI_NUMERICSERV) == 0) - fprintf(stderr," from [%s]:%s", addr, port); - - fprintf(stderr," on interface %d\n", ifindex); -#endif - - switch (demux_protocol(buf, len)) { -#ifdef WITH_DTLS - case DTLS : - ssl = get_ssl(ctx, sockfd, (struct sockaddr *)&src, ifindex); - if (!ssl) { - fprintf(stderr, "cannot create new SSL object\n"); - /* return recv(sockfd, buf, sizeof(buf), MSG_DONTWAIT);*/ - len = recvfrom(sockfd, buf, sizeof(buf), MSG_DONTWAIT, - (struct sockaddr *)&src, &sz); - getnameinfo((struct sockaddr *)&src, sz, - addr, sizeof(addr), port, sizeof(port), - NI_NUMERICHOST | NI_NUMERICSERV); - printf("discarded %d bytes from [%s]:%s\n", len, addr, port); - return len; - } - len = SSL_read(ssl, buf, sizeof(buf)); - break; -#endif - case UNKNOWN: - default : - len = recv(sockfd, buf, sizeof(buf), MSG_DONTWAIT); - } - - if (len > 0) { - printf("here is the data:\n"); - for (i=0; i 0) { /* read from socket */ - if ( FD_ISSET( sockfd, &fds[READ]) ) { - _read(ctx, sockfd); /* read received data */ - } else if ( FD_ISSET( sockfd, &fds[WRITE]) ) { /* write to socket */ - _write(ctx, sockfd); /* write data */ - } - } else { /* timeout */ - check_timeout(); - } - remove_closed(); - } - - end: -#ifdef WITH_DTLS - for (idx = 0; idx < MAX_SSL_PEERS; idx++) { - if (ssl_peer_storage[idx] && ssl_peer_storage[idx]->ssl) { - if (ssl_peer_storage[idx]->state == PEER_ST_ESTABLISHED) - SSL_shutdown(ssl_peer_storage[idx]->ssl); - SSL_free(ssl_peer_storage[idx]->ssl); - } - } - - SSL_CTX_free(ctx); -#endif - close(sockfd); /* don't care if we close stdin at this point */ - return res; -} diff --git a/net/ip/tinydtls/tinydtls.h b/net/ip/tinydtls/tinydtls.h deleted file mode 100644 index 95900d0ca996be1984c7037c7d7ffaf3d765d956..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/tinydtls.h +++ /dev/null @@ -1,45 +0,0 @@ -/* tinydtls.h. Generated from tinydtls.h.in by configure. */ -/* tinydtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2014 Olaf Bergmann - * Copyright (C) 2013 Hauke Mehrtens - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * @file tinydtls.h - * @brief public tinydtls API - */ - -#ifndef _DTLS_TINYDTLS_H_ -#define _DTLS_TINYDTLS_H_ - -/** Defined to 1 if tinydtls is built with support for ECC */ -#define DTLS_ECC 1 - -/** Defined to 1 if tinydtls is built with support for PSK */ -#define DTLS_PSK 1 - -/** Defined to 1 if tinydtls is built for Contiki OS */ -#define WITH_CONTIKI 1 - -#endif /* _DTLS_TINYDTLS_H_ */ diff --git a/net/ip/tinydtls/tinydtls.h.in b/net/ip/tinydtls/tinydtls.h.in deleted file mode 100644 index a2e6685feb4052e549f1c1a78933bc2b692d74ac..0000000000000000000000000000000000000000 --- a/net/ip/tinydtls/tinydtls.h.in +++ /dev/null @@ -1,44 +0,0 @@ -/* tinydtls -- a very basic DTLS implementation - * - * Copyright (C) 2011--2014 Olaf Bergmann - * Copyright (C) 2013 Hauke Mehrtens - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * @file tinydtls.h - * @brief public tinydtls API - */ - -#ifndef _DTLS_TINYDTLS_H_ -#define _DTLS_TINYDTLS_H_ - -/** Defined to 1 if tinydtls is built with support for ECC */ -#undef DTLS_ECC - -/** Defined to 1 if tinydtls is built with support for PSK */ -#undef DTLS_PSK - -/** Defined to 1 if tinydtls is built for Contiki OS */ -#undef WITH_CONTIKI - -#endif /* _DTLS_TINYDTLS_H_ */ diff --git a/samples/bluetooth/ipsp/src/Makefile b/samples/bluetooth/ipsp/src/Makefile index 617ff39f7130a86f9debfaa0b46f2a5a5754e332..8fa7c344f60785322bffef1e8950d51314e5f89e 100644 --- a/samples/bluetooth/ipsp/src/Makefile +++ b/samples/bluetooth/ipsp/src/Makefile @@ -1,7 +1,3 @@ -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os/lib -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os -ccflags-y +=-I${ZEPHYR_BASE}/net/ip ccflags-y +=-I${ZEPHYR_BASE}/samples/bluetooth obj-y = main.o ../../gatt/ipss.o diff --git a/samples/bluetooth/ipsp/testcase.ini b/samples/bluetooth/ipsp/testcase.ini index 64b66bf18e7722ffa07bef48936ab0c4699d0a26..d2d5a4102c3070915857cad90267a8490800bb09 100644 --- a/samples/bluetooth/ipsp/testcase.ini +++ b/samples/bluetooth/ipsp/testcase.ini @@ -2,3 +2,4 @@ tags = bluetooth net build_only = true platform_whitelist = qemu_x86 qemu_cortex_m3 +skip = true diff --git a/samples/net/coap_observe_client/Makefile b/samples/net/coap_observe_client/Makefile deleted file mode 100644 index 226d667a4197f40706d1fbe2331cf79eaa4278fe..0000000000000000000000000000000000000000 --- a/samples/net/coap_observe_client/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# Makefile - coap observe client test application - -# -# Copyright (c) 2015 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -NET_IFACE ?= slip -MDEF_FILE = prj.mdef -BOARD ?= qemu_x86 -CONF_FILE ?= prj_$(NET_IFACE).conf - -include $(ZEPHYR_BASE)/Makefile.inc - -ifeq ($(CONFIG_NETWORKING_WITH_BT), y) - QEMU_EXTRA_FLAGS = -serial unix:/tmp/bt-server-bredr -else - include $(ZEPHYR_BASE)/samples/net/common/Makefile.ipstack -endif diff --git a/samples/net/coap_observe_client/prj.mdef b/samples/net/coap_observe_client/prj.mdef deleted file mode 100644 index 2e6dcf75c2a5696fc9c3169802f4a31c0ecbe883..0000000000000000000000000000000000000000 --- a/samples/net/coap_observe_client/prj.mdef +++ /dev/null @@ -1,5 +0,0 @@ -% Application : Network listener - -% TASK NAME PRIO ENTRY STACK GROUPS -% =================================================== - TASK MAIN 7 startup 2048 [EXE] diff --git a/samples/net/coap_observe_client/prj_802154.conf b/samples/net/coap_observe_client/prj_802154.conf deleted file mode 100644 index a7ddf96421563aa540259ee06d5b6257edaaf8e9..0000000000000000000000000000000000000000 --- a/samples/net/coap_observe_client/prj_802154.conf +++ /dev/null @@ -1,12 +0,0 @@ -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_NETWORKING_WITH_15_4=y -CONFIG_NETWORKING_WITH_15_4_TI_CC2520=y -CONFIG_NETWORKING_WITH_6LOWPAN=y -CONFIG_6LOWPAN_COMPRESSION_IPHC=y -CONFIG_IP_BUF_RX_SIZE=3 -CONFIG_IP_BUF_TX_SIZE=5 -CONFIG_ER_COAP=y -CONFIG_ER_COAP_CLIENT=y -CONFIG_ER_COAP_DEBUG=y diff --git a/samples/net/coap_observe_client/prj_bt.conf b/samples/net/coap_observe_client/prj_bt.conf deleted file mode 100644 index 99865d52cdcda20fb963132b625bf450da4c7f20..0000000000000000000000000000000000000000 --- a/samples/net/coap_observe_client/prj_bt.conf +++ /dev/null @@ -1,8 +0,0 @@ -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_NETWORKING_WITH_BT=y -CONFIG_IP_BUF_RX_SIZE=5 -CONFIG_IP_BUF_TX_SIZE=3 -CONFIG_ER_COAP=y -CONFIG_ER_COAP_CLIENT=y -CONFIG_ER_COAP_DEBUG=y diff --git a/samples/net/coap_observe_client/prj_slip.conf b/samples/net/coap_observe_client/prj_slip.conf deleted file mode 100644 index bb4a9421d1f1bbf9261a4c47714f53ffa3545ade..0000000000000000000000000000000000000000 --- a/samples/net/coap_observe_client/prj_slip.conf +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_NETWORKING_UART=y -CONFIG_IP_BUF_RX_SIZE=3 -CONFIG_IP_BUF_TX_SIZE=5 -CONFIG_NANO_TIMEOUTS=y -CONFIG_NANO_TIMERS=y -CONFIG_ER_COAP=y -CONFIG_ER_COAP_CLIENT=y -CONFIG_ER_COAP_DEBUG=y -CONFIG_NET_TESTING=y -CONFIG_NETWORKING_IPV6_NO_ND=y diff --git a/samples/net/coap_observe_client/src/Makefile b/samples/net/coap_observe_client/src/Makefile deleted file mode 100644 index 4f489743e82ae01599dee5a2ad0865a7f2747a1e..0000000000000000000000000000000000000000 --- a/samples/net/coap_observe_client/src/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -ccflags-y +=-I${ZEPHYR_BASE}/net/ip -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os/lib -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os/sys -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/tinydtls -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/er-coap -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/rest-engine -ccflags-y +=-I${ZEPHYR_BASE}/samples/bluetooth/ - -obj-y = coap-observe-client.o - -ifeq ($(CONFIG_NETWORKING_WITH_BT), y) - obj-y += ../../../bluetooth/gatt/ipss.o -endif - -ifeq ($(CONFIG_NET_TESTING), y) -ccflags-y +=-I${ZEPHYR_BASE}/samples/net/common/ -ccflags-y +=-DNET_TESTING_SERVER=0 -endif diff --git a/samples/net/coap_observe_client/src/coap-observe-client.c b/samples/net/coap_observe_client/src/coap-observe-client.c deleted file mode 100644 index 19c419ae83b9b3519f944372092ae39190b9d986..0000000000000000000000000000000000000000 --- a/samples/net/coap_observe_client/src/coap-observe-client.c +++ /dev/null @@ -1,367 +0,0 @@ -/* coap-observe-client.c - Observe a remote resource */ - -/* - * Copyright (c) 2015 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined(CONFIG_STDOUT_CONSOLE) -#include -#define PRINT printf -#else -#include -#define PRINT printk -#endif - -#if defined(CONFIG_TINYDTLS_DEBUG) -#define DEBUG DEBUG_FULL -#else -#define DEBUG DEBUG_PRINT -#endif -#include "contiki/ip/uip-debug.h" - -#include - -#include - -#include - -#include -#include - -#include "er-coap-engine.h" -#include "er-coap-observe-client.h" - -#include -#include - -#if defined(CONFIG_NET_TESTING) -#include -#endif - -#if defined(CONFIG_NANOKERNEL) -#define STACKSIZE 2000 -char fiberStack[STACKSIZE]; -#endif - -static coap_observee_t *obs; - -#if defined(CONFIG_NETWORKING_WITH_IPV6) -/* admin-local, dynamically allocated multicast address */ -#define MCAST_IPADDR { { { 0xff, 0x84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2 } } } - -/* Define the peer IP address where to send messages */ -#if !defined(CONFIG_NET_TESTING) -#define PEER_IPADDR { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 } } } -#define MY_IPADDR { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2 } } } - -#endif - -#else /* CONFIG_NETWORKING_WITH_IPV6 */ - -#error "IPv4 not supported at the moment, fix me!" - -/* Organization-local 239.192.0.0/14 */ -#define MCAST_IPADDR { { { 239, 192, 0, 2 } } } - -#if !defined(CONFIG_NET_TESTING) -#define PEER_IPADDR { { { 192, 0, 2, 1 } } } -#endif - -#endif /* CONFIG_NETWORKING_WITH_IPV6 */ - -#define MY_PORT 8484 -#define PEER_PORT COAP_DEFAULT_PORT - -/* The path of the resource to observe */ -//#define OBS_RESOURCE_URI "test/push" -#define OBS_RESOURCE_URI "time" - -/* Toggle interval in seconds */ -#define TOGGLE_INTERVAL 5 - -#if defined(CONFIG_NETWORKING_WITH_IPV6) -static const struct in6_addr in6addr_peer = PEER_IPADDR; -static struct in6_addr in6addr_my = MY_IPADDR; -#else -static struct in_addr in4addr_peer = PEER_IPADDR; -static struct in_addr in4addr_my = MY_IPADDR; -#endif - -static inline void init_app(void) -{ - PRINT("%s: run coap observe client\n", __func__); - -#if defined(CONFIG_NET_TESTING) - net_testing_setup(); -#endif -} - -#if defined(DTLS_PSK) -/* This function is the "key store" for tinyDTLS. It is called to - * retrieve a key for the given identity within this particular - * session. */ -static int get_psk_info(struct dtls_context_t *ctx, - const session_t *session, - dtls_credentials_type_t type, - const unsigned char *id, size_t id_len, - unsigned char *result, size_t result_length) -{ - struct keymap_t { - unsigned char *id; - size_t id_length; - unsigned char *key; - size_t key_length; - } psk[3] = { - { (unsigned char *)"Client_identity", 15, - (unsigned char *)"secretPSK", 9 }, - { (unsigned char *)"default identity", 16, - (unsigned char *)"\x11\x22\x33", 3 }, - { (unsigned char *)"\0", 2, - (unsigned char *)"", 1 } - }; - - if (type != DTLS_PSK_KEY) { - return 0; - } - - if (id) { - int i; - for (i = 0; i < sizeof(psk)/sizeof(struct keymap_t); i++) { - if (id_len == psk[i].id_length && - memcmp(id, psk[i].id, id_len) == 0) { - if (result_length < psk[i].key_length) { - PRINTF("buffer too small for PSK"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - memcpy(result, psk[i].key, psk[i].key_length); - return psk[i].key_length; - } - } - } - - return dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR); -} -#else -#define get_psk_info NULL -#endif /* DTLS_PSK */ - -#if defined(DTLS_ECC) -const unsigned char ecdsa_priv_key[] = { - 0xD9, 0xE2, 0x70, 0x7A, 0x72, 0xDA, 0x6A, 0x05, - 0x04, 0x99, 0x5C, 0x86, 0xED, 0xDB, 0xE3, 0xEF, - 0xC7, 0xF1, 0xCD, 0x74, 0x83, 0x8F, 0x75, 0x70, - 0xC8, 0x07, 0x2D, 0x0A, 0x76, 0x26, 0x1B, 0xD4}; - -const unsigned char ecdsa_pub_key_x[] = { - 0xD0, 0x55, 0xEE, 0x14, 0x08, 0x4D, 0x6E, 0x06, - 0x15, 0x59, 0x9D, 0xB5, 0x83, 0x91, 0x3E, 0x4A, - 0x3E, 0x45, 0x26, 0xA2, 0x70, 0x4D, 0x61, 0xF2, - 0x7A, 0x4C, 0xCF, 0xBA, 0x97, 0x58, 0xEF, 0x9A}; - -const unsigned char ecdsa_pub_key_y[] = { - 0xB4, 0x18, 0xB6, 0x4A, 0xFE, 0x80, 0x30, 0xDA, - 0x1D, 0xDC, 0xF4, 0xF4, 0x2E, 0x2F, 0x26, 0x31, - 0xD0, 0x43, 0xB1, 0xFB, 0x03, 0xE2, 0x2F, 0x4D, - 0x17, 0xDE, 0x43, 0xF9, 0xF9, 0xAD, 0xEE, 0x70}; - -static int get_ecdsa_key(struct dtls_context_t *ctx, - const session_t *session, - const dtls_ecdsa_key_t **result) -{ - static const dtls_ecdsa_key_t ecdsa_key = { - .curve = DTLS_ECDH_CURVE_SECP256R1, - .priv_key = ecdsa_priv_key, - .pub_key_x = ecdsa_pub_key_x, - .pub_key_y = ecdsa_pub_key_y - }; - - *result = &ecdsa_key; - return 0; -} - -static int verify_ecdsa_key(struct dtls_context_t *ctx, - const session_t *session, - const unsigned char *other_pub_x, - const unsigned char *other_pub_y, - size_t key_size) -{ - return 0; -} -#else -#define get_ecdsa_key NULL -#define verify_ecdsa_key NULL -#endif /* DTLS_ECC */ - -/* - * Handle the response to the observe request and the following notifications - */ -static void notification_callback(coap_observee_t *obs, void *notification, - coap_notification_flag_t flag) -{ - int len = 0; - const uint8_t *payload = NULL; - - PRINT("Notification handler\n"); - PRINT("Observee URI: %s\n", obs->url); - if(notification) { - len = coap_get_payload(notification, &payload); - } - switch(flag) { - case NOTIFICATION_OK: - PRINT("NOTIFICATION OK: %*s\n", len, (char *)payload); - break; - case OBSERVE_OK: /* server accepeted observation request */ - PRINT("OBSERVE_OK: %*s\n", len, (char *)payload); - break; - case OBSERVE_NOT_SUPPORTED: - PRINT("OBSERVE_NOT_SUPPORTED: %*s\n", len, (char *)payload); - obs = NULL; - break; - case ERROR_RESPONSE_CODE: - PRINT("ERROR_RESPONSE_CODE: %*s\n", len, (char *)payload); - obs = NULL; - break; - case NO_REPLY_FROM_SERVER: - PRINT("NO_REPLY_FROM_SERVER: " - "removing observe registration with token %x%x\n", - obs->token[0], obs->token[1]); - obs = NULL; - break; - } -} - -/* - * Toggle the observation of the remote resource - */ -void toggle_observation(coap_context_t *coap_ctx) -{ - if(obs) { - PRINT("Stopping observation\n"); - coap_obs_remove_observee(obs); - obs = NULL; - } else { - PRINT("Starting observation\n"); - obs = coap_obs_request_registration(coap_ctx, - (uip_ipaddr_t *)&in6addr_peer, - PEER_PORT, - OBS_RESOURCE_URI, - notification_callback, - NULL); - } -} - -#define WAIT_TIME 1 -#define WAIT_TICKS (WAIT_TIME * sys_clock_ticks_per_sec) - -#if 0 -#define WAIT_PEER (5 * sys_clock_ticks_per_sec) -#else -#define WAIT_PEER TICKS_UNLIMITED -#endif - -PROCESS(coap_observe_client_process, "CoAP observe client process"); -PROCESS_THREAD(coap_observe_client_process, ev, data, buf, user_data) -{ - PROCESS_BEGIN(); - - while(1) { - PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_TIMER); - /* Currently the timeout is handled in while loop in startup() */ - } - PROCESS_END(); -} - -void startup(void) -{ - static struct etimer et; - static coap_context_t *coap_ctx; - bool first_round = true; - - net_init(); - - coap_init_engine(); - coap_init_mid(); - - init_app(); - -#if defined(CONFIG_NETWORKING_WITH_BT) - if (bt_enable(NULL)) { - PRINT("Bluetooth init failed\n"); - return; - } - ipss_init(); - ipss_advertise(); -#endif - - coap_ctx = coap_context_new((uip_ipaddr_t *)&in6addr_my, MY_PORT); - if (!coap_ctx) { - PRINT("Cannot get CoAP context.\n"); - return; - } - - coap_context_set_key_handlers(coap_ctx, - get_psk_info, - get_ecdsa_key, - verify_ecdsa_key); - - if (!coap_context_connect(coap_ctx, - (uip_ipaddr_t *)&in6addr_peer, - PEER_PORT)) { - PRINT("Cannot connect to peer.\n"); - return; - } - - etimer_set(&et, TOGGLE_INTERVAL * sys_clock_ticks_per_sec, - &coap_observe_client_process); - - while (1) { - while (!coap_context_is_connected(coap_ctx)) { - PRINT("Trying to connect to peer...\n"); - if (!coap_context_wait_data(coap_ctx, WAIT_TICKS)) { - continue; - } - } - - if(first_round || etimer_expired(&et)) { - PRINT("--Toggle timer--\n"); - toggle_observation(coap_ctx); - PRINT("--Done--\n"); - etimer_restart(&et); - first_round = false; - } - - if (coap_context_wait_data(coap_ctx, WAIT_TICKS)) { -#if defined(CONFIG_NANOKERNEL) - /* Print the stack usage only if we did something */ - net_analyze_stack("CoAP observe client", - fiberStack, STACKSIZE); -#endif - } - - coap_check_transactions(); - } - coap_context_close(coap_ctx); -} - -#if defined(CONFIG_NANOKERNEL) - -void main(void) -{ - fiber_start(&fiberStack[0], STACKSIZE, - (nano_fiber_entry_t)startup, 0, 0, 7, 0); -} - -#endif /* CONFIG_NANOKERNEL */ diff --git a/samples/net/coap_observe_client/testcase.ini b/samples/net/coap_observe_client/testcase.ini deleted file mode 100644 index 754a05ea35d0054b16f4f99a9f04abfece1ba968..0000000000000000000000000000000000000000 --- a/samples/net/coap_observe_client/testcase.ini +++ /dev/null @@ -1,12 +0,0 @@ -[test] -tags = net -build_only = true -arch_whitelist = x86 -platform_whitelist = qemu_x86 - -[test_bt] -tags = net bluetooth -build_only = true -extra_args = CONF_FILE="prj_bt.conf" -arch_whitelist = x86 -platform_whitelist = qemu_x86 diff --git a/samples/net/coap_server/Makefile b/samples/net/coap_server/Makefile deleted file mode 100644 index db5a9b3010bed79a8f93ad66c990a188fd14d3a4..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# Makefile - coap server test application - -# -# Copyright (c) 2015 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -NET_IFACE ?= slip -MDEF_FILE = prj.mdef -BOARD ?= qemu_x86 -CONF_FILE ?= prj_$(NET_IFACE).conf - -include $(ZEPHYR_BASE)/Makefile.inc - -ifeq ($(CONFIG_NETWORKING_WITH_BT), y) - QEMU_EXTRA_FLAGS = -serial unix:/tmp/bt-server-bredr -else - include $(ZEPHYR_BASE)/samples/net/common/Makefile.ipstack -endif diff --git a/samples/net/coap_server/prj.mdef b/samples/net/coap_server/prj.mdef deleted file mode 100644 index 6ff2267623cc521d7aa60cf45be6259e8f0622fc..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/prj.mdef +++ /dev/null @@ -1,5 +0,0 @@ -% Application : coap server - -% TASK NAME PRIO ENTRY STACK GROUPS -% =================================================== - TASK MAIN 7 startup 2048 [EXE] diff --git a/samples/net/coap_server/prj_802154.conf b/samples/net/coap_server/prj_802154.conf deleted file mode 100644 index e93c651ee9056d24b2985512e467214f478a180d..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/prj_802154.conf +++ /dev/null @@ -1,10 +0,0 @@ -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_IP_BUF_RX_SIZE=3 -CONFIG_IP_BUF_TX_SIZE=4 -CONFIG_NETWORKING_WITH_15_4=y -CONFIG_NETWORKING_WITH_15_4_TI_CC2520=y -CONFIG_NETWORKING_WITH_6LOWPAN=y -CONFIG_6LOWPAN_COMPRESSION_IPHC=y -CONFIG_ER_COAP=y -CONFIG_ER_COAP_DEBUG=y diff --git a/samples/net/coap_server/prj_bt.conf b/samples/net/coap_server/prj_bt.conf deleted file mode 100644 index 5e36ca37f778ae644f8f735256a219d2de6c3993..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/prj_bt.conf +++ /dev/null @@ -1,7 +0,0 @@ -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_NETWORKING_WITH_BT=y -CONFIG_IP_BUF_RX_SIZE=5 -CONFIG_IP_BUF_TX_SIZE=3 -CONFIG_ER_COAP=y -CONFIG_ER_COAP_DEBUG=y diff --git a/samples/net/coap_server/prj_slip.conf b/samples/net/coap_server/prj_slip.conf deleted file mode 100644 index 09535b9e34d12b8851bdf715facdcdfff1d9ccae..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/prj_slip.conf +++ /dev/null @@ -1,10 +0,0 @@ -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_NETWORKING_UART=y -CONFIG_IP_BUF_RX_SIZE=3 -CONFIG_IP_BUF_TX_SIZE=4 -CONFIG_ER_COAP=y -CONFIG_ER_COAP_DEBUG=y -CONFIG_NET_TESTING=y -CONFIG_NETWORKING_IPV6_NO_ND=y diff --git a/samples/net/coap_server/src/Makefile b/samples/net/coap_server/src/Makefile deleted file mode 100644 index b2707850ab987ce6717d4c5ed74c90d060a04ac3..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os/lib -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os/sys -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/tinydtls -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/er-coap -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/rest-engine -ccflags-y +=-I${ZEPHYR_BASE}/net/ip -ccflags-y +=-I${ZEPHYR_BASE}/samples/bluetooth/ - -obj-y = coap-server.o - -ifeq ($(CONFIG_NETWORKING_WITH_BT), y) - obj-y += ../../../bluetooth/gatt/ipss.o -endif - -ifeq ($(CONFIG_NET_TESTING), y) -ccflags-y +=-I${ZEPHYR_BASE}/samples/net/common/ -ccflags-y +=-DNET_TESTING_SERVER=1 -endif - -obj-y += \ - resources/res-plugtest-create1.o \ - resources/res-plugtest-create2.o \ - resources/res-plugtest-create3.o \ - resources/res-plugtest-large.o \ - resources/res-plugtest-large-create.o \ - resources/res-plugtest-large-update.o \ - resources/res-plugtest-links.o \ - resources/res-plugtest-locquery.o \ - resources/res-plugtest-longpath.o \ - resources/res-plugtest-multi.o \ - resources/res-plugtest-obs.o \ - resources/res-plugtest-path.o \ - resources/res-plugtest-query.o \ - resources/res-plugtest-separate.o \ - resources/res-plugtest-test.o \ - resources/res-plugtest-validate.o diff --git a/samples/net/coap_server/src/coap-server.c b/samples/net/coap_server/src/coap-server.c deleted file mode 100644 index 52ee0a512979bc07c8ed59fb2b2afd5cda56f42f..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/coap-server.c +++ /dev/null @@ -1,322 +0,0 @@ -/* coap-server.c - Erbium REST engine example */ - -/* - * Copyright (c) 2015 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined(CONFIG_STDOUT_CONSOLE) -#include -#define PRINT printf -#else -#include -#define PRINT printk -#endif - -#if defined(CONFIG_TINYDTLS_DEBUG) -#define DEBUG DEBUG_FULL -#else -#define DEBUG DEBUG_PRINT -#endif -#include "contiki/ip/uip-debug.h" - -#include - -#if defined(CONFIG_NANOKERNEL) -#if defined(CONFIG_TINYDTLS) -/* DTLS needs bigger stack */ -#define STACKSIZE 2500 -#else -#define STACKSIZE 1700 -#endif -char fiberStack[STACKSIZE]; -#endif - -#include - -#include - -#include -#include - -#include "contiki/ipv6/uip-ds6.h" -#include "rest-engine.h" -#include "er-coap.h" -#include "er-coap-engine.h" - -#if defined(CONFIG_TINYDTLS_DEBUG) -#include -#endif - -#include -#include - -#if defined(CONFIG_NET_TESTING) -#include -#endif - -#if defined(CONFIG_ER_COAP_WITH_DTLS) -#define MY_PORT COAP_DEFAULT_SECURE_PORT -#else -#define MY_PORT COAP_DEFAULT_PORT -#endif - -#define PEER_PORT 0 - -static inline void init_app(void) -{ - PRINT("%s: run coap server\n", __func__); - -#if defined(CONFIG_NET_TESTING) - net_testing_setup(); -#endif -} - -#if defined(DTLS_PSK) -/* This function is the "key store" for tinyDTLS. It is called to - * retrieve a key for the given identity within this particular - * session. */ -static int get_psk_info(struct dtls_context_t *ctx, - const session_t *session, - dtls_credentials_type_t type, - const unsigned char *id, size_t id_len, - unsigned char *result, size_t result_length) -{ - struct keymap_t { - unsigned char *id; - size_t id_length; - unsigned char *key; - size_t key_length; - } psk[3] = { - { (unsigned char *)"Client_identity", 15, - (unsigned char *)"secretPSK", 9 }, - { (unsigned char *)"default identity", 16, - (unsigned char *)"\x11\x22\x33", 3 }, - { (unsigned char *)"\0", 2, - (unsigned char *)"", 1 } - }; - - if (type != DTLS_PSK_KEY) { - return 0; - } - - if (id) { - int i; - for (i = 0; i < sizeof(psk)/sizeof(struct keymap_t); i++) { - if (id_len == psk[i].id_length && - memcmp(id, psk[i].id, id_len) == 0) { - if (result_length < psk[i].key_length) { - PRINTF("buffer too small for PSK"); - return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); - } - - memcpy(result, psk[i].key, psk[i].key_length); - return psk[i].key_length; - } - } - } - - return dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR); -} -#else -#define get_psk_info NULL -#endif /* DTLS_PSK */ - -#if defined(DTLS_ECC) -const unsigned char ecdsa_priv_key[] = { - 0xD9, 0xE2, 0x70, 0x7A, 0x72, 0xDA, 0x6A, 0x05, - 0x04, 0x99, 0x5C, 0x86, 0xED, 0xDB, 0xE3, 0xEF, - 0xC7, 0xF1, 0xCD, 0x74, 0x83, 0x8F, 0x75, 0x70, - 0xC8, 0x07, 0x2D, 0x0A, 0x76, 0x26, 0x1B, 0xD4}; - -const unsigned char ecdsa_pub_key_x[] = { - 0xD0, 0x55, 0xEE, 0x14, 0x08, 0x4D, 0x6E, 0x06, - 0x15, 0x59, 0x9D, 0xB5, 0x83, 0x91, 0x3E, 0x4A, - 0x3E, 0x45, 0x26, 0xA2, 0x70, 0x4D, 0x61, 0xF2, - 0x7A, 0x4C, 0xCF, 0xBA, 0x97, 0x58, 0xEF, 0x9A}; - -const unsigned char ecdsa_pub_key_y[] = { - 0xB4, 0x18, 0xB6, 0x4A, 0xFE, 0x80, 0x30, 0xDA, - 0x1D, 0xDC, 0xF4, 0xF4, 0x2E, 0x2F, 0x26, 0x31, - 0xD0, 0x43, 0xB1, 0xFB, 0x03, 0xE2, 0x2F, 0x4D, - 0x17, 0xDE, 0x43, 0xF9, 0xF9, 0xAD, 0xEE, 0x70}; - -static int get_ecdsa_key(struct dtls_context_t *ctx, - const session_t *session, - const dtls_ecdsa_key_t **result) -{ - static const dtls_ecdsa_key_t ecdsa_key = { - .curve = DTLS_ECDH_CURVE_SECP256R1, - .priv_key = ecdsa_priv_key, - .pub_key_x = ecdsa_pub_key_x, - .pub_key_y = ecdsa_pub_key_y - }; - - *result = &ecdsa_key; - return 0; -} - -static int verify_ecdsa_key(struct dtls_context_t *ctx, - const session_t *session, - const unsigned char *other_pub_x, - const unsigned char *other_pub_y, - size_t key_size) -{ - return 0; -} -#else -#define get_ecdsa_key NULL -#define verify_ecdsa_key NULL -#endif /* DTLS_ECC */ - -#if 0 -#define WAIT_TIME 1 -#define WAIT_TICKS (WAIT_TIME * sys_clock_ticks_per_sec) -#else -#define WAIT_TICKS TICKS_UNLIMITED -#endif - -extern resource_t - res_plugtest_test, - res_plugtest_validate, - res_plugtest_create1, - res_plugtest_create2, - res_plugtest_create3, - res_plugtest_longpath, - res_plugtest_query, - res_plugtest_locquery, - res_plugtest_multi, - res_plugtest_link1, - res_plugtest_link2, - res_plugtest_link3, - res_plugtest_path, - res_plugtest_separate, - res_plugtest_large, - res_plugtest_large_update, - res_plugtest_large_create, - res_plugtest_obs; - -void startup(void) -{ - static coap_context_t *coap_ctx; - static struct net_addr any_addr; - static struct net_addr my_addr; - -#if defined(CONFIG_NETWORKING_WITH_IPV6) - static const struct in6_addr in6addr_my = IN6ADDR_ANY_INIT; - static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; - - any_addr.in6_addr = in6addr_any; - any_addr.family = AF_INET6; - - my_addr.in6_addr = in6addr_my; - my_addr.family = AF_INET6; -#else - any_addr.in_addr = in4addr_any; - any_addr.family = AF_INET; - - my_addr.in_addr = in4addr_my; - my_addr.family = AF_INET; -#endif - - PRINT("Starting ETSI IoT Plugtests Server\n"); - - PRINT("uIP buffer: %u\n", UIP_BUFSIZE); - PRINT("LL header: %u\n", UIP_LLH_LEN); - PRINT("IP+UDP header: %u\n", UIP_IPUDPH_LEN); - PRINT("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE); - - net_init(); - - rest_init_engine(); - -#if defined(CONFIG_TINYDTLS_DEBUG) - dtls_set_log_level(DTLS_LOG_DEBUG); -#endif - - init_app(); - -#if defined(CONFIG_NETWORKING_WITH_BT) - if (bt_enable(NULL)) { - PRINT("Bluetooth init failed\n"); - return; - } - ipss_init(); - ipss_advertise(); -#endif - - /* Activate the application-specific resources. */ - rest_activate_resource(&res_plugtest_test, "test"); - rest_activate_resource(&res_plugtest_longpath, "seg1/seg2/seg3"); - rest_activate_resource(&res_plugtest_query, "query"); - -#if NOT_SUPPORTED - /* These are not supported atm. */ - rest_activate_resource(&res_plugtest_separate, "separate"); -#endif - -#if 0 - /* Currently these are not activated. */ - rest_activate_resource(&res_plugtest_validate, "validate"); - rest_activate_resource(&res_plugtest_create1, "create1"); - rest_activate_resource(&res_plugtest_create2, "create2"); - rest_activate_resource(&res_plugtest_create3, "create3"); - rest_activate_resource(&res_plugtest_locquery, "location-query"); - rest_activate_resource(&res_plugtest_multi, "multi-format"); - rest_activate_resource(&res_plugtest_link1, "link1"); - rest_activate_resource(&res_plugtest_link2, "link2"); - rest_activate_resource(&res_plugtest_link3, "link3"); - rest_activate_resource(&res_plugtest_path, "path"); - rest_activate_resource(&res_plugtest_large, "large"); - rest_activate_resource(&res_plugtest_large_update, "large-update"); - rest_activate_resource(&res_plugtest_large_create, "large-create"); - rest_activate_resource(&res_plugtest_obs, "obs"); -#endif - -#if defined(CONFIG_NETWORKING_WITH_IPV6) - coap_ctx = coap_init_server((uip_ipaddr_t *)&my_addr.in6_addr, - MY_PORT, - (uip_ipaddr_t *)&any_addr.in6_addr, - PEER_PORT); -#else - coap_ctx = coap_init_server((uip_ipaddr_t *)&my_addr.in4_addr, - MY_PORT, - (uip_ipaddr_t *)&any_addr.in4_addr, - PEER_PORT); -#endif - - coap_context_set_key_handlers(coap_ctx, - get_psk_info, - get_ecdsa_key, - verify_ecdsa_key); - - /* Read requests and pass them to rest engine */ - while (1) { - if (coap_context_wait_data(coap_ctx, WAIT_TICKS)) { -#if defined(CONFIG_NANOKERNEL) - /* Print the stack usage only if we did something */ - net_analyze_stack("CoAP server", fiberStack, STACKSIZE); -#endif - } - coap_check_transactions(); - } -} - -#if defined(CONFIG_NANOKERNEL) -void main(void) -{ - fiber_start(&fiberStack[0], STACKSIZE, - (nano_fiber_entry_t)startup, 0, 0, 7, 0); -} -#endif diff --git a/samples/net/coap_server/src/er-plugtest.h b/samples/net/coap_server/src/er-plugtest.h deleted file mode 100644 index da059638f5780353ebab72f5ceebfd6ca598064c..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/er-plugtest.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Erbium (Er) CoAP client example - * \author - * Matthias Kovatsch - */ - -#ifndef __ER_PLUGTEST_H__ -#define __ER_PLUGTEST_H__ - -#ifndef DEBUG -#define DEBUG DEBUG_NONE -#endif -#include "contiki/ip/uip-debug.h" - -/* double expansion */ -#define TO_STRING2(x) # x -#define TO_STRING(x) TO_STRING2(x) - -#define MAX_PLUGFEST_PAYLOAD 64 + 1 /* +1 for the terminating zero, which is not transmitted */ -#define MAX_PLUGFEST_BODY 2048 -#define CHUNKS_TOTAL 2012 - -#endif /* __ER_PLUGTEST_H__ */ diff --git a/samples/net/coap_server/src/resources/res-plugtest-create1.c b/samples/net/coap_server/src/resources/res-plugtest-create1.c deleted file mode 100644 index 4ba5f6181d95d0d4106d5d3ac126875e0c3c1900..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/resources/res-plugtest-create1.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ETSI Plugtest resource - * \author - * Matthias Kovatsch - */ - -#include -#include "rest-engine.h" -#include "er-coap.h" -#include "er-plugtest.h" - -static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); -static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - -RESOURCE(res_plugtest_create1, - "title=\"Creates on PUT\"", - NULL, - NULL, - res_put_handler, - res_delete_handler); - -static uint8_t create1_exists = 0; - -static void -res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - PRINTF("/create1 PUT"); - - if(coap_get_header_if_none_match(request)) { - if(!create1_exists) { - REST.set_response_status(response, REST.status.CREATED); - - create1_exists = 1; - } else { - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } else { - REST.set_response_status(response, REST.status.CHANGED); - } -} -static void -res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - PRINTF("/create1 DELETE "); - REST.set_response_status(response, REST.status.DELETED); - - create1_exists = 0; -} diff --git a/samples/net/coap_server/src/resources/res-plugtest-create2.c b/samples/net/coap_server/src/resources/res-plugtest-create2.c deleted file mode 100644 index 25877ac70c23caaf139664f013d9c71343d5852e..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/resources/res-plugtest-create2.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ETSI Plugtest resource - * \author - * Matthias Kovatsch - */ - -#include -#include "rest-engine.h" -#include "er-coap.h" -#include "er-plugtest.h" - -static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - -RESOURCE(res_plugtest_create2, - "title=\"Creates on POST\"", - NULL, - res_post_handler, - NULL, - NULL); - -static void -res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - PRINTF("/create2 "); - - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "/location1/location2/location3"); -} diff --git a/samples/net/coap_server/src/resources/res-plugtest-create3.c b/samples/net/coap_server/src/resources/res-plugtest-create3.c deleted file mode 100644 index 2498c065a0da7d48c845188d5db73d81e2dc57c0..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/resources/res-plugtest-create3.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ETSI Plugtest resource - * \author - * Matthias Kovatsch - */ - -#include -#include "rest-engine.h" -#include "er-coap.h" -#include "er-plugtest.h" - -static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); -static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - -RESOURCE(res_plugtest_create3, - "title=\"Default test resource\"", - NULL, - NULL, - res_put_handler, - res_delete_handler); - -static uint8_t create3_exists = 0; - -static void -res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - PRINTF("/create3 PUT "); - - if(coap_get_header_if_none_match(request)) { - if(!create3_exists) { - REST.set_response_status(response, REST.status.CREATED); - - create3_exists = 1; - } else { - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } else { - REST.set_response_status(response, REST.status.CHANGED); - } -} -static void -res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - PRINTF("/create3 DELETE "); - REST.set_response_status(response, REST.status.DELETED); - - create3_exists = 0; -} diff --git a/samples/net/coap_server/src/resources/res-plugtest-large-create.c b/samples/net/coap_server/src/resources/res-plugtest-large-create.c deleted file mode 100644 index 888dfaa31868c98acbafbf36adb82ef1575e9138..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/resources/res-plugtest-large-create.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ETSI Plugtest resource - * \author - * Matthias Kovatsch - */ - -#include -#include "rest-engine.h" -#include "er-coap.h" -#include "er-plugtest.h" - -static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - -/* - * Large resource that can be created using POST method - */ -RESOURCE(res_plugtest_large_create, - "title=\"Large resource that can be created using POST method\";rt=\"block\"", - NULL, - res_post_handler, - NULL, - NULL); - -static void -res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *)request; - - uint8_t *incoming = NULL; - size_t len = 0; - - unsigned int ct = -1; - - if(!REST.get_header_content_type(request, &ct)) { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoContentType"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - if((len = REST.get_request_payload(request, (const uint8_t **)&incoming))) { - if(coap_req->block1_num * coap_req->block1_size + len <= 2048) { - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "/nirvana"); - coap_set_header_block1(response, coap_req->block1_num, 0, - coap_req->block1_size); - } else { - REST.set_response_status(response, REST.status.REQUEST_ENTITY_TOO_LARGE); - const char *error_msg = "2048B max."; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - } else { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoPayload"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } -} diff --git a/samples/net/coap_server/src/resources/res-plugtest-large-update.c b/samples/net/coap_server/src/resources/res-plugtest-large-update.c deleted file mode 100644 index 12c7d1e9f7dc61fcc3f3ecd97510aeb479c0a9f2..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/resources/res-plugtest-large-update.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ETSI Plugtest resource - * \author - * Matthias Kovatsch - */ - -#include -#include "sys/cc.h" -#include "rest-engine.h" -#include "er-coap.h" -#include "er-plugtest.h" - -static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); -static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - -RESOURCE( - res_plugtest_large_update, - "title=\"Large resource that can be updated using PUT method\";rt=\"block\";sz=\"" TO_STRING(MAX_PLUGFEST_BODY) "\"", - res_get_handler, - NULL, - res_put_handler, - NULL); - -static int32_t large_update_size = 0; -static uint8_t large_update_store[MAX_PLUGFEST_BODY] = { 0 }; -static unsigned int large_update_ct = APPLICATION_OCTET_STREAM; - -static void -res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - /* Check the offset for boundaries of the resource data. */ - if(*offset >= large_update_size) { - REST.set_response_status(response, REST.status.BAD_OPTION); - /* A block error message should not exceed the minimum block size (16). */ - - const char *error_msg = "BlockOutOfScope"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - REST.set_response_payload(response, large_update_store + *offset, - MIN(large_update_size - *offset, preferred_size)); - REST.set_header_content_type(response, large_update_ct); - - /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ - *offset += preferred_size; - - /* Signal end of resource representation. */ - if(*offset >= large_update_size) { - *offset = -1; - } -} -static void -res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *)request; - uint8_t *incoming = NULL; - size_t len = 0; - - unsigned int ct = -1; - - if(!REST.get_header_content_type(request, &ct)) { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoContentType"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - if((len = REST.get_request_payload(request, (const uint8_t **)&incoming))) { - if(coap_req->block1_num * coap_req->block1_size + len <= sizeof(large_update_store)) { - memcpy( - large_update_store + coap_req->block1_num * coap_req->block1_size, - incoming, len); - large_update_size = coap_req->block1_num * coap_req->block1_size + len; - large_update_ct = ct; - - REST.set_response_status(response, REST.status.CHANGED); - coap_set_header_block1(response, coap_req->block1_num, 0, - coap_req->block1_size); - } else { - REST.set_response_status(response, - REST.status.REQUEST_ENTITY_TOO_LARGE); - REST.set_response_payload( - response, - buffer, - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "%uB max.", - sizeof(large_update_store))); - return; - } - } else { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoPayload"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } -} diff --git a/samples/net/coap_server/src/resources/res-plugtest-large.c b/samples/net/coap_server/src/resources/res-plugtest-large.c deleted file mode 100644 index d997dd927831bbc43718acd412acb78ea0952feb..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/resources/res-plugtest-large.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ETSI Plugtest resource - * \author - * Matthias Kovatsch - */ - -#include -#include "rest-engine.h" -#include "er-coap.h" -#include "er-plugtest.h" - -static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - -RESOURCE(res_plugtest_large, - "title=\"Large resource\";rt=\"block\";sz=\"" TO_STRING(CHUNKS_TOTAL) "\"", - res_get_handler, - NULL, - NULL, - NULL); - -static void -res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int32_t strpos = 0; - - /* Check the offset for boundaries of the resource data. */ - if(*offset >= CHUNKS_TOTAL) { - REST.set_response_status(response, REST.status.BAD_OPTION); - /* A block error message should not exceed the minimum block size (16). */ - - const char *error_msg = "BlockOutOfScope"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - /* Generate data until reaching CHUNKS_TOTAL. */ - while(strpos < preferred_size) { - strpos += snprintf((char *)buffer + strpos, preferred_size - strpos + 1, - "|%ld|", *offset); - } - - /* snprintf() does not adjust return value if truncated by size. */ - if(strpos > preferred_size) { - strpos = preferred_size; - /* Truncate if above CHUNKS_TOTAL bytes. */ - } - if(*offset + (int32_t)strpos > CHUNKS_TOTAL) { - strpos = CHUNKS_TOTAL - *offset; - } - REST.set_response_payload(response, buffer, strpos); - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - - /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ - *offset += strpos; - - /* Signal end of resource representation. */ - if(*offset >= CHUNKS_TOTAL) { - *offset = -1; - } -} diff --git a/samples/net/coap_server/src/resources/res-plugtest-links.c b/samples/net/coap_server/src/resources/res-plugtest-links.c deleted file mode 100644 index be68aadf7daf5f2a3958012a543f312ba2c5c71e..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/resources/res-plugtest-links.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ETSI Plugtest resource - * \author - * Matthias Kovatsch - */ - -#include -#include "rest-engine.h" -#include "er-coap.h" -#include "er-plugtest.h" - -static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - -RESOURCE(res_plugtest_link1, - "rt=\"Type1 Type2\";if=\"If1\"", - res_get_handler, - NULL, - NULL, - NULL); -RESOURCE(res_plugtest_link2, - "rt=\"Type2 Type3\";if=\"If2\"", - res_get_handler, - NULL, - NULL, - NULL); -RESOURCE(res_plugtest_link3, - "rt=\"Type1 Type3\";if=\"foo\"", - res_get_handler, - NULL, - NULL, - NULL); - -static void -res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - const char *msg = "Dummy link"; - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, msg, strlen(msg)); -} diff --git a/samples/net/coap_server/src/resources/res-plugtest-locquery.c b/samples/net/coap_server/src/resources/res-plugtest-locquery.c deleted file mode 100644 index 02b09551478e7f9ed6f3a7654eed49cf79fde6de..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/resources/res-plugtest-locquery.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ETSI Plugtest resource - * \author - * Matthias Kovatsch - */ - -#include -#include "rest-engine.h" -#include "er-coap.h" -#include "er-plugtest.h" - -static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - -RESOURCE(res_plugtest_locquery, - "title=\"Resource accepting query parameters\"", - NULL, - res_post_handler, - NULL, - NULL); - -static void -res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ -#if DEBUG > 0 - coap_packet_t *const coap_req = (coap_packet_t *)request; - - PRINTF( - "/location-query POST (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); -#endif - - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "?first=1&second=2"); -} diff --git a/samples/net/coap_server/src/resources/res-plugtest-longpath.c b/samples/net/coap_server/src/resources/res-plugtest-longpath.c deleted file mode 100644 index d6c4fb8555b6ded5e0fa77b67095ed2c4f5e309c..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/resources/res-plugtest-longpath.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ETSI Plugtest resource - * \author - * Matthias Kovatsch - */ - -#include -#include "rest-engine.h" -#include "er-coap.h" -#include "er-plugtest.h" - -static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - -RESOURCE(res_plugtest_longpath, - "title=\"Long path resource\"", - res_get_handler, - NULL, - NULL, - NULL); - -static void -res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *)request; - - PRINTF("/seg1/seg2/seg3 GET "); - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload( - response, - buffer, - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, - "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); - - PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); -} diff --git a/samples/net/coap_server/src/resources/res-plugtest-multi.c b/samples/net/coap_server/src/resources/res-plugtest-multi.c deleted file mode 100644 index 281a2268fc82ba3e0be5c0f54a8be173b8afe0b5..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/resources/res-plugtest-multi.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ETSI Plugtest resource - * \author - * Matthias Kovatsch - */ - -#include -#include "rest-engine.h" -#include "er-coap.h" -#include "er-plugtest.h" - -static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - -RESOURCE(res_plugtest_multi, - "title=\"Resource providing text/plain and application/xml\";ct=\"0 41\"", - res_get_handler, - NULL, - NULL, - NULL); - -static void -res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *)request; - - unsigned int accept = -1; - REST.get_header_accept(request, &accept); - - PRINTF("/multi-format GET (%s %u) ", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); - - if(accept == -1 || accept == REST.type.TEXT_PLAIN) { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload( - response, - buffer, - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, - "Type: %u\nCode: %u\nMID: %u%s", coap_req->type, coap_req->code, - coap_req->mid, accept != -1 ? "\nAccept: 0" : "")); - PRINTF("PLAIN\n"); - } else if(accept == REST.type.APPLICATION_XML) { - REST.set_header_content_type(response, REST.type.APPLICATION_XML); - REST.set_response_payload( - response, - buffer, - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, - "", - coap_req->type, coap_req->code, coap_req->mid, accept)); - PRINTF("XML\n"); - } else { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain and application/xml"; - REST.set_response_payload(response, msg, strlen(msg)); - PRINTF("ERROR\n"); - } -} diff --git a/samples/net/coap_server/src/resources/res-plugtest-obs.c b/samples/net/coap_server/src/resources/res-plugtest-obs.c deleted file mode 100644 index e202c2043a5265458088c9a421c169312e2a95eb..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/resources/res-plugtest-obs.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ETSI Plugtest resource - * \author - * Matthias Kovatsch - */ - -#include -#include "rest-engine.h" -#include "er-coap.h" -#include "er-coap-observe.h" -#include "er-plugtest.h" - -static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); -static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); -static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); -static void res_periodic_handler(void); - -PERIODIC_RESOURCE(res_plugtest_obs, - "title=\"Observable resource which changes every 5 seconds\";obs", - res_get_handler, - NULL, - res_put_handler, - res_delete_handler, - 5 * CLOCK_SECOND, - res_periodic_handler); - -static int32_t obs_counter = 0; -static char obs_content[MAX_PLUGFEST_BODY]; -static size_t obs_content_len = 0; -static unsigned int obs_format = 0; - -static char obs_status = 0; - -static void -obs_purge_list() -{ - PRINTF("### SERVER ACTION ### Purging obs list"); - coap_remove_observer_by_uri(NULL, 0, res_plugtest_obs.url); -} -static void -res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - /* Keep server log clean from ticking events */ - if(request != NULL) { - PRINTF("/obs GET\n"); - } - REST.set_header_content_type(response, obs_format); - REST.set_header_max_age(response, 5); - - if(obs_content_len) { - REST.set_header_content_type(response, obs_format); - REST.set_response_payload(response, obs_content, obs_content_len); - } else { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, obs_content, - snprintf(obs_content, MAX_PLUGFEST_PAYLOAD, "TICK %lu", obs_counter)); - } - /* A post_handler that handles subscriptions will be called for periodic resources by the REST framework. */ -} -static void -res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint8_t *incoming = NULL; - unsigned int ct = -1; - - REST.get_header_content_type(request, &ct); - - PRINTF("/obs PUT\n"); - - if(ct != obs_format) { - obs_status = 1; - obs_format = ct; - } else { - obs_content_len = REST.get_request_payload(request, - (const uint8_t **)&incoming); - memcpy(obs_content, incoming, obs_content_len); - res_periodic_handler(); - } - - REST.set_response_status(response, REST.status.CHANGED); -} -static void -res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - PRINTF("/obs DELETE\n"); - - obs_status = 2; - - REST.set_response_status(response, REST.status.DELETED); -} -/* - * Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE. - * It will be called by the REST manager process with the defined period. - */ -static void -res_periodic_handler() -{ - ++obs_counter; - - /* PRINTF("TICK %u for /%s\n", obs_counter, r->url); */ - - if(obs_status == 1) { - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(&res_plugtest_obs); - - PRINTF("######### sending 5.00\n"); - - obs_purge_list(); - } else if(obs_status == 2) { - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(&res_plugtest_obs); - - obs_purge_list(); - - obs_counter = 0; - obs_content_len = 0; - } else { - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(&res_plugtest_obs); - } obs_status = 0; -} diff --git a/samples/net/coap_server/src/resources/res-plugtest-path.c b/samples/net/coap_server/src/resources/res-plugtest-path.c deleted file mode 100644 index 3566a51b94b79403dd3e9a81db47277085b5c9ce..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/resources/res-plugtest-path.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ETSI Plugtest resource - * \author - * Matthias Kovatsch - */ - -#include -#include "rest-engine.h" -#include "er-coap.h" -#include "er-plugtest.h" - -static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - -PARENT_RESOURCE(res_plugtest_path, - "title=\"Path test resource\";ct=\"40\"", - res_get_handler, - NULL, - NULL, - NULL); - -static void -res_get_handler(void *request, void *response, uint8_t *buffer, - uint16_t preferred_size, int32_t *offset) -{ - - const char *uri_path = NULL; - int len = REST.get_url(request, &uri_path); - int base_len = strlen(res_plugtest_path.url); - - if(len == base_len) { - REST.set_header_content_type(response, REST.type.APPLICATION_LINK_FORMAT); - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, - ",,"); - } else { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "/%.*s", len, uri_path); - } - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); -} diff --git a/samples/net/coap_server/src/resources/res-plugtest-query.c b/samples/net/coap_server/src/resources/res-plugtest-query.c deleted file mode 100644 index 538646c6e673cf92c6029601c6d809d53e294ef4..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/resources/res-plugtest-query.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ETSI Plugtest resource - * \author - * Matthias Kovatsch - */ - -#include -#include "rest-engine.h" -#include "er-coap.h" -#include "er-plugtest.h" - -static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - -RESOURCE(res_plugtest_query, - "title=\"Resource accepting query parameters\"", - res_get_handler, - NULL, - NULL, - NULL); - -static void -res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *)request; - int len = 0; - const char *query = NULL; - - PRINTF( - "/query GET (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); - - if((len = REST.get_query(request, &query))) { - PRINTF("Query: %.*s\n", len, query); - /* Code 2.05 CONTENT is default. */ - } - REST.set_header_content_type(response, - REST.type.TEXT_PLAIN); - REST.set_response_payload( - response, - buffer, - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, - "Type: %u\nCode: %u\nMID: %u\nQuery: %.*s", coap_req->type, - coap_req->code, coap_req->mid, len, query)); -} diff --git a/samples/net/coap_server/src/resources/res-plugtest-separate.c b/samples/net/coap_server/src/resources/res-plugtest-separate.c deleted file mode 100644 index 58605d6a4ed687b3e85e8d32f71215b8af03d243..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/resources/res-plugtest-separate.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ETSI Plugtest resource - * \author - * Matthias Kovatsch - */ - -#define DEBUG DEBUG_NULL - -#include -#include "rest-engine.h" -#include "er-coap.h" -#include "er-coap-transactions.h" -#include "er-coap-separate.h" -#include "er-plugtest.h" - -static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); -static void res_resume_handler(void); - -PERIODIC_RESOURCE(res_plugtest_separate, - "title=\"Resource which cannot be served immediately and which cannot be acknowledged in a piggy-backed way\"", - res_get_handler, - NULL, - NULL, - NULL, - 3 * CLOCK_SECOND, - res_resume_handler); - -/* A structure to store the required information */ -typedef struct application_separate_store { - /* Provided by Erbium to store generic request information such as remote address and token. */ - coap_separate_t request_metadata; - /* Add fields for addition information to be stored for finalizing, e.g.: */ - char buffer[MAX_PLUGFEST_PAYLOAD]; -} application_separate_store_t; - -static uint8_t separate_active = 0; -static application_separate_store_t separate_store[1]; - -void -res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *)request; - - PRINTF("/separate "); - if(separate_active) { - PRINTF("REJECTED "); - coap_separate_reject(); - } else { - PRINTF("STORED "); - separate_active = 1; - - /* Take over and skip response by engine. */ - coap_separate_accept(request, &separate_store->request_metadata); - /* Be aware to respect the Block2 option, which is also stored in the coap_separate_t. */ - - snprintf(separate_store->buffer, MAX_PLUGFEST_PAYLOAD, - "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, - coap_req->mid); - } - - PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); -} -static void -res_resume_handler() -{ - if(separate_active) { - PRINTF("/separate "); - coap_transaction_t *transaction = NULL; - if((transaction = coap_new_transaction(separate_store->request_metadata.mid, - NULL, - &separate_store->request_metadata.addr, - separate_store->request_metadata.port))) { - PRINTF( - "RESPONSE (%s %u)\n", separate_store->request_metadata.type == COAP_TYPE_CON ? "CON" : "NON", separate_store->request_metadata.mid); - - coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ - - /* Restore the request information for the response. */ - coap_separate_resume(response, &separate_store->request_metadata, CONTENT_2_05); - - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - coap_set_payload(response, separate_store->buffer, - strlen(separate_store->buffer)); - - /* - * Be aware to respect the Block2 option, which is also stored in the coap_separate_t. - * As it is a critical option, this example resource pretends to handle it for compliance. - */ - coap_set_header_block2(response, - separate_store->request_metadata.block2_num, 0, - separate_store->request_metadata.block2_size); - - /* Warning: No check for serialization error. */ - transaction->packet_len = coap_serialize_message(response, - transaction->packet); - coap_send_transaction(transaction); - /* The engine will clear the transaction (right after send for NON, after acked for CON). */ - - separate_active = 0; - } else { - PRINTF("ERROR (transaction)\n"); - } - } /* if (separate_active) */ -} diff --git a/samples/net/coap_server/src/resources/res-plugtest-test.c b/samples/net/coap_server/src/resources/res-plugtest-test.c deleted file mode 100644 index 2987242b9a3be0b7956a783d0bb06842526bd8e2..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/resources/res-plugtest-test.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ETSI Plugtest resource - * \author - * Matthias Kovatsch - */ - -#include -#include "rest-engine.h" -#include "er-coap.h" -#include "er-plugtest.h" - -static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); -static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); -static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); -static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - -RESOURCE(res_plugtest_test, "title=\"Default test resource\"", res_get_handler, res_post_handler, res_put_handler, res_delete_handler); - -static uint8_t test_etag[8] = { 0 }; -static uint8_t test_etag_len = 1; -static uint8_t test_change = 1; -static uint8_t test_none_match_okay = 1; - -static const uint8_t *bytes = NULL; -static size_t len = 0; - -static void -test_update_etag() -{ - int i; - test_etag_len = (random_rand() % 8) + 1; - for(i = 0; i < test_etag_len; ++i) { - test_etag[i] = random_rand(); - } - test_change = 0; - - PRINTF("### SERVER ACTION ### Changed ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", test_etag_len, test_etag[0], test_etag[1], test_etag[2], test_etag[3], test_etag[4], test_etag[5], test_etag[6], test_etag[7]); -} -static void -res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *)request; - - if(test_change) { - test_update_etag(); - } - PRINTF("/test GET (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); - - if((len = coap_get_header_etag(request, &bytes)) > 0 - && len == test_etag_len - && memcmp(test_etag, bytes, len) == 0) { - PRINTF("validate "); - REST.set_response_status(response, REST.status.NOT_MODIFIED); - REST.set_header_etag(response, test_etag, test_etag_len); - - test_change = 1; - PRINTF("### SERVER ACTION ### Resource will change\n"); - } else { - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_header_etag(response, test_etag, test_etag_len); - REST.set_header_max_age(response, 30); - REST.set_response_payload( - response, - buffer, - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); - } -} -static void -res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ -#if DEBUG > 0 - coap_packet_t *const coap_req = (coap_packet_t *)request; -#endif - - PRINTF("/test POST (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); - - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "/location1/location2/location3"); -} -static void -res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ -#if DEBUG > 0 - coap_packet_t *const coap_req = (coap_packet_t *)request; -#endif - - PRINTF("/test PUT (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); - - if(coap_get_header_if_none_match(request)) { - if(test_none_match_okay) { - REST.set_response_status(response, REST.status.CREATED); - - test_none_match_okay = 0; - PRINTF("### SERVER ACTION ### If-None-Match will FAIL\n"); - } else { - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - - test_none_match_okay = 1; - PRINTF("### SERVER ACTION ### If-None-Match will SUCCEED\n"); - } - } else if(((len = coap_get_header_if_match(request, &bytes)) > 0 - && (len == test_etag_len - && memcmp(test_etag, bytes, len) == 0)) - || len == 0) { - test_update_etag(); - REST.set_header_etag(response, test_etag, test_etag_len); - - REST.set_response_status(response, REST.status.CHANGED); - - if(len > 0) { - test_change = 1; - PRINTF("### SERVER ACTION ### Resource will change\n"); - } - } else { - PRINTF("Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", - len, - test_etag_len, - bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], - test_etag[0], test_etag[1], test_etag[2], test_etag[3], test_etag[4], test_etag[5], test_etag[6], test_etag[7]); - - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } -} -static void -res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ -#if DEBUG > 0 - coap_packet_t *const coap_req = (coap_packet_t *)request; -#endif - - PRINTF("/test DELETE (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); - REST.set_response_status(response, REST.status.DELETED); -} diff --git a/samples/net/coap_server/src/resources/res-plugtest-validate.c b/samples/net/coap_server/src/resources/res-plugtest-validate.c deleted file mode 100644 index 4242f7ce27a025ee9e384d161dbafa747cab6ceb..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/src/resources/res-plugtest-validate.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ETSI Plugtest resource - * \author - * Matthias Kovatsch - */ - -#include -#include "rest-engine.h" -#include "er-coap.h" -#include "er-plugtest.h" - -static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); -static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - -RESOURCE(res_plugtest_validate, - "title=\"Validation test resource\"", - res_get_handler, - NULL, - res_put_handler, - NULL); - -static uint8_t validate_etag[8] = { 0 }; -static uint8_t validate_etag_len = 1; -static uint8_t validate_change = 1; - -static const uint8_t *bytes = NULL; -static size_t len = 0; - -static void -validate_update_etag() -{ - int i; - validate_etag_len = (random_rand() % 8) + 1; - for(i = 0; i < validate_etag_len; ++i) { - validate_etag[i] = random_rand(); - } - validate_change = 0; - - PRINTF("### SERVER ACTION ### Changed ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", - validate_etag_len, validate_etag[0], validate_etag[1], validate_etag[2], validate_etag[3], validate_etag[4], validate_etag[5], validate_etag[6], validate_etag[7]); -} -static void -res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *)request; - - if(validate_change) { - validate_update_etag(); - } - PRINTF("/validate GET"); - PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); - - if((len = coap_get_header_etag(request, &bytes)) > 0 - && len == validate_etag_len && memcmp(validate_etag, bytes, len) == 0) { - PRINTF("validate "); - REST.set_response_status(response, REST.status.NOT_MODIFIED); - REST.set_header_etag(response, validate_etag, validate_etag_len); - - validate_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } else { - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_header_etag(response, validate_etag, validate_etag_len); - REST.set_header_max_age(response, 30); - REST.set_response_payload( - response, - buffer, - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, - "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, - coap_req->mid)); - } -} -static void -res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ -#if DEBUG > 0 - coap_packet_t *const coap_req = (coap_packet_t *)request; - - PRINTF("/validate PUT "); - PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); -#endif - - if(((len = coap_get_header_if_match(request, &bytes)) > 0 - && (len == validate_etag_len - && memcmp(validate_etag, bytes, len) == 0)) - || len == 0) { - validate_update_etag(); - REST.set_header_etag(response, validate_etag, validate_etag_len); - - REST.set_response_status(response, REST.status.CHANGED); - - if(len > 0) { - validate_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - } else { - PRINTF( - "Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X] ", - len, - validate_etag_len, - bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], - validate_etag[0], validate_etag[1], validate_etag[2], validate_etag[3], validate_etag[4], validate_etag[5], validate_etag[6], validate_etag[7]); - - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } -} diff --git a/samples/net/coap_server/testcase.ini b/samples/net/coap_server/testcase.ini deleted file mode 100644 index 0ff7448d5400ff7b5464d8f74967697e2e429f18..0000000000000000000000000000000000000000 --- a/samples/net/coap_server/testcase.ini +++ /dev/null @@ -1,12 +0,0 @@ -[test] -tags = net -build_only = true -arch_whitelist = x86 -platform_whitelist = qemu_x86 - -[test-bt] -tags = net bluetooth -build_only = true -extra_args = CONF_FILE="prj_bt.conf" -arch_whitelist = x86 -platform_whitelist = qemu_x86 diff --git a/samples/net/dhcp_client/Makefile b/samples/net/dhcp_client/Makefile deleted file mode 100644 index a55fd5de15d9fc563ece98dadce3d85153207362..0000000000000000000000000000000000000000 --- a/samples/net/dhcp_client/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# Makefile - echo client test application - -# -# Copyright (c) 2015 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -NET_IFACE ?= galileo -MDEF_FILE = prj.mdef -BOARD ?= galileo -CONF_FILE ?= prj_$(BOARD).conf - -include $(ZEPHYR_BASE)/Makefile.inc diff --git a/samples/net/dhcp_client/prj.mdef b/samples/net/dhcp_client/prj.mdef deleted file mode 100644 index 865de24b6fff4f09dc9a70592743250624a45321..0000000000000000000000000000000000000000 --- a/samples/net/dhcp_client/prj.mdef +++ /dev/null @@ -1,5 +0,0 @@ -% Application : echo client - -% TASK NAME PRIO ENTRY STACK GROUPS -% ================================== - TASK MAIN 7 main 2048 [EXE] diff --git a/samples/net/dhcp_client/prj_frdm_k64f.conf b/samples/net/dhcp_client/prj_frdm_k64f.conf deleted file mode 100644 index 3ae3916e4385ede82eca0177f4d1d27ff07a0b76..0000000000000000000000000000000000000000 --- a/samples/net/dhcp_client/prj_frdm_k64f.conf +++ /dev/null @@ -1,32 +0,0 @@ -# -#console -# -CONFIG_STDOUT_CONSOLE=y -CONFIG_CONSOLE_HANDLER=y -CONFIG_CONSOLE_HANDLER_SHELL=y -CONFIG_PRINTK=y -CONFIG_MINIMAL_LIBC_EXTENDED=y -# -# networking -# -CONFIG_NETWORKING=y -CONFIG_IP_BUF_RX_SIZE=2 -CONFIG_IP_BUF_TX_SIZE=3 -CONFIG_NETWORKING_WITH_IPV4=y -CONFIG_RANDOM_GENERATOR=y -CONFIG_NETWORKING_WITH_TCP=y -CONFIG_DHCP=y -CONFIG_NANO_TIMEOUTS=y - -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_NETWORK_IP_STACK_DEBUG_DHCP=y -CONFIG_NETWORK_IP_STACK_DEBUG_PRINT=y -CONFIG_NETWORK_IP_STACK_DEBUG_RECV_SEND=y -CONFIG_NETWORK_IP_STACK_DEBUG_IPV4=y -CONFIG_NETWORK_IP_STACK_DEBUG_CONTEXT=y -CONFIG_NETWORK_IP_STACK_DEBUG_NET_BUF=y -# -# Ethernet -# -CONFIG_ETHERNET=y -#CONFIG_ETHERNET_DEBUG=y diff --git a/samples/net/dhcp_client/prj_galileo.conf b/samples/net/dhcp_client/prj_galileo.conf deleted file mode 100644 index 5a4ae10f05ab3ebe5eca04e140335370702c3273..0000000000000000000000000000000000000000 --- a/samples/net/dhcp_client/prj_galileo.conf +++ /dev/null @@ -1,34 +0,0 @@ -# -#console -# -CONFIG_STDOUT_CONSOLE=y -CONFIG_CONSOLE_HANDLER=y -CONFIG_CONSOLE_HANDLER_SHELL=y -CONFIG_PRINTK=y -CONFIG_MINIMAL_LIBC_EXTENDED=y -# -# networking -# -CONFIG_NETWORKING=y -CONFIG_IP_BUF_RX_SIZE=2 -CONFIG_IP_BUF_TX_SIZE=3 -CONFIG_NETWORKING_WITH_IPV4=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NETWORKING_WITH_TCP=y -CONFIG_DHCP=y -CONFIG_NANO_TIMEOUTS=y - -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_NETWORK_IP_STACK_DEBUG_DHCP=y -CONFIG_NETWORK_IP_STACK_DEBUG_PRINT=y -CONFIG_NETWORK_IP_STACK_DEBUG_RECV_SEND=y -CONFIG_NETWORK_IP_STACK_DEBUG_IPV4=y -CONFIG_NETWORK_IP_STACK_DEBUG_CONTEXT=y -CONFIG_NETWORK_IP_STACK_DEBUG_NET_BUF=y -# -# Ethernet -# -CONFIG_ETHERNET=y -#CONFIG_ETHERNET_DEBUG=y -CONFIG_ETH_DW=y -CONFIG_PCI_ENUMERATION=y diff --git a/samples/net/dhcp_client/src/Makefile b/samples/net/dhcp_client/src/Makefile deleted file mode 100644 index 07e0ebef69eb1f8263051437d99506ebacfc0af1..0000000000000000000000000000000000000000 --- a/samples/net/dhcp_client/src/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os/lib -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os -ccflags-y +=-I${ZEPHYR_BASE}/net/ip - -obj-y = dhcp-client.o diff --git a/samples/net/dhcp_client/src/dhcp-client.c b/samples/net/dhcp_client/src/dhcp-client.c deleted file mode 100644 index 3fb0e5607c3e58e18941127f13e078a7602e3980..0000000000000000000000000000000000000000 --- a/samples/net/dhcp_client/src/dhcp-client.c +++ /dev/null @@ -1,52 +0,0 @@ -/* dhcp-client.c - Get IPv4 address */ - -/* - * Copyright (c) 2016 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined(CONFIG_STDOUT_CONSOLE) -#include -#define PRINT printf -#else -#include -#define PRINT printk -#endif - -#include -#include - -#include -#include -#include -#include "contiki/ip/dhcpc.h" - - -static void dhcpc_configured_cb(void) -{ - PRINT("%s\n", __func__); - PRINT("Got IP address %d.%d.%d.%d\n", uip_ipaddr_to_quad(&uip_hostaddr)); -} - -static void dhcpc_unconfigured_cb(void) -{ - PRINT("%s\n", __func__); -} - -void main(void) -{ - PRINT("run dhcp client\n"); - dhcpc_set_callbacks(dhcpc_configured_cb, dhcpc_unconfigured_cb); - net_init(); -} diff --git a/samples/net/dhcp_client/testcase.ini b/samples/net/dhcp_client/testcase.ini deleted file mode 100644 index 99297a6174e845f8fc264e4de5e2cb7fcfde2dea..0000000000000000000000000000000000000000 --- a/samples/net/dhcp_client/testcase.ini +++ /dev/null @@ -1,5 +0,0 @@ -[test] -tags = net -build_only = true -arch_whitelist = x86 -platform_whitelist = galileo diff --git a/samples/net/dtls_client/Makefile b/samples/net/dtls_client/Makefile deleted file mode 100644 index 248255417cfa4a9825edc59742f02033e7d376a5..0000000000000000000000000000000000000000 --- a/samples/net/dtls_client/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# Makefile - dtls client that is used in testing - -# -# Copyright (c) 2015 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -NET_IFACE ?= slip -MDEF_FILE = prj.mdef -BOARD ?= qemu_x86 -CONF_FILE = prj_$(NET_IFACE).conf - -include $(ZEPHYR_BASE)/Makefile.inc -include $(ZEPHYR_BASE)/samples/net/common/Makefile.ipstack diff --git a/samples/net/dtls_client/prj.mdef b/samples/net/dtls_client/prj.mdef deleted file mode 100644 index f168b446702008394dd31132a2603959f22b20fd..0000000000000000000000000000000000000000 --- a/samples/net/dtls_client/prj.mdef +++ /dev/null @@ -1,5 +0,0 @@ -% Application : DTSL server - -% TASK NAME PRIO ENTRY STACK GROUPS -% ================================== - TASK TASKA 7 startup 3000 [EXE] diff --git a/samples/net/dtls_client/prj_802154.conf b/samples/net/dtls_client/prj_802154.conf deleted file mode 100644 index 9fc3c7d946c8bb702c146356f66474468fde1a56..0000000000000000000000000000000000000000 --- a/samples/net/dtls_client/prj_802154.conf +++ /dev/null @@ -1,11 +0,0 @@ -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_IP_BUF_RX_SIZE=4 -CONFIG_IP_BUF_TX_SIZE=3 -CONFIG_NANO_TIMEOUTS=y -CONFIG_TINYDTLS=y -CONFIG_NETWORKING_WITH_15_4=y -CONFIG_NETWORKING_WITH_15_4_TI_CC2520=y -CONFIG_NETWORKING_WITH_6LOWPAN=y -CONFIG_6LOWPAN_COMPRESSION_IPHC=y diff --git a/samples/net/dtls_client/prj_qemu.conf b/samples/net/dtls_client/prj_qemu.conf deleted file mode 100644 index ea0015bfd247cc4f24f019414fc2f08b6f30ec5f..0000000000000000000000000000000000000000 --- a/samples/net/dtls_client/prj_qemu.conf +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG_NET_TESTING=y -CONFIG_NETWORKING_IPV6_NO_ND=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NETWORKING=y -CONFIG_IP_BUF_TX_SIZE=2 -CONFIG_IP_BUF_RX_SIZE=10 -CONFIG_NANO_TIMEOUTS=y -CONFIG_TINYDTLS=y -CONFIG_NETWORKING_WITH_15_4=y -CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART=y -CONFIG_NETWORKING_WITH_6LOWPAN=y -CONFIG_6LOWPAN_COMPRESSION_IPHC=y -CONFIG_NETWORKING_STATISTICS=y diff --git a/samples/net/dtls_client/prj_slip.conf b/samples/net/dtls_client/prj_slip.conf deleted file mode 100644 index c76001740d2c3feb53b633c5fcd13fb2b646314c..0000000000000000000000000000000000000000 --- a/samples/net/dtls_client/prj_slip.conf +++ /dev/null @@ -1,10 +0,0 @@ -CONFIG_NET_TESTING=y -CONFIG_NETWORKING_IPV6_NO_ND=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_NETWORKING_UART=y -CONFIG_IP_BUF_TX_SIZE=2 -CONFIG_IP_BUF_RX_SIZE=10 -CONFIG_NANO_TIMEOUTS=y -CONFIG_TINYDTLS=y diff --git a/samples/net/dtls_client/src/Makefile b/samples/net/dtls_client/src/Makefile deleted file mode 100644 index f44668e06309c93d4711983b2e4045489e448486..0000000000000000000000000000000000000000 --- a/samples/net/dtls_client/src/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os/lib -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os/sys -ccflags-y +=-I${ZEPHYR_BASE}/net/ip - -ifeq ($(CONFIG_NET_TESTING), y) -ccflags-y +=-I${ZEPHYR_BASE}/samples/net/common/ -ccflags-y +=-DNET_TESTING_SERVER=0 -endif - -obj-y = dtls-client.o diff --git a/samples/net/dtls_client/src/dtls-client.c b/samples/net/dtls_client/src/dtls-client.c deleted file mode 100644 index cb54f6d6a92b91920980c3355eeffe2a424270e6..0000000000000000000000000000000000000000 --- a/samples/net/dtls_client/src/dtls-client.c +++ /dev/null @@ -1,479 +0,0 @@ -/* dtls-client.c - dtls client */ - -/* - * Copyright (c) 2015 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined(CONFIG_STDOUT_CONSOLE) -#include -#define PRINT printf -#else -#include -#define PRINT printk -#endif - -#if defined(CONFIG_TINYDTLS_DEBUG) -#define DEBUG DEBUG_FULL -#else -#define DEBUG DEBUG_PRINT -#endif -#include "contiki/ip/uip-debug.h" - -#include - -#include - -#include - -#include -#include -#include - -#include - -#if defined(CONFIG_NET_TESTING) -#include -#endif - -/* Generated by http://www.lipsum.com/ - * 1202 bytes of Lorem Ipsum. - * - * This is the maximum we can send with encryption. - */ -static const char lorem_ipsum[] = - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin congue orci et lectus ultricies, sed elementum urna finibus. Nam bibendum, massa id sollicitudin finibus, massa ante pharetra lacus, nec semper felis metus eu massa. Curabitur gravida, neque a pulvinar suscipit, felis massa maximus neque, eu sagittis felis enim nec justo. Suspendisse sit amet sem a magna aliquam tincidunt. Mauris consequat ante in consequat auctor. Nam eu congue mauris, congue aliquet metus. Etiam elit ipsum, vehicula et lectus at, dignissim accumsan turpis. Sed magna nisl, tempor ut dolor sed, feugiat pharetra velit. Nulla sed purus at elit dapibus lobortis. In hac habitasse platea dictumst. Praesent quis libero id enim aliquet viverra eleifend non urna. Vivamus metus justo, dignissim eget libero molestie, tincidunt pellentesque purus. Quisque pulvinar, nisi sed egestas vestibulum, ante felis elementum justo, ut viverra nisl est sagittis leo. Curabitur pharetra eros at felis ultricies efficitur." - "\n" - "Ut rutrum urna vitae neque rhoncus, id dictum ex dictum. Suspendisse venenatis vel mauris sed maximus. Sed malesuada elit vel neque hendrerit, in accumsan odio sodales. Aliquam erat volutpat. Praesent non situ.\n"; - -struct data { - bool fail; - bool connected; - int expecting; - int ipsum_len; - struct net_context *ctx; -}; - -static const unsigned char ecdsa_priv_key[] = { - 0xD9, 0xE2, 0x70, 0x7A, 0x72, 0xDA, 0x6A, 0x05, - 0x04, 0x99, 0x5C, 0x86, 0xED, 0xDB, 0xE3, 0xEF, - 0xC7, 0xF1, 0xCD, 0x74, 0x83, 0x8F, 0x75, 0x70, - 0xC8, 0x07, 0x2D, 0x0A, 0x76, 0x26, 0x1B, 0xD4}; - -static const unsigned char ecdsa_pub_key_x[] = { - 0xD0, 0x55, 0xEE, 0x14, 0x08, 0x4D, 0x6E, 0x06, - 0x15, 0x59, 0x9D, 0xB5, 0x83, 0x91, 0x3E, 0x4A, - 0x3E, 0x45, 0x26, 0xA2, 0x70, 0x4D, 0x61, 0xF2, - 0x7A, 0x4C, 0xCF, 0xBA, 0x97, 0x58, 0xEF, 0x9A}; - -static const unsigned char ecdsa_pub_key_y[] = { - 0xB4, 0x18, 0xB6, 0x4A, 0xFE, 0x80, 0x30, 0xDA, - 0x1D, 0xDC, 0xF4, 0xF4, 0x2E, 0x2F, 0x26, 0x31, - 0xD0, 0x43, 0xB1, 0xFB, 0x03, 0xE2, 0x2F, 0x4D, - 0x17, 0xDE, 0x43, 0xF9, 0xF9, 0xAD, 0xEE, 0x70}; - -#ifdef CONFIG_NETWORKING_WITH_IPV6 -/* The 2001:db8::/32 is the private address space for documentation RFC 3849 */ -/* Define the peer IP address where to send messages */ -#if !defined(CONFIG_NET_TESTING) -#define PEER_IPADDR { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 } } } -#endif -#else /* ipv6 */ -/* The 192.0.2.0/24 is the private address space for documentation RFC 5737 */ -#if !defined(CONFIG_NET_TESTING) -#define PEER_IPADDR { { { 192, 0, 2, 1 } } } -#endif -#endif - -#define MY_PORT 8484 -#define PEER_PORT 4242 - -static inline void init_app(void) -{ - PRINT("%s: run dtls client\n", __func__); - -#if defined(CONFIG_NET_TESTING) - net_testing_setup(); -#endif -} - -static inline void reverse(unsigned char *buf, int len) -{ - int i, last = len - 1; - - for (i = 0; i < len / 2; i++) { - unsigned char tmp = buf[i]; - buf[i] = buf[last - i]; - buf[last - i] = tmp; - } -} - -/* How many tics to wait for a network packet */ -#define WAIT_TIME 5 -#define WAIT_TICKS (WAIT_TIME * sys_clock_ticks_per_sec) - -static inline void send_message(const char *name, - dtls_context_t *ctx, - session_t *session) -{ - struct data *user_data = (struct data *)dtls_get_app_data(ctx); - struct net_buf *buf; - - buf = ip_buf_get_reserve_tx(UIP_IPUDPH_LEN); - if (buf) { - uint8_t *ptr; - int pos = sys_rand32_get() % user_data->ipsum_len; - - user_data->expecting = user_data->ipsum_len - pos; - - ptr = net_buf_add(buf, user_data->expecting); - memcpy(ptr, lorem_ipsum + pos, user_data->expecting); - ip_buf_appdatalen(buf) = user_data->expecting; - - dtls_write(ctx, session, - ip_buf_appdata(buf), ip_buf_appdatalen(buf)); - - /* The encrypted data to peer is actually sent by - * send_to_peer() so we need to release the buffer - * here. - */ - ip_buf_unref(buf); - } -} - -static inline bool wait_reply(const char *name, - struct dtls_context_t *dtls, - session_t *session) -{ - struct data *user_data = (struct data *)dtls_get_app_data(dtls); - struct net_buf *buf; - - /* Wait for the answer */ - buf = net_receive(user_data->ctx, WAIT_TICKS); - if (buf) { - PRINT("Received data %p datalen %d\n", - ip_buf_appdata(buf), ip_buf_appdatalen(buf)); - - dtls_handle_message(dtls, session, ip_buf_appdata(buf), - ip_buf_appdatalen(buf)); - - ip_buf_unref(buf); - return true; - } - - return false; -} - -#ifdef CONFIG_NETWORKING_WITH_IPV6 -static const struct in6_addr in6addr_peer = PEER_IPADDR; -#else -static struct in_addr in4addr_peer = PEER_IPADDR; -#endif - -static inline struct net_context *get_context(void) -{ - static struct net_addr peer_addr; - static struct net_addr my_addr; - struct net_context *ctx; - -#ifdef CONFIG_NETWORKING_WITH_IPV6 - static struct in6_addr in6addr_my = IN6ADDR_ANY_INIT; - - peer_addr.in6_addr = in6addr_peer; - peer_addr.family = AF_INET6; - - my_addr.in6_addr = in6addr_my; - my_addr.family = AF_INET6; -#else - static struct in_addr in4addr_my = { { { 0 } } }; - - peer_addr.in_addr = in4addr_peer; - peer_addr.family = AF_INET; - - my_addr.in_addr = in4addr_my; - my_addr.family = AF_INET; -#endif - - ctx = net_context_get(IPPROTO_UDP, - &peer_addr, PEER_PORT, - &my_addr, MY_PORT); - if (!ctx) { - PRINT("%s: Cannot get network context\n", __func__); - return NULL; - } - - return ctx; -} - -static int read_from_peer(struct dtls_context_t *ctx, - session_t *session, - uint8 *data, size_t len) -{ - struct data *user_data = (struct data *)dtls_get_app_data(ctx); - int pos; - - PRINT("%s: read from peer %p len %d\n", __func__, data, len); - - if (user_data->expecting != len) { - PRINT("%s: received %d bytes, expected %d\n", - __func__, len, user_data->expecting); - user_data->fail = true; - return 0; - } - - /* In this test we reverse the received bytes. - * We could also just pass the data back as is. - */ - reverse(data, len); - - /* Did we get all the data back? - */ - pos = user_data->ipsum_len - user_data->expecting; - - if (memcmp(lorem_ipsum + pos, data, user_data->expecting)) { - PRINT("%s: received data mismatch.\n", __func__); - user_data->fail = true; - } - - return 0; -} - -static int send_to_peer(struct dtls_context_t *ctx, - session_t *session, - uint8 *data, size_t len) -{ - struct data *user_data = (struct data *)dtls_get_app_data(ctx); - struct net_buf *buf; - int max_data_len; - uint8_t *ptr; - - buf = ip_buf_get_tx(user_data->ctx); - if (!buf) { - len = -ENOBUFS; - goto out; - } - - max_data_len = IP_BUF_MAX_DATA - UIP_IPUDPH_LEN; - - PRINT("%s: send to peer data %p len %d\n", __func__, data, len); - - if (len > max_data_len) { - PRINT("%s: too much (%d bytes) data to send (max %d bytes)\n", - __func__, len, max_data_len); - ip_buf_unref(buf); - len = -EINVAL; - goto out; - } - - ptr = net_buf_add(buf, len); - memcpy(ptr, data, len); - ip_buf_appdatalen(buf) = len; - - if (net_send(buf)) { - ip_buf_unref(buf); - } - -out: - return len; -} - -#ifdef DTLS_PSK -/* This function is the "key store" for tinyDTLS. It is called to - * retrieve a key for the given identity within this particular - * session. */ -static int get_psk_info(struct dtls_context_t *ctx, - const session_t *session, - dtls_credentials_type_t type, - const unsigned char *id, size_t id_len, - unsigned char *result, size_t result_length) -{ - struct keymap_t { - unsigned char *id; - size_t id_length; - unsigned char *key; - size_t key_length; - } psk[3] = { - { (unsigned char *)"Client_identity", 15, - (unsigned char *)"secretPSK", 9 }, - { (unsigned char *)"default identity", 16, - (unsigned char *)"\x11\x22\x33", 3 }, - { (unsigned char *)"\0", 2, - (unsigned char *)"", 1 } - }; - - if (type != DTLS_PSK_KEY) { - return 0; - } - - if (id) { - int i; - for (i = 0; i < sizeof(psk)/sizeof(struct keymap_t); i++) { - if (id_len == psk[i].id_length && - memcmp(id, psk[i].id, id_len) == 0) { - if (result_length < psk[i].key_length) { - dtls_warn("buffer too small for PSK"); - return dtls_alert_fatal_create( - DTLS_ALERT_INTERNAL_ERROR); - } - - memcpy(result, psk[i].key, psk[i].key_length); - return psk[i].key_length; - } - } - } - - return dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR); -} -#endif /* DTLS_PSK */ - -#ifdef DTLS_ECC -static int get_ecdsa_key(struct dtls_context_t *ctx, - const session_t *session, - const dtls_ecdsa_key_t **result) -{ - static const dtls_ecdsa_key_t ecdsa_key = { - .curve = DTLS_ECDH_CURVE_SECP256R1, - .priv_key = ecdsa_priv_key, - .pub_key_x = ecdsa_pub_key_x, - .pub_key_y = ecdsa_pub_key_y - }; - - *result = &ecdsa_key; - return 0; -} - -static int verify_ecdsa_key(struct dtls_context_t *ctx, - const session_t *session, - const unsigned char *other_pub_x, - const unsigned char *other_pub_y, - size_t key_size) -{ - return 0; -} -#endif /* DTLS_ECC */ - -static int handle_event(struct dtls_context_t *ctx, session_t *session, - dtls_alert_level_t level, unsigned short code) -{ - dtls_debug("event: level %d code %d\n", level, code); - - if (level > 0) { - /* alert code, quit */ - } else if (level == 0) { - /* internal event */ - if (code == DTLS_EVENT_CONNECTED) { - struct data *user_data = - (struct data *)dtls_get_app_data(ctx); - - PRINT("*** Connected ***\n"); - - /* We can send data now */ - user_data->connected = true; - } - } - - return 0; -} - -static void init_dtls(struct data *user_data, dtls_context_t **dtls) -{ - static dtls_handler_t cb = { - .write = send_to_peer, - .read = read_from_peer, - .event = handle_event, -#ifdef DTLS_PSK - .get_psk_info = get_psk_info, -#endif /* DTLS_PSK */ -#ifdef DTLS_ECC - .get_ecdsa_key = get_ecdsa_key, - .verify_ecdsa_key = verify_ecdsa_key -#endif /* DTLS_ECC */ - }; - - PRINT("DTLS client started\n"); - -#ifdef CONFIG_TINYDTLS_DEBUG - dtls_set_log_level(DTLS_LOG_DEBUG); -#endif - - *dtls = dtls_new_context(user_data); - if (*dtls) { - dtls_set_handler(*dtls, &cb); - } -} - -void startup(void) -{ - static dtls_context_t *dtls; - static session_t session; - static struct data user_data; - - user_data.ipsum_len = strlen(lorem_ipsum); - - net_init(); - - dtls_init(); - - init_app(); - - user_data.ctx = get_context(); - if (!user_data.ctx) { - PRINT("%s: Cannot get network context\n", __func__); - return; - } - - init_dtls(&user_data, &dtls); - if (!dtls) { - PRINT("%s: Cannot get DTLS context\n", __func__); - return; - } - - dtls_session_init(&session); - - uip_ipaddr_copy(&session.addr.ipaddr, (uip_ipaddr_t *)&in6addr_peer); - session.addr.port = uip_htons(PEER_PORT); - - PRINT("Trying to connect to "); - PRINT6ADDR(&session.addr.ipaddr); - PRINTF(":%d\n", uip_ntohs(session.addr.port)); - - dtls_connect(dtls, &session); - - while (!user_data.fail) { - if (user_data.connected) { - send_message(__func__, dtls, &session); - } - if (!wait_reply(__func__, dtls, &session)) { - if (user_data.connected) { - break; - } - } - } - - PRINT("ERROR: Did not receive reply, closing.\n"); - dtls_close(dtls, &session); -} - -#ifdef CONFIG_NANOKERNEL - -#define STACKSIZE 3000 -char fiberStack[STACKSIZE]; - -void main(void) -{ - fiber_start(&fiberStack[0], STACKSIZE, - (nano_fiber_entry_t)startup, 0, 0, 7, 0); -} - -#endif /* CONFIG_NANOKERNEL */ diff --git a/samples/net/dtls_client/testcase.ini b/samples/net/dtls_client/testcase.ini deleted file mode 100644 index 4aaa2413e62a3b1e4ab286839113c8568284c06d..0000000000000000000000000000000000000000 --- a/samples/net/dtls_client/testcase.ini +++ /dev/null @@ -1,5 +0,0 @@ -[test] -tags = net -build_only = true -arch_whitelist = x86 -platform_whitelist = qemu_x86 diff --git a/samples/net/dtls_server/Makefile b/samples/net/dtls_server/Makefile deleted file mode 100644 index e86abd1186aa8a0b87cbf62a604eb4a56044e91f..0000000000000000000000000000000000000000 --- a/samples/net/dtls_server/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# Makefile - dtls server that is used in testing - -# -# Copyright (c) 2015 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -NET_IFACE ?= slip -MDEF_FILE = prj.mdef -BOARD ?= qemu_x86 -CONF_FILE ?= prj_$(NET_IFACE).conf - -include $(ZEPHYR_BASE)/Makefile.inc - -ifeq ($(CONFIG_NETWORKING_WITH_BT), y) - QEMU_EXTRA_FLAGS = -serial unix:/tmp/bt-server-bredr -else - include $(ZEPHYR_BASE)/samples/net/common/Makefile.ipstack -endif diff --git a/samples/net/dtls_server/prj.mdef b/samples/net/dtls_server/prj.mdef deleted file mode 100644 index f168b446702008394dd31132a2603959f22b20fd..0000000000000000000000000000000000000000 --- a/samples/net/dtls_server/prj.mdef +++ /dev/null @@ -1,5 +0,0 @@ -% Application : DTSL server - -% TASK NAME PRIO ENTRY STACK GROUPS -% ================================== - TASK TASKA 7 startup 3000 [EXE] diff --git a/samples/net/dtls_server/prj_802154.conf b/samples/net/dtls_server/prj_802154.conf deleted file mode 100644 index e361ea702098627e9c82b0fbf95b9d602e7c9485..0000000000000000000000000000000000000000 --- a/samples/net/dtls_server/prj_802154.conf +++ /dev/null @@ -1,10 +0,0 @@ -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_IP_BUF_RX_SIZE=3 -CONFIG_IP_BUF_TX_SIZE=2 -CONFIG_NANO_TIMEOUTS=y -CONFIG_TINYDTLS=y -CONFIG_NETWORKING_WITH_15_4=y -CONFIG_NETWORKING_WITH_15_4_TI_CC2520=y -CONFIG_NETWORKING_WITH_6LOWPAN=y -CONFIG_6LOWPAN_COMPRESSION_IPHC=y diff --git a/samples/net/dtls_server/prj_bt.conf b/samples/net/dtls_server/prj_bt.conf deleted file mode 100644 index ac1900380f645e362a6d82c2be305d03b7b1bfd9..0000000000000000000000000000000000000000 --- a/samples/net/dtls_server/prj_bt.conf +++ /dev/null @@ -1,6 +0,0 @@ -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_NETWORKING_WITH_BT=y -CONFIG_IP_BUF_RX_SIZE=5 -CONFIG_IP_BUF_TX_SIZE=3 -CONFIG_TINYDTLS=y diff --git a/samples/net/dtls_server/prj_qemu.conf b/samples/net/dtls_server/prj_qemu.conf deleted file mode 100644 index 9df72cfae555f9fb87ba22d45685cb11ea9e9a1b..0000000000000000000000000000000000000000 --- a/samples/net/dtls_server/prj_qemu.conf +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG_NET_TESTING=y -CONFIG_NETWORKING_IPV6_NO_ND=y -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_IP_BUF_RX_SIZE=10 -CONFIG_IP_BUF_TX_SIZE=2 -CONFIG_NANO_TIMEOUTS=y -CONFIG_TINYDTLS=y -CONFIG_NETWORKING_WITH_15_4=y -CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART=y -CONFIG_NETWORKING_WITH_6LOWPAN=y -CONFIG_6LOWPAN_COMPRESSION_IPHC=y -CONFIG_NETWORKING_STATISTICS=y diff --git a/samples/net/dtls_server/prj_slip.conf b/samples/net/dtls_server/prj_slip.conf deleted file mode 100644 index 4b929a41a2660c1ea36e41ae351c38b188ada511..0000000000000000000000000000000000000000 --- a/samples/net/dtls_server/prj_slip.conf +++ /dev/null @@ -1,11 +0,0 @@ -CONFIG_NET_TESTING=y -CONFIG_NETWORKING_IPV6_NO_ND=y -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_NETWORKING_WITH_LOOPBACK=y -CONFIG_NETWORKING_UART=y -CONFIG_NETWORKING_DEBUG_UART=y -CONFIG_IP_BUF_RX_SIZE=10 -CONFIG_IP_BUF_TX_SIZE=2 -CONFIG_NANO_TIMEOUTS=y -CONFIG_TINYDTLS=y diff --git a/samples/net/dtls_server/src/Makefile b/samples/net/dtls_server/src/Makefile deleted file mode 100644 index f3f5d16d6b8ce625c1c1f0ec32ccb98dc74331c7..0000000000000000000000000000000000000000 --- a/samples/net/dtls_server/src/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os/lib -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os/sys -ccflags-y +=-I${ZEPHYR_BASE}/net/ip -ccflags-y +=-I${ZEPHYR_BASE}/samples/bluetooth/ - -ifeq ($(CONFIG_NET_TESTING), y) -ccflags-y +=-I${ZEPHYR_BASE}/samples/net/common/ -ccflags-y +=-DNET_TESTING_SERVER=1 -endif - -obj-y = dtls-server.o - -ifeq ($(CONFIG_NETWORKING_WITH_BT), y) - obj-y += ../../../bluetooth/gatt/ipss.o -endif diff --git a/samples/net/dtls_server/src/dtls-server.c b/samples/net/dtls_server/src/dtls-server.c deleted file mode 100644 index 15fb7b00c307bab894f0fd9d99d4f03127aa72e5..0000000000000000000000000000000000000000 --- a/samples/net/dtls_server/src/dtls-server.c +++ /dev/null @@ -1,406 +0,0 @@ -/* dtls-server.c - dtls server */ - -/* - * Copyright (c) 2015 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined(CONFIG_STDOUT_CONSOLE) -#include -#define PRINT printf -#else -#include -#define PRINT printk -#endif - -#include - -#include - -#include -#include -#include - -#include - -#include -#include - -#if defined(CONFIG_NET_TESTING) -#include -#endif - -static const unsigned char ecdsa_priv_key[] = { - 0xD9, 0xE2, 0x70, 0x7A, 0x72, 0xDA, 0x6A, 0x05, - 0x04, 0x99, 0x5C, 0x86, 0xED, 0xDB, 0xE3, 0xEF, - 0xC7, 0xF1, 0xCD, 0x74, 0x83, 0x8F, 0x75, 0x70, - 0xC8, 0x07, 0x2D, 0x0A, 0x76, 0x26, 0x1B, 0xD4}; - -static const unsigned char ecdsa_pub_key_x[] = { - 0xD0, 0x55, 0xEE, 0x14, 0x08, 0x4D, 0x6E, 0x06, - 0x15, 0x59, 0x9D, 0xB5, 0x83, 0x91, 0x3E, 0x4A, - 0x3E, 0x45, 0x26, 0xA2, 0x70, 0x4D, 0x61, 0xF2, - 0x7A, 0x4C, 0xCF, 0xBA, 0x97, 0x58, 0xEF, 0x9A}; - -static const unsigned char ecdsa_pub_key_y[] = { - 0xB4, 0x18, 0xB6, 0x4A, 0xFE, 0x80, 0x30, 0xDA, - 0x1D, 0xDC, 0xF4, 0xF4, 0x2E, 0x2F, 0x26, 0x31, - 0xD0, 0x43, 0xB1, 0xFB, 0x03, 0xE2, 0x2F, 0x4D, - 0x17, 0xDE, 0x43, 0xF9, 0xF9, 0xAD, 0xEE, 0x70}; - -#define MY_PORT 4242 - -static inline void init_app(void) -{ - PRINT("%s: run dtls server\n", __func__); - -#if defined(CONFIG_NET_TESTING) - net_testing_setup(); -#endif -} - -static inline void reverse(unsigned char *buf, int len) -{ - int i, last = len - 1; - - for (i = 0; i < len / 2; i++) { - unsigned char tmp = buf[i]; - buf[i] = buf[last - i]; - buf[last - i] = tmp; - } -} - -/* How many tics to wait for a network packet */ -#if 0 -#define WAIT_TIME 1 -#define WAIT_TICKS (WAIT_TIME * sys_clock_ticks_per_sec) -#else -#define WAIT_TICKS TICKS_UNLIMITED -#endif - -static inline void receive_message(const char *name, - struct net_context *recv, - dtls_context_t *dtls) -{ - struct net_buf *buf; - - buf = net_receive(recv, WAIT_TICKS); - if (buf) { - session_t session; - - dtls_session_init(&session); - - uip_ipaddr_copy(&session.addr.ipaddr, - &NET_BUF_IP(buf)->srcipaddr); - session.addr.port = NET_BUF_UDP(buf)->srcport; - - PRINT("Received data %p datalen %d\n", - ip_buf_appdata(buf), ip_buf_appdatalen(buf)); - - dtls_handle_message(dtls, &session, ip_buf_appdata(buf), - ip_buf_appdatalen(buf)); - - /* We never send the buffer by this function. A network buffer - * to be sent is allocated in send_to_peer() that is - * responsible for sending the data. - */ - ip_buf_unref(buf); - } -} - -#if defined(CONFIG_NETWORKING_WITH_IPV6) -static struct in6_addr in6addr_my = IN6ADDR_ANY_INIT; -#else -static struct in_addr in4addr_my = { { { 0 } } }; -#endif - -static inline struct net_context *get_context(void) -{ - static struct net_addr any_addr; - static struct net_addr my_addr; - struct net_context *ctx; - -#if defined(CONFIG_NETWORKING_WITH_IPV6) - static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; - - any_addr.in6_addr = in6addr_any; - any_addr.family = AF_INET6; - - my_addr.in6_addr = in6addr_my; - my_addr.family = AF_INET6; -#else - static const struct in_addr in4addr_any = { { { 0 } } }; - - any_addr.in_addr = in4addr_any; - any_addr.family = AF_INET; - - my_addr.in_addr = in4addr_my; - my_addr.family = AF_INET; -#endif - - ctx = net_context_get(IPPROTO_UDP, - &any_addr, 0, - &my_addr, MY_PORT); - if (!ctx) { - PRINT("%s: Cannot get network context\n", __func__); - return NULL; - } - - return ctx; -} - -static int read_from_peer(struct dtls_context_t *ctx, - session_t *session, - uint8 *data, size_t len) -{ - PRINT("%s: read from peer %p len %d\n", __func__, data, len); - - /* In this test we reverse the received bytes. - * We could also just pass the data back as is. - */ - reverse(data, len); - - /* echo incoming application data */ - return dtls_write(ctx, session, data, len); -} - -static int send_to_peer(struct dtls_context_t *ctx, - session_t *session, - uint8 *data, size_t len) -{ - struct net_context *recv = - (struct net_context *)dtls_get_app_data(ctx); - struct net_buf *buf; - int max_data_len; - uint8_t *ptr; - - buf = ip_buf_get_tx(recv); - if (!buf) { - len = -ENOBUFS; - goto out; - } - - max_data_len = IP_BUF_MAX_DATA - sizeof(struct uip_udp_hdr) - - sizeof(struct uip_ip_hdr); - - PRINT("%s: reply to peer data %p len %d\n", __func__, data, len); - - if (len > max_data_len) { - PRINT("%s: too much (%d bytes) data to send (max %d bytes)\n", - __func__, len, max_data_len); - ip_buf_unref(buf); - len = -EINVAL; - goto out; - } - - /* Note that we have reversed the addresses here - * because net_reply() will reverse them again. - */ -#if defined(CONFIG_NETWORKING_WITH_IPV6) - uip_ip6addr_copy(&NET_BUF_IP(buf)->destipaddr, - (uip_ip6addr_t *)&in6addr_my); - uip_ip6addr_copy(&NET_BUF_IP(buf)->srcipaddr, - (uip_ip6addr_t *)&session->addr.ipaddr); -#else - uip_ip4addr_copy(&NET_BUF_IP(buf)->destipaddr, - (uip_ip4addr_t *)&in4addr_my); - uip_ip4addr_copy(&NET_BUF_IP(buf)->srcipaddr, - (uip_ip4addr_t *)&session->addr.ipaddr); -#endif - NET_BUF_UDP(buf)->destport = uip_ntohs(MY_PORT); - NET_BUF_UDP(buf)->srcport = session->addr.port; - - uip_set_udp_conn(buf) = net_context_get_udp_connection(recv); - - ptr = net_buf_add(buf, len); - memcpy(ptr, data, len); - ip_buf_appdata(buf) = ptr; - ip_buf_appdatalen(buf) = len; - - if (net_reply(recv, buf)) { - ip_buf_unref(buf); - } - -out: - return len; -} - -#if defined(DTLS_PSK) -/* This function is the "key store" for tinyDTLS. It is called to - * retrieve a key for the given identity within this particular - * session. */ -static int get_psk_info(struct dtls_context_t *ctx, - const session_t *session, - dtls_credentials_type_t type, - const unsigned char *id, size_t id_len, - unsigned char *result, size_t result_length) -{ - struct keymap_t { - unsigned char *id; - size_t id_length; - unsigned char *key; - size_t key_length; - } psk[3] = { - { (unsigned char *)"Client_identity", 15, - (unsigned char *)"secretPSK", 9 }, - { (unsigned char *)"default identity", 16, - (unsigned char *)"\x11\x22\x33", 3 }, - { (unsigned char *)"\0", 2, - (unsigned char *)"", 1 } - }; - - if (type != DTLS_PSK_KEY) { - return 0; - } - - if (id) { - int i; - for (i = 0; i < sizeof(psk)/sizeof(struct keymap_t); i++) { - if (id_len == psk[i].id_length && - memcmp(id, psk[i].id, id_len) == 0) { - if (result_length < psk[i].key_length) { - dtls_warn("buffer too small for PSK"); - return dtls_alert_fatal_create( - DTLS_ALERT_INTERNAL_ERROR); - } - - memcpy(result, psk[i].key, psk[i].key_length); - return psk[i].key_length; - } - } - } - - return dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR); -} -#endif /* DTLS_PSK */ - -#if defined(DTLS_ECC) -static int get_ecdsa_key(struct dtls_context_t *ctx, - const session_t *session, - const dtls_ecdsa_key_t **result) -{ - static const dtls_ecdsa_key_t ecdsa_key = { - .curve = DTLS_ECDH_CURVE_SECP256R1, - .priv_key = ecdsa_priv_key, - .pub_key_x = ecdsa_pub_key_x, - .pub_key_y = ecdsa_pub_key_y - }; - - *result = &ecdsa_key; - return 0; -} - -static int verify_ecdsa_key(struct dtls_context_t *ctx, - const session_t *session, - const unsigned char *other_pub_x, - const unsigned char *other_pub_y, - size_t key_size) -{ - return 0; -} -#endif /* DTLS_ECC */ - -static int handle_event(struct dtls_context_t *ctx, session_t *session, - dtls_alert_level_t level, unsigned short code) -{ - dtls_debug("event: level %d code %d\n", level, code); - - if (level > 0) { - /* alert code, quit */ - } else if (level == 0) { - /* internal event */ - if (code == DTLS_EVENT_CONNECTED) { - PRINT("*** Connected ***\n"); - } - } - - return 0; -} - -static void init_dtls(struct net_context *recv, dtls_context_t **dtls) -{ - static dtls_handler_t cb = { - .write = send_to_peer, - .read = read_from_peer, - .event = handle_event, -#if defined(DTLS_PSK) - .get_psk_info = get_psk_info, -#endif /* DTLS_PSK */ -#if defined(DTLS_ECC) - .get_ecdsa_key = get_ecdsa_key, - .verify_ecdsa_key = verify_ecdsa_key -#endif /* DTLS_ECC */ - }; - - PRINT("DTLS server started\n"); - -#if defined(CONFIG_TINYDTLS_DEBUG) - dtls_set_log_level(DTLS_LOG_DEBUG); -#endif - - *dtls = dtls_new_context(recv); - if (*dtls) { - dtls_set_handler(*dtls, &cb); - } -} - -void startup(void) -{ - static dtls_context_t *dtls; - static struct net_context *recv; - - net_init(); - - dtls_init(); - - init_app(); - -#if defined(CONFIG_NETWORKING_WITH_BT) - if (bt_enable(NULL)) { - PRINT("Bluetooth init failed\n"); - return; - } - ipss_init(); - ipss_advertise(); -#endif - - recv = get_context(); - if (!recv) { - PRINT("%s: Cannot get network context\n", __func__); - return; - } - - init_dtls(recv, &dtls); - if (!dtls) { - PRINT("%s: Cannot get DTLS context\n", __func__); - return; - } - - while (1) { - receive_message(__func__, recv, dtls); - } -} - -#if defined(CONFIG_NANOKERNEL) - -#define STACKSIZE 3000 -char fiberStack[STACKSIZE]; - -void main(void) -{ - fiber_start(&fiberStack[0], STACKSIZE, - (nano_fiber_entry_t)startup, 0, 0, 7, 0); -} - -#endif /* CONFIG_MICROKERNEL || CONFIG_NANOKERNEL */ diff --git a/samples/net/dtls_server/testcase.ini b/samples/net/dtls_server/testcase.ini deleted file mode 100644 index 38eb45b6d78eadb6d05f0c4af09ea6b32d05a5f3..0000000000000000000000000000000000000000 --- a/samples/net/dtls_server/testcase.ini +++ /dev/null @@ -1,6 +0,0 @@ -[test] -tags = net -build_only = true -arch_whitelist = x86 -platform_whitelist = qemu_x86 - diff --git a/samples/net/echo_client/testcase.ini b/samples/net/echo_client/testcase.ini index 9409d91629bacbc12056d7da1f995f4440ed84ea..f494ab187b7f429889cd0bfc84af8a8a89a4331b 100644 --- a/samples/net/echo_client/testcase.ini +++ b/samples/net/echo_client/testcase.ini @@ -3,6 +3,7 @@ tags = net build_only = true arch_whitelist = x86 platform_whitelist = minnowboard +skip = true [test_bt] tags = net bluetooth @@ -10,3 +11,4 @@ build_only = true extra_args = CONF_FILE="prj_bt.conf" arch_whitelist = x86 platform_whitelist = minnowboard +skip = true diff --git a/samples/net/echo_server/testcase.ini b/samples/net/echo_server/testcase.ini index 9409d91629bacbc12056d7da1f995f4440ed84ea..f494ab187b7f429889cd0bfc84af8a8a89a4331b 100644 --- a/samples/net/echo_server/testcase.ini +++ b/samples/net/echo_server/testcase.ini @@ -3,6 +3,7 @@ tags = net build_only = true arch_whitelist = x86 platform_whitelist = minnowboard +skip = true [test_bt] tags = net bluetooth @@ -10,3 +11,4 @@ build_only = true extra_args = CONF_FILE="prj_bt.conf" arch_whitelist = x86 platform_whitelist = minnowboard +skip = true diff --git a/samples/net/loopback_test/Makefile b/samples/net/loopback_test/Makefile deleted file mode 100644 index 5eb82282f573ec91ff683f3c4b581a9765e15376..0000000000000000000000000000000000000000 --- a/samples/net/loopback_test/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# Makefile - Simple loopback network app Makefile - -# -# Copyright (c) 2015 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -BOARD ?= qemu_x86 -CONF_FILE ?= prj.conf - -include $(ZEPHYR_BASE)/Makefile.inc diff --git a/samples/net/loopback_test/prj.conf b/samples/net/loopback_test/prj.conf deleted file mode 100644 index cce64e41b791a8462af386836318c8c71deb9dea..0000000000000000000000000000000000000000 --- a/samples/net/loopback_test/prj.conf +++ /dev/null @@ -1,5 +0,0 @@ -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOOPBACK=y -CONFIG_NETWORKING_IPV6_NO_ND=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_STDOUT_CONSOLE=y diff --git a/samples/net/loopback_test/prj_10000.conf b/samples/net/loopback_test/prj_10000.conf deleted file mode 100644 index fb8d322cf4dcce9447bf2ff854aac82905f52fd6..0000000000000000000000000000000000000000 --- a/samples/net/loopback_test/prj_10000.conf +++ /dev/null @@ -1,6 +0,0 @@ -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOOPBACK=y -CONFIG_NETWORKING_IPV6_NO_ND=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_STDOUT_CONSOLE=y -CONFIG_NETWORK_LOOPBACK_TEST_COUNT=10000 diff --git a/samples/net/loopback_test/sample.tc b/samples/net/loopback_test/sample.tc deleted file mode 100644 index 7f69ebd1263f1555ae76af582e449aa24bc0c9e3..0000000000000000000000000000000000000000 --- a/samples/net/loopback_test/sample.tc +++ /dev/null @@ -1,8 +0,0 @@ -# @testcase dynamic -# No configuration? -# @targets \ -# board:(?!quark_se_ctb) \ -# board:(?!quark_d2000_crb) \ -# -# @eval console-rx %(console)s:15 fiber_receiver: Received: [0-9]+ bytes -# @eval console-rx %(console)s:15 fiber_sender: App data: [0-9]+ bytes diff --git a/samples/net/loopback_test/src/Makefile b/samples/net/loopback_test/src/Makefile deleted file mode 100644 index 7d1e103e9864ac7d3a2c874deb3266e973081de9..0000000000000000000000000000000000000000 --- a/samples/net/loopback_test/src/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -ccflags-y += -I${ZEPHYR_BASE}/net/ip/contiki -ccflags-y += -I${ZEPHYR_BASE}/net/ip/contiki/os/lib -ccflags-y += -I${ZEPHYR_BASE}/net/ip/contiki/os -ccflags-y += -I${ZEPHYR_BASE}/net/ip - -obj-y = network.o diff --git a/samples/net/loopback_test/src/network.c b/samples/net/loopback_test/src/network.c deleted file mode 100644 index 54f325760f739a6ae6e2bcc75e84ddc61d2bfe77..0000000000000000000000000000000000000000 --- a/samples/net/loopback_test/src/network.c +++ /dev/null @@ -1,263 +0,0 @@ -/* network.c - Loopback demo: IPV6 + UDP */ - -/* - * Copyright (c) 2015 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#if defined(CONFIG_STDOUT_CONSOLE) -#include -#define PRINT printf -#else -#include -#define PRINT printk -#endif - -#include -#include -#include - -#include - -/* Longer packet sending works only if fragmentation is supported - * by network stack. - */ -/* Generated by http://www.lipsum.com/ - * 2 paragraphs, 185 words, 1231 bytes of Lorem Ipsum - * The main() will add one null byte at the end so the maximum - * length for the data to send is 1232 bytes. - */ -static const char *text = - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam " - "congue non neque vel tempor. In id porta nibh, ut cursus tortor. " - "Morbi eleifend tristique vehicula. Nunc vitae risus mauris. " - "Praesent vel imperdiet dolor, et ultricies nibh. Aliquam erat " - "volutpat. Maecenas pellentesque dolor vitae dictum tincidunt. " - "Fusce vel nibh nec leo tristique auctor eu a massa. Nam et tellus " - "ac tortor sollicitudin semper vitae nec tortor. Aliquam nec lacus " - "velit. Maecenas ornare ullamcorper justo non auctor. Donec " - "aliquam feugiat turpis, quis elementum sem rutrum ut. Sed eu " - "ullamcorper libero, ut suscipit magna." - "\n" - "Donec vehicula magna ut varius aliquam. Ut vitae commodo nulla, " - "quis ornare dolor. Nulla tortor sem, venenatis eu iaculis id, " - "commodo ut massa. Sed est lorem, euismod vitae enim sed, " - "hendrerit gravida felis. Donec eros lacus, auctor ut ultricies " - "eget, lobortis quis nisl. Aliquam sit amet blandit eros. " - "Interdum et malesuada fames ac ante ipsum primis in faucibus. " - "Quisque egestas nisl leo, sed consectetur leo ornare eu. " - "Suspendisse vitae urna vel purus maximus finibus. Proin sed " - "sollicitudin turpis. Mauris interdum neque eu tellus " - "pellentesque, id fringilla nisi fermentum. Suspendisse gravida " - "pharetra sodales orci aliquam."; - -/* Specify delay between greetings (in ms); compute equivalent in ticks */ -#define SLEEPTIME 1000 -#define SLEEPTICKS (SLEEPTIME * sys_clock_ticks_per_sec / 1000) - -#define STACKSIZE 2000 -static char receiver_stack[STACKSIZE]; -static char sender_stack[STACKSIZE]; - -static struct net_addr any_addr; -static struct net_addr loopback_addr; - -static int sent; -static int received; - -static nano_thread_id_t sender_id; -static nano_thread_id_t receiver_id; - -static int failure; -static int data_len; - -/* How many packets to send/receive */ -#if defined(CONFIG_NETWORK_LOOPBACK_TEST_COUNT) -#define TEST_COUNT CONFIG_NETWORK_LOOPBACK_TEST_COUNT -#else -#define TEST_COUNT 0 -#endif -static unsigned long count = TEST_COUNT; - -int eval_rcvd_data(char *rcvd_buf, int rcvd_len) -{ - int rc = 0; - - if (data_len != rcvd_len) { - rc = -1; - PRINT("Received %d bytes but was sent %d bytes\n", - rcvd_len, data_len); - } else { - /* Data integrity */ - rc = memcmp(text, rcvd_buf, data_len-1); - if (rc != 0) { - PRINT("Sent and received data does not match.\n"); - PRINT("Sent: %.*s\n", data_len, text); - PRINT("Received: %.*s\n", - data_len, rcvd_buf); - } - } - return rc; -} - -void fiber_receiver(void) -{ - struct net_context *ctx; - struct net_buf *buf; - char *rcvd_buf; - int rcvd_len; - - ctx = net_context_get(IPPROTO_UDP, - &any_addr, 0, - &loopback_addr, 4242); - if (!ctx) { - PRINT("%s: Cannot get network context\n", __func__); - return; - } - - while (!failure) { - /* Fiber blocks until something is ready to be read */ - buf = net_receive(ctx, TICKS_UNLIMITED); - if (buf) { - /* Application level data and its length */ - rcvd_buf = ip_buf_appdata(buf); - rcvd_len = ip_buf_appdatalen(buf); - - PRINT("[%d] %s: Received: %d bytes\n", - received, __func__, rcvd_len); - - if (eval_rcvd_data(rcvd_buf, rcvd_len) != 0) { - PRINT("[%d] %s: net_receive failed!\n", - received, __func__); - failure = 1; - } - ip_buf_unref(buf); - received++; - } - fiber_wakeup(sender_id); - fiber_sleep(SLEEPTICKS); - if (count && (count < received)) { - break; - } - } -} - -void prepare_to_send(struct net_buf *buf, size_t *len) -{ - char *ptr; - int text_len; - - text_len = strlen(text); - *len = sys_rand32_get() % text_len; - - /* net_buf_add: returns a pointer to the current tail of - * buf->data before adding n bytes. - * Adding 0 bytes just allows us to get a pointer to the - * tail without affecting buf->len. - */ - ptr = net_buf_add(buf, 0); - memcpy(ptr, text, *len); - net_buf_add(buf, *len); - /* We need to know where the text finishes to add the - * end-of-line character. - */ - ptr = net_buf_add(buf, 1); - *ptr = '\0'; - - *len += 1; -} - -void fiber_sender(void) -{ - struct net_context *ctx; - struct net_buf *buf; - uint16_t sent_len; - size_t len; - int header_size; - - ctx = net_context_get(IPPROTO_UDP, - &loopback_addr, 4242, - &any_addr, 0); - if (!ctx) { - PRINT("Cannot get network context\n"); - return; - } - - while (!failure) { - buf = ip_buf_get_tx(ctx); - if (buf) { - prepare_to_send(buf, &len); - sent_len = buf->len; - header_size = ip_buf_reserve(buf); - data_len = sent_len - header_size; - ip_buf_appdatalen(buf) = data_len; - - PRINT("[%d] %s: App data: %d bytes, IPv6+UDP: %d bytes, " - "Total packet size: %d bytes\n", - sent, __func__, len, header_size, sent_len); - - if (net_send(buf) < 0) { - PRINT("[%d] %s: net_send failed!\n", - sent, __func__); - failure = 1; - } - ip_buf_unref(buf); - sent++; - } - fiber_wakeup(receiver_id); - fiber_sleep(SLEEPTICKS); - if (sent != received) { - failure = 1; - } - if (count && (count < sent)) { - break; - } - - } - - if (failure) { - PRINT("TEST FAILED\n"); - } else { - PRINT("TEST PASSED\n"); - } -} - -void main(void) -{ - struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; /* :: */ - struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; /* ::1 */ - - PRINT("%s: running network loopback test\n", __func__); - - sys_rand32_init(); - - net_init(); - net_driver_loopback_init(); - - any_addr.in6_addr = in6addr_any; - any_addr.family = AF_INET6; - - loopback_addr.in6_addr = in6addr_loopback; - loopback_addr.family = AF_INET6; - - receiver_id = task_fiber_start(receiver_stack, STACKSIZE, - (nano_fiber_entry_t)fiber_receiver, - 0, 0, 7, 0); - - sender_id = task_fiber_start(sender_stack, STACKSIZE, - (nano_fiber_entry_t)fiber_sender, - 0, 0, 7, 0); -} diff --git a/samples/net/loopback_test/testcase.ini b/samples/net/loopback_test/testcase.ini deleted file mode 100644 index 3fe82271f4bcd2602bb89fc7de3c5d60eb2cd8bb..0000000000000000000000000000000000000000 --- a/samples/net/loopback_test/testcase.ini +++ /dev/null @@ -1,4 +0,0 @@ -[test] -build_only = true -tags = net -platform_whitelist = qemu_cortex_m3 qemu_x86 diff --git a/samples/net/mbedtls_sslclient/testcase.ini b/samples/net/mbedtls_sslclient/testcase.ini index 9269d248e98c3a6f01cdf56a91fbc12239c60a47..909c943651e76b3d0fb10d0898b953922965f3fc 100644 --- a/samples/net/mbedtls_sslclient/testcase.ini +++ b/samples/net/mbedtls_sslclient/testcase.ini @@ -4,3 +4,4 @@ build_only = true arch_whitelist = x86 platform_whitelist = galileo +skip = true diff --git a/samples/net/nats_clients/publisher/testcase.ini b/samples/net/nats_clients/publisher/testcase.ini index 99297a6174e845f8fc264e4de5e2cb7fcfde2dea..2dcbdd9ed8ef17c4352f5d8e2d2f82fe378e3a54 100644 --- a/samples/net/nats_clients/publisher/testcase.ini +++ b/samples/net/nats_clients/publisher/testcase.ini @@ -3,3 +3,4 @@ tags = net build_only = true arch_whitelist = x86 platform_whitelist = galileo +skip = true diff --git a/samples/net/nats_clients/subscriber/testcase.ini b/samples/net/nats_clients/subscriber/testcase.ini index 99297a6174e845f8fc264e4de5e2cb7fcfde2dea..2dcbdd9ed8ef17c4352f5d8e2d2f82fe378e3a54 100644 --- a/samples/net/nats_clients/subscriber/testcase.ini +++ b/samples/net/nats_clients/subscriber/testcase.ini @@ -3,3 +3,4 @@ tags = net build_only = true arch_whitelist = x86 platform_whitelist = galileo +skip = true diff --git a/samples/net/test/test_15_4/Makefile b/samples/net/test/test_15_4/Makefile deleted file mode 100644 index 9baeb02c94b3b772ade819ed89ffc97a9bd4acd6..0000000000000000000000000000000000000000 --- a/samples/net/test/test_15_4/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# Makefile - IP 15.4 test Makefile for nanokernel - -# -# Copyright (c) 2011-2014, Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MDEF_FILE = prj.mdef -BOARD ?= qemu_x86 -CONF_FILE = prj.conf -SOURCE_DIR = $(ZEPHYR_BASE)/samples/net/test_15_4/src/ - -include $(ZEPHYR_BASE)/Makefile.inc -include $(ZEPHYR_BASE)/samples/net/test_15_4/Makefile.15_4 diff --git a/samples/net/test/test_15_4/README b/samples/net/test/test_15_4/README deleted file mode 100644 index 277f1c51ee00df07daa1fe817dec3fa6b90b943b..0000000000000000000000000000000000000000 --- a/samples/net/test/test_15_4/README +++ /dev/null @@ -1,84 +0,0 @@ -802.15.4 test Application: - -1) Loopback in single qemu: - - $ make qemu0 - - This enables the dummy driver will feed sending 802.15.4 frames back to - 15_4 Rx FIFO. 15_4 Rx FIFO will asseble all frames and feed it to IP Rx FIFO. - - -2) Loopback between two qemus without monitoring support: - - $ make qemu1 - - Then in second window start the other qemu - - $ make qemu2 - - If you want to run test 3) then you need to remove the pipes before - doing so. - - $ make remove_pipes - -3) Loopback between two qemus with monitoring support: - - $ make qemu1monitor - - Then in second window start the monitor (found in net/ip/tools directory) - $ ./monitor_15_4 sample.pcap - - Then in third window start the other qemu - - $ make qemu2monitor - - If you want to run test 2) then you need to remove the pipes before - doing so. - - $ make remove_pipes - - - -Expert and more detailed instructions: --------------------------------------- -You can execute the tests manually if needed. Just follow the instructions -below. - -802.15.4 test Application: - - 1) Loopback in single qemu: - Enable CONFIG_NETWORKING_WITH_15_4_LOOPBACK config option in prj_x86/arm.conf - to test 802.15.4. By enabling this option dummy driver will feed sending - 802.15.4 frames back to 15_4 Rx FIFO. 15_4 Rx FIFO will asseble all frames - and feed it to IP Rx FIFO. - - 2) Loopback between two qemus: - Enable CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART config option in - prj_x86/arm.conf to send 802.15.4 frames out through QEMU UART and receive - frames through QEMU UART. - - Follow below simple steps to create fifos at host. - - $ mkfifo /tmp/ip-15-4-1.{in,out} - $ ln /tmp/ip-15-4-1.in /tmp/ip-15-4-2.out - $ ln /tmp/ip-15-4-1.out /tmp/ip-15-4-2.in - - Open two terminals and run two qemus with below options. - $ make qemu QEMU_NUM=1 CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART=y - $ make qemu QEMU_NUM=2 CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART=y - - 3) Loopback between two qemus and pcap support: - Enable CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART config option in - prj_x86/arm.conf to send 802.15.4 frames out through QEMU UART and receive - frames through QEMU UART. - - Follow below simple steps to create fifos at host. - - $ mkfifo /tmp/ip-15-4-1.{in,out} - $ mkfifo /tmp/ip-15-4-2.{in,out} - - also read net/ip/contiki/tools/README and run monitor_15.4 - and then - - $ make qemu QEMU_NUM=1 CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART=y - $ make qemu QEMU_NUM=2 CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART=y diff --git a/samples/net/test/test_15_4/prj.conf b/samples/net/test/test_15_4/prj.conf deleted file mode 100644 index a52654e1b42fdacff2a67d3c6042ca770d3c545c..0000000000000000000000000000000000000000 --- a/samples/net/test/test_15_4/prj.conf +++ /dev/null @@ -1,8 +0,0 @@ -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_NETWORKING_WITH_6LOWPAN=y -CONFIG_NETWORKING_WITH_15_4=y -CONFIG_NET_BUF_RX_SIZE=5 -CONFIG_NET_BUF_TX_SIZE=3 -CONFIG_NET_15_4_LOOPBACK_NUM=1 -CONFIG_NET_SANITY_TEST=y diff --git a/samples/net/test/test_15_4/prj.mdef b/samples/net/test/test_15_4/prj.mdef deleted file mode 100644 index bad07455f5a8f43e7d2241b682c26e7aa6454df1..0000000000000000000000000000000000000000 --- a/samples/net/test/test_15_4/prj.mdef +++ /dev/null @@ -1 +0,0 @@ -% Application : Network demo diff --git a/samples/net/test_15_4/Makefile b/samples/net/test_15_4/Makefile deleted file mode 100644 index dc55c9fbe5dbef789500bbaba667b75d556e5fd1..0000000000000000000000000000000000000000 --- a/samples/net/test_15_4/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# Makefile - IP 15.4 test Makefile for nanokernel - -# -# Copyright (c) 2011-2014, Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MDEF_FILE = prj.mdef -BOARD ?= qemu_x86 -CONF_FILE = prj.conf -CFLAGS += -DNET_802154_TX_STACK_SIZE=5120 - -include $(ZEPHYR_BASE)/Makefile.inc -include $(ZEPHYR_BASE)/samples/net/test_15_4/Makefile.15_4 diff --git a/samples/net/test_15_4/Makefile.15_4 b/samples/net/test_15_4/Makefile.15_4 deleted file mode 100644 index 5745132c0e6f9a7c54cdc8306ca6d80b5306b06b..0000000000000000000000000000000000000000 --- a/samples/net/test_15_4/Makefile.15_4 +++ /dev/null @@ -1,104 +0,0 @@ -# Makefile - IP 15.4 test Makefile for nano and micro kernel - -# -# Copyright (c) 2015 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -PIPE_BASE=/tmp/ip-15-4 - -ifeq ($(MAKECMDGOALS),qemu1) - QEMU_NUM=1 -endif -ifeq ($(MAKECMDGOALS),qemu1monitor) - QEMU_NUM=1 -endif -ifeq ($(MAKECMDGOALS),qemu2) - QEMU_NUM=2 -endif -ifeq ($(MAKECMDGOALS),qemu2monitor) - QEMU_NUM=2 -endif -ifdef QEMU_NUM - QEMU_EXTRA_FLAGS += -serial none -serial pipe:${PIPE_BASE}-${QEMU_NUM} -pidfile qemu-${QEMU_NUM}.pid -endif - -PIPE1_IN=${PIPE_BASE}-1.in -PIPE1_OUT=${PIPE_BASE}-1.out -PIPE2_IN=${PIPE_BASE}-2.in -PIPE2_OUT=${PIPE_BASE}-2.out - -.PHONY: remove_pipes -remove_pipes: - rm -f ${PIPE1_IN} ${PIPE1_OUT} ${PIPE2_IN} ${PIPE2_OUT} - -${PIPE1_IN}: - mkfifo $@ - -${PIPE1_OUT}: - mkfifo $@ - -${PIPE2_IN}: - mkfifo $@ - -${PIPE2_OUT}: - mkfifo $@ - -.PHONY: PIPE2_IN_LINK -PIPE2_IN_LINK: ${PIPE1_IN} - -ln ${PIPE1_IN} ${PIPE2_OUT} - -.PHONY: PIPE2_OUT_LINK -PIPE2_OUT_LINK: ${PIPE1_OUT} - -ln ${PIPE1_OUT} ${PIPE2_IN} - -SINGLE_CONFIG_OPTIONS="CONFIG_NETWORKING_WITH_15_4_LOOPBACK=y" - -.PHONY: set_options_default -set_options_default: - echo "${SINGLE_CONFIG_OPTIONS}" >> ${DOTCONFIG} - -# Setup the single qemu test case (one qemu using loopback driver) -qemu0: $(DOTCONFIG) - $(Q)$(call zephyrmake,$(O),qemu) - -# Setup the dual qemu test case (two qemus passing data between them) -.PHONY: setup_pipes_dual -setup_pipes_dual: ${PIPE1_IN} ${PIPE1_OUT} PIPE2_IN_LINK PIPE2_OUT_LINK - -# Setup the dual qemu test case with pcap support (two qemus passing data -# between them and saving data to pcap via help of monitor applicaiton) -.PHONY: setup_pipes_dual_monitor -setup_pipes_dual_monitor: ${PIPE1_IN} ${PIPE1_OUT} ${PIPE2_IN} ${PIPE2_OUT} - -DUAL_CONFIG_OPTIONS="CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART=y" - -.PHONY: set_options -set_options: - echo "${DUAL_CONFIG_OPTIONS}" >> ${DOTCONFIG} - -export QEMU_NUM -export QEMU_EXTRA_FLAGS - -qemu1: setup_pipes_dual $(DOTCONFIG) set_options - $(Q)$(call zephyrmake,$(O),qemu) - -qemu2: setup_pipes_dual $(DOTCONFIG) set_options - $(Q)$(call zephyrmake,$(O),qemu) - -qemu1monitor: setup_pipes_dual_monitor $(DOTCONFIG) set_options - $(Q)$(call zephyrmake,$(O),qemu) - -qemu2monitor: setup_pipes_dual_monitor $(DOTCONFIG) set_options - $(Q)$(call zephyrmake,$(O),qemu) diff --git a/samples/net/test_15_4/README b/samples/net/test_15_4/README deleted file mode 100644 index 277f1c51ee00df07daa1fe817dec3fa6b90b943b..0000000000000000000000000000000000000000 --- a/samples/net/test_15_4/README +++ /dev/null @@ -1,84 +0,0 @@ -802.15.4 test Application: - -1) Loopback in single qemu: - - $ make qemu0 - - This enables the dummy driver will feed sending 802.15.4 frames back to - 15_4 Rx FIFO. 15_4 Rx FIFO will asseble all frames and feed it to IP Rx FIFO. - - -2) Loopback between two qemus without monitoring support: - - $ make qemu1 - - Then in second window start the other qemu - - $ make qemu2 - - If you want to run test 3) then you need to remove the pipes before - doing so. - - $ make remove_pipes - -3) Loopback between two qemus with monitoring support: - - $ make qemu1monitor - - Then in second window start the monitor (found in net/ip/tools directory) - $ ./monitor_15_4 sample.pcap - - Then in third window start the other qemu - - $ make qemu2monitor - - If you want to run test 2) then you need to remove the pipes before - doing so. - - $ make remove_pipes - - - -Expert and more detailed instructions: --------------------------------------- -You can execute the tests manually if needed. Just follow the instructions -below. - -802.15.4 test Application: - - 1) Loopback in single qemu: - Enable CONFIG_NETWORKING_WITH_15_4_LOOPBACK config option in prj_x86/arm.conf - to test 802.15.4. By enabling this option dummy driver will feed sending - 802.15.4 frames back to 15_4 Rx FIFO. 15_4 Rx FIFO will asseble all frames - and feed it to IP Rx FIFO. - - 2) Loopback between two qemus: - Enable CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART config option in - prj_x86/arm.conf to send 802.15.4 frames out through QEMU UART and receive - frames through QEMU UART. - - Follow below simple steps to create fifos at host. - - $ mkfifo /tmp/ip-15-4-1.{in,out} - $ ln /tmp/ip-15-4-1.in /tmp/ip-15-4-2.out - $ ln /tmp/ip-15-4-1.out /tmp/ip-15-4-2.in - - Open two terminals and run two qemus with below options. - $ make qemu QEMU_NUM=1 CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART=y - $ make qemu QEMU_NUM=2 CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART=y - - 3) Loopback between two qemus and pcap support: - Enable CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART config option in - prj_x86/arm.conf to send 802.15.4 frames out through QEMU UART and receive - frames through QEMU UART. - - Follow below simple steps to create fifos at host. - - $ mkfifo /tmp/ip-15-4-1.{in,out} - $ mkfifo /tmp/ip-15-4-2.{in,out} - - also read net/ip/contiki/tools/README and run monitor_15.4 - and then - - $ make qemu QEMU_NUM=1 CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART=y - $ make qemu QEMU_NUM=2 CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART=y diff --git a/samples/net/test_15_4/prj.conf b/samples/net/test_15_4/prj.conf deleted file mode 100644 index 9eb54c7c36afc853de04414100f8b310a9a650b6..0000000000000000000000000000000000000000 --- a/samples/net/test_15_4/prj.conf +++ /dev/null @@ -1,8 +0,0 @@ -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_NETWORKING_WITH_6LOWPAN=y -CONFIG_NETWORKING_WITH_15_4=y -CONFIG_NET_15_4_LOOPBACK_NUM=1 -CONFIG_IP_BUF_RX_SIZE=5 -CONFIG_IP_BUF_TX_SIZE=3 -CONFIG_TI_CC2520_LEGACY=y \ No newline at end of file diff --git a/samples/net/test_15_4/prj.mdef b/samples/net/test_15_4/prj.mdef deleted file mode 100644 index cb307179328a6de4adae4bd0f102cb94813a16a7..0000000000000000000000000000000000000000 --- a/samples/net/test_15_4/prj.mdef +++ /dev/null @@ -1,11 +0,0 @@ -% Application : Network demo - -% TASK NAME PRIO ENTRY STACK GROUPS -% ================================== - TASK TASKA 7 taskA 2048 [EXE] - TASK TASKB 7 taskB 2048 [EXE] - -% SEMA NAME -% ============= - SEMA TASKASEM - SEMA TASKBSEM diff --git a/samples/net/test_15_4/sample.tc b/samples/net/test_15_4/sample.tc deleted file mode 100644 index cef7b75ae2bb74fd8dffceaa139f425a800c74e8..0000000000000000000000000000000000000000 --- a/samples/net/test_15_4/sample.tc +++ /dev/null @@ -1,16 +0,0 @@ -# @testcase dynamic - -# @targets \ -# board:(?!arduino_101) \ -# board:(?!arduino_101_sss) \ -# board:(?!arduino_due) \ -# board:(?!frdm_k64f) \ -# board:(?!galileo) \ -# board:(?!minnowboard) \ -# board:(?!qemu_cortex_m3) \ -# board:(?!qemu_x86) \ -# board:(?!quark_d2000_crb) \ -# board:(?!quark_se_c1000_ss_devboard) \ -# -# @eval console-rx %(console)s:15 received [0-9]+ bytes -# @eval console-rx %(console)s:15 sent [0-9]+ bytes diff --git a/samples/net/test_15_4/src/Makefile b/samples/net/test_15_4/src/Makefile deleted file mode 100644 index ae7e84559b44378753356cf43bdd947d12dee090..0000000000000000000000000000000000000000 --- a/samples/net/test_15_4/src/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -ccflags-y += -I${ZEPHYR_BASE}/net/ip/contiki -ccflags-y += -I${ZEPHYR_BASE}/net/ip/contiki/os/lib -ccflags-y += -I${ZEPHYR_BASE}/net/ip/contiki/os -ccflags-y += -I${ZEPHYR_BASE}/net/ip -ccflags-$(CONFIG_NET_SANITY_TEST) += -I${ZEPHYR_BASE}/samples/include - -obj-y = network.o diff --git a/samples/net/test_15_4/src/network.c b/samples/net/test_15_4/src/network.c deleted file mode 100644 index ee03adc5e2f6540a4cbdf3f1ba586a5cffb9b2ee..0000000000000000000000000000000000000000 --- a/samples/net/test_15_4/src/network.c +++ /dev/null @@ -1,414 +0,0 @@ -/* network.c - Networking demo */ - -/* - * Copyright (c) 2015 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#if defined(CONFIG_STDOUT_CONSOLE) -#include -#define PRINT printf -#else -#include -#define PRINT printk -#endif - -#ifdef CONFIG_NET_SANITY_TEST -#include -#endif - -#include -#include -#include -#include - -/* The following uIP includes are for testing purposes only. Never - * ever use them in your application. - */ -#include "contiki/ipv6/uip-ds6-route.h" /* to set the route */ -#include "contiki/ipv6/uip-ds6-nbr.h" /* to set the neighbor cache */ - -#ifndef CONFIG_NET_15_4_LOOPBACK_NUM -#define CONFIG_NET_15_4_LOOPBACK_NUM 0 -#endif - -#if 0 -#define SRC_IPADDR { { { 0xfe,0x80,0,0,0,0,0,0,0x08,0xbe,0xef,0x2d,0xbc,0x15,0xf0,0x0d } } } -#define DEST_IPADDR { { { 0xfe,0x80,0,0,0,0,0,0,0x08,0xbe,0xef,0x2d,0xbc,0x15,0xf0,0x0d } } } -#define SRC_PORT 0xF0B1 -#define DEST_PORT 0xF0B0 - -const struct in6_addr in6addr_src = SRC_IPADDR; -const struct in6_addr in6addr_dest = DEST_IPADDR; - -/* source mac address */ -uint8_t src_mac[] = { 0x0a, 0xbe, 0xef, 0x2d, 0xbc, 0x15, 0xf0, 0x0d }; -/* destincation mac address */ -const uip_lladdr_t dest_mac = { { 0x0a, 0xbe, 0xef, 0x2d, 0xbc, 0x15, 0xf0, 0x0d } }; - -#else - -#define SRC_PORT 0 -#define DEST_PORT 4242 - -const struct in6_addr in6addr_src = IN6ADDR_ANY_INIT; /* :: */ -const struct in6_addr in6addr_dest = IN6ADDR_LOOPBACK_INIT; /* ::1 */ -/* source mac address */ -uint8_t src_mac[] = { 0x0a, 0xbe, 0xef, 0x2d, 0xbc, 0x15, 0xf0, 0x0d }; -/* destincation mac address */ -const uip_lladdr_t dest_mac = { }; - -#endif - -static struct net_addr loopback_addr; -static struct net_addr any_addr; - -#ifdef CONFIG_NET_SANITY_TEST -static int loopback = 0; -static int test_rp = TC_PASS; -#endif - -/* Generated by http://www.lipsum.com/ - * 2 paragraphs, 185 words, 1230 bytes of Lorem Ipsum - * The send_data() will add one null byte at the end and - * 6lowpan needs one byte header so the maximum - * length for the data to send is 1231 bytes. - */ -#if 0 -static const char *lorem_ipsum = - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam congue non neque vel tempor. In id porta nibh, ut cursus tortor. Morbi eleifend tristique vehicula. Nunc vitae risus mauris. Praesent vel imperdiet dolor, et ultricies nibh. Aliquam erat volutpat."; -#else -static const char *lorem_ipsum = - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam congue non neque vel tempor. In id porta nibh, ut cursus tortor. Morbi eleifend tristique vehicula. Nunc vitae risus mauris. Praesent vel imperdiet dolor, et ultricies nibh. Aliquam erat volutpat. Maecenas pellentesque dolor vitae dictum tincidunt. Fusce vel nibh nec leo tristique auctor eu a massa. Nam et tellus ac tortor sollicitudin semper vitae nec tortor. Aliquam nec lacus velit. Maecenas ornare ullamcorper justo non auctor. Donec aliquam feugiat turpis, quis elementum sem rutrum ut. Sed eu ullamcorper libero, ut suscipit magna." - "\n" - "Donec vehicula magna ut varius aliquam. Ut vitae commodo nulla, quis ornare dolor. Nulla tortor sem, venenatis eu iaculis id, commodo ut massa. Sed est lorem, euismod vitae enim sed, hendrerit gravida felis. Donec eros lacus, auctor ut ultricies eget, lobortis quis nisl. Aliquam sit amet blandit eros. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque egestas nisl leo, sed consectetur leo ornare eu. Suspendisse vitae urna vel purus maximus finibus. Proin sed sollicitudin turpis. Mauris interdum neque eu tellus pellentesque, id fringilla nisi fermentum. Suspendisse gravida pharetra sodales orci aliquam"; -#endif - -static inline void init_test() -{ - PRINT("%s: run 802.15.4 loopback tester\n", __func__); - - net_set_mac(src_mac, sizeof(src_mac)); - - any_addr.in6_addr = in6addr_src; - any_addr.family = AF_INET6; - - loopback_addr.in6_addr = in6addr_dest; - loopback_addr.family = AF_INET6; -} - -static void set_routes() -{ - /* Workaround to get packets from this task to listening fiber. - * Do not attempt to do anything like this in live environment. - */ - if (!uip_ds6_nbr_add((uip_ipaddr_t *)&in6addr_dest, - &dest_mac, 0, NBR_REACHABLE)) - PRINT("Cannot add neighbor cache\n"); - - if (!uip_ds6_route_add((uip_ipaddr_t *)&in6addr_dest, 128, - (uip_ipaddr_t *)&in6addr_dest)) - PRINT("Cannot add localhost route\n"); -} - -static void send_data(const char *taskname, struct net_context *ctx) -{ - int len = strlen(lorem_ipsum); - struct net_buf *buf; - - buf = ip_buf_get_tx(ctx); - if (buf) { - uint8_t *ptr; - uint16_t sent_len; - - ptr = net_buf_add(buf, 0); - memcpy(ptr, lorem_ipsum, len); - ptr = net_buf_add(buf, len); - ptr = net_buf_add(buf, 1); /* add \0 */ - *ptr = '\0'; - sent_len = buf->len; - - if (net_send(buf) < 0) { - PRINT("%s: %s(): sending %d bytes failed\n", - taskname, __func__, len); - ip_buf_unref(buf); - } else { - PRINT("%s: %s(): sent %d bytes\n", taskname, - __func__, sent_len); - } - } -} - -static void receive_data(const char *taskname, struct net_context *ctx) -{ - struct net_buf *buf; -#ifdef CONFIG_NET_SANITY_TEST - int rp; -#endif - - buf = net_receive(ctx, TICKS_NONE); - if (buf) { - PRINT("%s: %s(): received %d bytes\n", taskname, - __func__, ip_buf_appdatalen(buf)); - if (memcmp(ip_buf_appdata(buf), - lorem_ipsum, strlen(lorem_ipsum))) { - PRINT("ERROR: data does not match\n"); - -#ifdef CONFIG_NET_SANITY_TEST - rp = TC_FAIL; - } else { - rp = TC_PASS; -#endif - } - - ip_buf_unref(buf); - -#ifdef CONFIG_NET_SANITY_TEST - loopback++; - test_rp = test_rp && rp; - TC_END_RESULT(rp); - - if (loopback == CONFIG_NET_15_4_LOOPBACK_NUM) { - loopback = 0; - TC_END_REPORT(test_rp); - } -#endif - } -} - -static struct net_context *get_context(const struct net_addr *remote, - uint16_t remote_port, - struct net_addr *local, - uint16_t local_port) -{ - struct net_context *ctx; - - ctx = net_context_get(IPPROTO_UDP, - remote, remote_port, - local, local_port); - if (!ctx) { - PRINT("%s: Cannot get network context\n", __func__); - return NULL; - } - - return ctx; -} - -#ifdef CONFIG_MICROKERNEL - -/* - * Microkernel version of hello world demo has two tasks that utilize - * semaphores and sleeps to take turns printing a greeting message at - * a controlled rate. - */ - -/* specify delay between greetings (in ms); compute equivalent in ticks */ - -#define SLEEPTIME 500 -#define SLEEPTICKS (SLEEPTIME * sys_clock_ticks_per_sec / 1000) - -/* specify delay between greetings (in ms); compute equivalent in ticks */ - -#define SLEEPTIME 500 -#define SLEEPTICKS (SLEEPTIME * sys_clock_ticks_per_sec / 1000) - -/* - * - * @param taskname task identification string - * @param mySem task's own semaphore - * @param otherSem other task's semaphore - * - */ -static void listen(const char *taskname, ksem_t mySem, ksem_t otherSem, - struct net_context *ctx) -{ - int i = 0; - - while (1) { - task_sem_take(mySem, TICKS_UNLIMITED); - - receive_data(taskname, ctx); - - if (CONFIG_NET_15_4_LOOPBACK_NUM != 0 && - i >= CONFIG_NET_15_4_LOOPBACK_NUM) { - task_sem_give(otherSem); - return; - } - - /* wait a while, then let other task have a turn */ - task_sleep(SLEEPTICKS); - task_sem_give(otherSem); - i++; - } -} - -void taskA(void) -{ - struct net_context *ctx; - - net_init(); - init_test(); - - ctx = get_context(&any_addr, SRC_PORT, &loopback_addr, DEST_PORT); - if (!ctx) { - PRINT("%s: Cannot get network context\n", __func__); - return; - } - - /* taskA gives its own semaphore, allowing it to say hello right away */ - task_sem_give(TASKASEM); - - listen(__func__, TASKASEM, TASKBSEM, ctx); -} - -static void send(const char *taskname, ksem_t mySem, ksem_t otherSem, - struct net_context *ctx) -{ - int i = 0; - - while (1) { - if (CONFIG_NET_15_4_LOOPBACK_NUM != 0 && - i >= CONFIG_NET_15_4_LOOPBACK_NUM) { - task_sem_give(otherSem); - return; - } - - task_sem_take(mySem, TICKS_UNLIMITED); - - send_data(taskname, ctx); - - /* wait a while, then let other task have a turn */ - task_sleep(SLEEPTICKS); - task_sem_give(otherSem); - i++; - } -} - -void taskB(void) -{ - struct net_context *ctx; - - ctx = get_context(&loopback_addr, DEST_PORT, &any_addr, SRC_PORT); - if (!ctx) { - PRINT("%s: Cannot get network context\n", __func__); - return; - } - - set_routes(); - - send(__func__, TASKBSEM, TASKASEM, ctx); -} - -#else /* CONFIG_NANOKERNEL */ - -/* - * Nanokernel version of hello world demo has a task and a fiber that utilize - * semaphores and timers to take turns printing a greeting message at - * a controlled rate. - */ - -/* specify delay between greetings (in ms); compute equivalent in ticks */ - -#ifdef CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART -#define SLEEPTIME 2000 -#else -/* No need to sleep so long if we are using the loopback without uart */ -#define SLEEPTIME 100 -#endif -#define SLEEPTICKS (SLEEPTIME * sys_clock_ticks_per_sec / 1000) - -#define STACKSIZE 2000 - -char fiberStack_sending[STACKSIZE]; -char fiberStack_receiving[STACKSIZE]; - -void fiber_receiving(void) -{ - struct nano_timer timer; - uint32_t data[2] = {0, 0}; - struct net_context *ctx; - int i = 0; - - ctx = get_context(&any_addr, SRC_PORT, &loopback_addr, DEST_PORT); - if (!ctx) { - PRINT("%s: Cannot get network context\n", __func__); - return; - } - - nano_timer_init(&timer, data); - - while (1) { - receive_data("listenFiber", ctx); - - if (CONFIG_NET_15_4_LOOPBACK_NUM != 0 && - i >= CONFIG_NET_15_4_LOOPBACK_NUM) { - nano_fiber_timer_stop(&timer); - return; - } - - nano_fiber_timer_start(&timer, SLEEPTICKS); - nano_fiber_timer_test(&timer, TICKS_UNLIMITED); - i++; - } -} - -void fiber_sending(void) -{ - struct nano_timer timer; - uint32_t data[2] = {0, 0}; - struct net_context *ctx; - int i = 0; - - ctx = get_context(&loopback_addr, DEST_PORT, &any_addr, SRC_PORT); - if (!ctx) { - PRINT("Cannot get network context\n"); - return; - } - - nano_timer_init(&timer, data); - - while (1) { - if (CONFIG_NET_15_4_LOOPBACK_NUM != 0 && - i >= CONFIG_NET_15_4_LOOPBACK_NUM) { - nano_fiber_timer_stop(&timer); - return; - } - - send_data("sendFiber", ctx); - - nano_fiber_timer_start(&timer, SLEEPTICKS); - nano_fiber_timer_test(&timer, TICKS_UNLIMITED); - i++; - } -} - -void main(void) -{ - PRINT("%s: run test_15_4\n", __func__); - - net_init(); - init_test(); - - set_routes(); - - task_fiber_start(&fiberStack_receiving[0], STACKSIZE, - (nano_fiber_entry_t) fiber_receiving, 0, 0, 7, 0); - - task_fiber_start(&fiberStack_sending[0], STACKSIZE, - (nano_fiber_entry_t) fiber_sending, 0, 0, 7, 0); -} - -#endif /* CONFIG_MICROKERNEL || CONFIG_NANOKERNEL */ diff --git a/samples/net/test_15_4/testcase.ini b/samples/net/test_15_4/testcase.ini deleted file mode 100644 index 92dcfae9140a8860d8d7e0366f7ca9dc1c120f76..0000000000000000000000000000000000000000 --- a/samples/net/test_15_4/testcase.ini +++ /dev/null @@ -1,4 +0,0 @@ -[test] -tags = net -platform_whitelist = quark_se_c1000_devboard -build_only = true diff --git a/samples/net/trickle-legacy/Makefile b/samples/net/trickle-legacy/Makefile deleted file mode 100644 index 4b3562e20b284d97cf7ef5a1c0b6fc70e69abfdf..0000000000000000000000000000000000000000 --- a/samples/net/trickle-legacy/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# Makefile - Example trickle application running in Contiki based -# legacy IP stack - -# -# Copyright (c) 2016 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -NET_IFACE ?= slip -MDEF_FILE = prj.mdef -BOARD ?= qemu_x86 -CONF_FILE ?= prj_$(NET_IFACE).conf - -include $(ZEPHYR_BASE)/Makefile.inc - -ifeq ($(CONFIG_NETWORKING_WITH_BT), y) - QEMU_EXTRA_FLAGS = -serial unix:/tmp/bt-server-bredr -else - include $(ZEPHYR_BASE)/samples/net/common/Makefile.ipstack -endif diff --git a/samples/net/trickle-legacy/prj.mdef b/samples/net/trickle-legacy/prj.mdef deleted file mode 100644 index b431140bd026bbb1ca0ad444d2275b30ab6f1158..0000000000000000000000000000000000000000 --- a/samples/net/trickle-legacy/prj.mdef +++ /dev/null @@ -1,5 +0,0 @@ -% Application : trickle demo app - -% TASK NAME PRIO ENTRY STACK GROUPS -% ================================== - TASK MAIN 7 main 2048 [EXE] diff --git a/samples/net/trickle-legacy/prj_802154.conf b/samples/net/trickle-legacy/prj_802154.conf deleted file mode 100644 index dd284d764c543694f1f41745c40e7745bd52ca04..0000000000000000000000000000000000000000 --- a/samples/net/trickle-legacy/prj_802154.conf +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_IP_BUF_RX_SIZE=3 -CONFIG_IP_BUF_TX_SIZE=2 -CONFIG_NANO_TIMEOUTS=y -CONFIG_NETWORKING_WITH_15_4=y -CONFIG_NETWORKING_WITH_15_4_TI_CC2520=y -CONFIG_SYS_LOG_TI_CC2520_LEVEL=4 -CONFIG_NETWORKING_WITH_6LOWPAN=y -CONFIG_6LOWPAN_COMPRESSION_IPHC=y -CONFIG_NETWORKING_STATISTICS=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NETWORKING_WITH_TRICKLE=y diff --git a/samples/net/trickle-legacy/prj_bt.conf b/samples/net/trickle-legacy/prj_bt.conf deleted file mode 100644 index 0a388e635c0d5db4364a46f4cf69e93ce2564ece..0000000000000000000000000000000000000000 --- a/samples/net/trickle-legacy/prj_bt.conf +++ /dev/null @@ -1,17 +0,0 @@ -CONFIG_BLUETOOTH=y -CONFIG_BLUETOOTH_DEBUG_LOG=y -CONFIG_BLUETOOTH_DEBUG_L2CAP=y -CONFIG_BLUETOOTH_SMP=y -CONFIG_BLUETOOTH_SIGNING=y -CONFIG_BLUETOOTH_PERIPHERAL=y -CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL=y -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_NETWORKING_WITH_6LOWPAN=y -CONFIG_6LOWPAN_COMPRESSION_IPHC=y -CONFIG_NETWORKING_WITH_BT=y -CONFIG_IP_BUF_RX_SIZE=5 -CONFIG_IP_BUF_TX_SIZE=3 -CONFIG_NETWORKING_STATISTICS=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NETWORKING_WITH_TRICKLE=y diff --git a/samples/net/trickle-legacy/prj_ethernet.conf b/samples/net/trickle-legacy/prj_ethernet.conf deleted file mode 100644 index 569d30f4c7ddc4754d209298103926efc09ec611..0000000000000000000000000000000000000000 --- a/samples/net/trickle-legacy/prj_ethernet.conf +++ /dev/null @@ -1,12 +0,0 @@ -CONFIG_INIT_STACKS=y -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_IP_BUF_RX_SIZE=3 -CONFIG_IP_BUF_TX_SIZE=2 -CONFIG_NANO_TIMEOUTS=y -CONFIG_ETHERNET=y -CONFIG_ETH_DW=y -CONFIG_ETHERNET_DEBUG=y -CONFIG_NETWORKING_STATISTICS=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NETWORKING_WITH_TRICKLE=y diff --git a/samples/net/trickle-legacy/prj_qemu.conf b/samples/net/trickle-legacy/prj_qemu.conf deleted file mode 100644 index 9fa33f6ab1d2ebe2c8a6d20fc70465874b82b13b..0000000000000000000000000000000000000000 --- a/samples/net/trickle-legacy/prj_qemu.conf +++ /dev/null @@ -1,9 +0,0 @@ -CONFIG_NETWORKING_IPV6_NO_ND=y -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_IP_BUF_RX_SIZE=3 -CONFIG_IP_BUF_TX_SIZE=2 -CONFIG_NANO_TIMEOUTS=y -CONFIG_NETWORKING_STATISTICS=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NETWORKING_WITH_TRICKLE=y diff --git a/samples/net/trickle-legacy/prj_slip.conf b/samples/net/trickle-legacy/prj_slip.conf deleted file mode 100644 index 2e9ad723291146cd58e9b32da60f44cd5dd71dca..0000000000000000000000000000000000000000 --- a/samples/net/trickle-legacy/prj_slip.conf +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG_NET_TESTING=y -CONFIG_NETWORKING_IPV6_NO_ND=y -CONFIG_NETWORKING=y -CONFIG_NETWORKING_WITH_LOGGING=y -CONFIG_NETWORKING_WITH_LOOPBACK=y -CONFIG_NETWORKING_UART=y -CONFIG_NETWORKING_DEBUG_UART=y -CONFIG_IP_BUF_RX_SIZE=3 -CONFIG_IP_BUF_TX_SIZE=2 -CONFIG_NANO_TIMEOUTS=y -CONFIG_NETWORKING_STATISTICS=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NETWORKING_WITH_TRICKLE=y diff --git a/samples/net/trickle-legacy/src/Makefile b/samples/net/trickle-legacy/src/Makefile deleted file mode 100644 index 60d9ec7b16f51ea177390113430b7ce472b37960..0000000000000000000000000000000000000000 --- a/samples/net/trickle-legacy/src/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -ccflags-y +=-I${ZEPHYR_BASE}/net/ip -ccflags-y +=-I${ZEPHYR_BASE}/samples/bluetooth/ - -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os/lib -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/trickle - -obj-y = main.o - -ifeq ($(CONFIG_NETWORKING_WITH_BT), y) - obj-y += ../../../bluetooth/gatt/ipss.o -endif diff --git a/samples/net/trickle-legacy/src/main.c b/samples/net/trickle-legacy/src/main.c deleted file mode 100644 index 80c74b4ae81aedcd5a5bdc8ac39068afe6a6b5c6..0000000000000000000000000000000000000000 --- a/samples/net/trickle-legacy/src/main.c +++ /dev/null @@ -1,192 +0,0 @@ -/* main.c - Trickle sample app for legacy IP stack */ - -/* - * Copyright (c) 2015 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined(CONFIG_STDOUT_CONSOLE) -#include -#define PRINT printf -#else -#include -#define PRINT printk -#endif - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include - -#define MY_IPADDR { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0x1 } } } -#define MY_PREFIX_LEN 64 - -static const struct in6_addr in6addr_my = MY_IPADDR; -#define MY_PORT 30001 - -#if defined(CONFIG_NANOKERNEL) -#define STACKSIZE 2000 -char __noinit __stack fiberStack[STACKSIZE]; -#endif - -static struct nano_delayed_work token_lifetime; -static uint32_t timeout = SECONDS(5); - -static struct trickle_timer tt; -static uint8_t token; - -#define IMIN 16 /* ticks */ -#define IMAX 10 /* doublings */ -#define REDUNDANCY_CONST 2 - -static void trickle_tx(void *user_data, uint8_t suppress) -{ - struct trickle_timer *t = (struct trickle_timer *)user_data; - - if (suppress == TRICKLE_TIMER_TX_SUPPRESS) { - return; - } - - PRINT("At %lu (I=%lu, c=%u): token 0x%02x\n", - sys_tick_get_32(), (unsigned long)t->i_cur, - t->c, token); - - /* FIXME: Send token .... */ -} - -static inline void init_app(void) -{ - PRINT("%s: run trickle demo\n", __func__); - - token = 0; - - trickle_timer_config(&tt, IMIN, IMAX, REDUNDANCY_CONST); - trickle_timer_set(&tt, trickle_tx, &tt); - - uip_ds6_prefix_add((uip_ipaddr_t *)&in6addr_my, MY_PREFIX_LEN, 0); -} - -/* How many tics to wait for a network packet */ -#define WAIT_TIME 1 -#define WAIT_TICKS (WAIT_TIME * sys_clock_ticks_per_sec) - -struct nano_fifo *net_context_get_queue(struct net_context *context); -static inline void receive_and_reply(const char *name, - struct net_context *udp_recv) -{ - struct net_buf *buf; - - buf = net_receive(udp_recv, WAIT_TICKS); - if (buf) { - } - - fiber_sleep(50); -} - -static inline bool get_context(struct net_context **udp_recv) -{ - static struct net_addr any_addr; - static struct net_addr my_addr; - static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; - - any_addr.in6_addr = in6addr_any; - any_addr.family = AF_INET6; - - my_addr.in6_addr = in6addr_my; - my_addr.family = AF_INET6; - - *udp_recv = net_context_get(IPPROTO_UDP, - &any_addr, 0, - &my_addr, MY_PORT); - if (!*udp_recv) { - PRINT("%s: Cannot get network context\n", __func__); - return false; - } - - return true; -} - -static inline void token_expired(struct nano_work *work) -{ - PRINT("Generate a new token value %d\n", token); - - /* Periodically (and randomly) generate a new token. - * This will trigger a trickle inconsistency - */ - if (!(sys_rand32_get() % 2)) { - token++; - - PRINT("Generating a new token 0x%02x\n", token); - - trickle_timer_reset_event(&tt); - } - - nano_delayed_work_submit(&token_lifetime, timeout); -} - -void receive(void) -{ - static struct net_context *udp_recv; - - if (!get_context(&udp_recv)) { - PRINT("%s: Cannot get network contexts\n", __func__); - return; - } - - /* - * Trickle is now started and is running the first interval. - * All nodes agree that token is 0 initially. This will then - * change when one node randomly decides to generate a new one token. - */ - nano_delayed_work_init(&token_lifetime, token_expired); - nano_delayed_work_submit(&token_lifetime, timeout); - - while (1) { - receive_and_reply(__func__, udp_recv); - } -} - -void main(void) -{ - net_init(); - - init_app(); - -#if defined(CONFIG_NETWORKING_WITH_BT) - if (bt_enable(NULL)) { - PRINT("Bluetooth init failed\n"); - return; - } - ipss_init(); - ipss_advertise(); -#endif - -#if defined(CONFIG_MICROKERNEL) - receive(); -#else - task_fiber_start (&fiberStack[0], STACKSIZE, - (nano_fiber_entry_t)receive, 0, 0, 7, 0); -#endif -} diff --git a/samples/net/zoap_client/src/Makefile b/samples/net/zoap_client/src/Makefile index 92f81867b989c83c5d21ec5f8896546f6a9c4ab0..d799baf118d186f3d7953161040d824e6a532116 100644 --- a/samples/net/zoap_client/src/Makefile +++ b/samples/net/zoap_client/src/Makefile @@ -1,8 +1,3 @@ -ccflags-y +=-I${ZEPHYR_BASE}/net/ip -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os/lib -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os - ifeq ($(CONFIG_NET_TESTING), y) ccflags-y +=-I${ZEPHYR_BASE}/samples/net/common/ ccflags-y +=-DNET_TESTING_SERVER=1 diff --git a/samples/net/zperf/testcase.ini b/samples/net/zperf/testcase.ini index 398bb9926ac3ed3426f437c9409da7e966436ffc..0fd01886fabe1146022b903083eee4a14b1fee13 100644 --- a/samples/net/zperf/testcase.ini +++ b/samples/net/zperf/testcase.ini @@ -2,3 +2,4 @@ build_only = true tags = samples platform_whitelist = galileo +skip = true diff --git a/tests/net/zoap/src/Makefile b/tests/net/zoap/src/Makefile index f3be6cee4754c1a80d5d6f23c2cc839fb6961e7c..2b356966312affe76ad4fdbabcb4b78d47b47d57 100644 --- a/tests/net/zoap/src/Makefile +++ b/tests/net/zoap/src/Makefile @@ -1,8 +1,3 @@ -ccflags-y +=-I${ZEPHYR_BASE}/net/ip -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os/lib -ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os - ccflags-y += -I${ZEPHYR_BASE}/tests/include obj-y = main.o